Commit Graph

3114 Commits

Author SHA1 Message Date
Kartikaya Gupta
d6673c9aad Bug 1449620 - Extract an APZUpdater class from APZSampler. r=botond
The APZUpdater class holds the methods that are to be run on the updater
thread. Note that there are a few differences between the APZSampler and
APZUpdater classes - most notably, APZSampler no longer has a
"RunOnSamplerThread" function because there should never be any need to
dispatch runnables to the sampler thread. There is still a
RunOnUpdaterThread in APZUpdater, as well as a mechanism for dispatching
runnables to the controller thread via the updater thread.

MozReview-Commit-ID: LLVWzRyhYWl

--HG--
extra : rebase_source : d3d2ae18b40f24473cab5567a48b67b8f478a733
2018-03-28 18:36:42 -04:00
Kartikaya Gupta
fb7f70182b Bug 1447299 - Ensure all APZSampler functions run on the sampler thread. r=botond
Functions in APZSampler that are only invoked without WR (e.g. from
AsyncCompositionManager only) can be asserted as running on the sampler
thread. Functions that are invoked with WR need to be bounced onto the
sampler thread. In all cases the functions are called from the
compositor thread, and so we assert that as well.

MozReview-Commit-ID: JPgGlgUUsgg

--HG--
extra : rebase_source : 8b950d3386e1e64e766b76edaa7894b251fb8664
2018-03-28 14:57:06 -04:00
Kartikaya Gupta
b015c3b3ec Bug 1447299 - Bounce PAPZCTreeManager controller messages through the sampler thread. r=botond
The methods on PAPZCTreeManagerParent are always invoked on the
compositor thread, which currently is always the same as the sampler
thread. When it does RunOnControllerThread calls, there is an implicit
ordering with respect to the sampler thread, because the controller
thread messages are always dispatched *from* the sampler thread.
When we move the sampler thread to be the render backend thread, we have
to preseve this implicit ordering, but we have to make it more explicit.

For example, if a content process sends a layers update followed by
a SetTargetAPZC message, it expects that the APZ will process them in
that order, as the SetTargetAPZC might refer to a scrollframe that was
just layerized. Currently, both these messages arrive on the compositor
thread; the layers update is processed directly as the compositor thread
is the sampler thread, and then the SetTargetAPZC message is bounced to
the controller thread. However, if the compositor thread is not the
sampler thread, then we would bounce the layers update to the sampler
thread, and bounce the SetTargetAPZC to the controller thread,
introducing a race. If SetTargetAPZC runs first bad things happen. The
solution in this patch is to bounce the SetTargetAPZC to the sampler
thread as well, so that it gets bounced to the controller thread only
after we have processed the layers update.

This patch accomplishes that by introducing a method on APZSampler that
does this "double bounce".

MozReview-Commit-ID: KI9wQQ9PZT4

--HG--
extra : rebase_source : 79d0d36a649f11cc795148cc86539a526c8beeae
2018-03-28 14:57:01 -04:00
Kartikaya Gupta
cf0569e64e Bug 1447299 - Have the APZCTreeManagerParent store a reference to the APZSampler. r=botond
MozReview-Commit-ID: BNhkhFAmYP8

--HG--
extra : rebase_source : 43ff9d5f74add3b8b8b0cf651d06a14d8ec82885
2018-03-28 14:56:55 -04:00
Kartikaya Gupta
eacf1f2dcc Bug 1447299 - Move the RunOnControllerThread from APZCTreeManager::SetLongTapEnabled to the caller. r=botond
This is functionally a no-op (it just moves the thread-bouncing code
from inside APZCTreeManager::SetLongTapEnabled to the call site in
APZCTreeManagerParent. The other call site, in
widget/android/nsWindow.cpp, is already known to be running on the
controller thread (which would be the Java UI thread in that case).

This makes the code in APZCTreeManagerParent more consistent and
simplifies the next changes.

MozReview-Commit-ID: 8VfEDVVFNl8

--HG--
extra : rebase_source : 02225ed5b80129a1d18b429eff93866a33d4ea86
2018-03-28 14:56:48 -04:00
Kartikaya Gupta
395eaf8c66 Bug 1448490 - Make the layers id a struct instead of a uint64_t. r=mattwoodrow
The new struct is in LayersTypes.h, all the rest of the changes are just
replacing existing uint64_t instances with the new LayersId struct.

Note that there is one functional change, in
CompositorBridgeParent::DeallocPWebRenderBridgeParent, where we now
correctly convert the PipelineId to a LayersId before using it to index
into sIndirectLayerTrees, whereas before we were incorrectly just using
the mHandle part of the PipelineId.

MozReview-Commit-ID: GFHZSZiwMrP

--HG--
extra : rebase_source : d2b274f63aaee2ee9bba030297e0a37a19af0d6c
2018-03-24 19:06:01 -04:00
arthur.iakab
24af737f4c Merge inbound to mozilla-central. a=merge 2018-03-22 01:46:39 +02:00
Ryan Hunt
aae4eeb5a2 Respect SYNC_DECODE when deciding to use Webrender for nsDisplayBackgroundImage. (bug 1439960, r=mstange)
Previously CreateWebrenderCommands would use GetLayerState to determine whether to use Webrender or
take the fallback path. GetLayerState would then under some cases call CanOptimizeToImageLayer()
which would get the image container using the appropriate flags for sync decoding.

Now nsDisplayBackgroundImage only uses CanCreateWebrenderCommands, which doesn't pass the correct
flags to image container, leading to reftest failures in some cases. This commit fixes that.

MozReview-Commit-ID: KlslXVHlRi5

--HG--
extra : rebase_source : aacb5fcae966cb9af8d8607e6c10e4c0822ea88d
2018-03-20 13:42:05 -05:00
Kartikaya Gupta
e862bb4f2f Bug 1447157 - Avoid crashing if an unregistered layer tree gets adopted. r=botond
It looks like we can get layer tree adopted messages when the compositor
doesn't have an entry for that layer tree in sIndirectLayerTrees. So we
need to null-check all the things we pull out of that structure - all
the properties are already null-checked except for the mParent. This
patch adds a null check around that as well.

MozReview-Commit-ID: 2fb4SdvgSrG

--HG--
extra : rebase_source : d6d053e1ae11288f4bfc5459993564ed6ba22133
2018-03-20 10:01:27 -04:00
Bogdan Tara
4785e99532 Merge inbound to mozilla-central. a=merge 2018-03-17 12:29:57 +02:00
Jeff Muizelaar
b0c6c75854 Bug 1439006. Allow multiple kinds of WebRenderUserData on a DisplayItem. r=mstange
Currently we can only have one type of WebRenderUserData on an Item. We already
have a hash table of WebRenderUserData so it's not hard to include type in the
hash to support one per type.

MozReview-Commit-ID: geJ0BeWv8b
2018-03-16 19:15:27 -04:00
Kartikaya Gupta
c864e00967 Bug 1441324 - Move the input event messages from PAPZCTreeManager to PAPZInputBridge. r=froydnj,rhunt
This remotes the APZInputBridge interface over the PAPZInputBridge
protocol in the case of the GPU process, and makes the GPU process'
main thread act as the APZ controller thread in that process. If
there is no GPU process we continue as before and the APZInputBridge
interface implementation is the concrete APZCTreeManager instance
in the UI process.

The main changes in this patch are moving all the code associated with
these messages out of APZCTreeManager{Parent,Child} and into
APZInputBridge{Parent,Child}. APZCTreeManagerChild now returns an
APZInputBridgeChild instance via InputBridge(), instead of returning
itself. The SetControllerThread call in the GPU process is also updated.

MozReview-Commit-ID: M4AaIW1Q0h

--HG--
extra : rebase_source : e5a8f14e23be34229fe80a47f6789d19b19e0a9f
2018-03-16 16:28:19 -04:00
Kartikaya Gupta
26139682b6 Bug 1441324 - Introduce an empty APZInputBridge protocol managed by PGPU. r=rhunt
This just adds the boilerplate that goes with the new protocol, without
adding any of the actual messages. The protocol is managed by PGPU, and
there will be one instance per compositor. The parent side lives on the
main thread of the GPU process, and the child side lives on the main
thread of the UI process. The protocol is only instantiated if the GPU
process is active.

MozReview-Commit-ID: J4VzwmEfYTa

--HG--
extra : rebase_source : 397ddda8b0e76e5ed5f63783b1220ed7b4414d99
2018-03-16 16:28:19 -04:00
Kartikaya Gupta
8848975da9 Bug 1441324 - Move the APZCTreeManager initialization for the GPU process to CompositorBridgeParent initialization. r=rhunt
This is important because the RecvInitialize method in CompositorBridgeParent
is run via a sync IPC message, and so we are guaranteed that when return to the
caller in the UI process, the APZCTreeManager will have been created. This
ensures that when we create the APZInputBridge actors (which will happen on a
different top-level protocol, but be triggered after the sync RecvInitialize
is complete) we know that the concrete APZCTreeManager is ready for use.

MozReview-Commit-ID: KYDyJNXxQJm

--HG--
extra : rebase_source : f7bbd000a94e405322ceaed6823693e4a95c81d4
2018-03-16 16:28:18 -04:00
Kartikaya Gupta
874af3e540 Bug 1441324 - Extract an APZInputBridge interface from IAPZCTreeManager. r=rhunt
This separates the methods that are used to deliver input events
synchronously over IPDL to the compositor; this interface will be
remoted over a new APZInputBridge IPDL protocol in future patches.

MozReview-Commit-ID: 1f3V9SUKlfW

--HG--
rename : gfx/layers/apz/public/IAPZCTreeManager.cpp => gfx/layers/apz/src/APZInputBridge.cpp
extra : rebase_source : 523abce7949baf9e3b7803a61632eb4434a6967f
2018-03-16 16:28:18 -04:00
Kartikaya Gupta
d16ab46492 Bug 1445662 - Update RemoteContentController to allow the GPU process controller thread to be different from the compositor thread. r=rhunt
A couple of RemoteContentController methods get called on the controller
thread in the GPU process. This is the same as the compositor thread so
we could just do compositor-thread stuff here, but we will want to
support the controller thread being the main thread instead of the
compositor thread. So we detect those cases and bounce the message
accordingly.
2018-03-15 15:25:11 -04:00
Kartikaya Gupta
5083c84c88 Bug 1445662 - Ensure ZoomToRect runs on the controller thread. r=rhunt
Currently the ZoomToRect function is only ever called on Android, on the
UI process main thread, which is neither the controller nor the sampler
thread. Instead of allowing "random" threads to run inside APZ, we
ensure that callers run it on the controller thread.
2018-03-15 15:25:10 -04:00
Kartikaya Gupta
323f2093f0 Bug 1445662 - Remove ProcessTouchVelocity from PAPZCTreeManager.ipdl. r=rhunt
This function is never actually called over IPDL. It is called directly
on the concrete APZCTreeManager instance by the
AndroidDynamicToolbarAnimator code, both of which live in the
compositor. So we don't need to expose this method on IAPZCTreeManager
or over PAPZCTreeManager.
2018-03-15 15:25:09 -04:00
Kartikaya Gupta
9ab9425d9f Bug 1445662 - Make the DPI non-static and bound to the controller thread. r=rhunt
Since we can have multiple browser windows on multiple different
displays with different DPIs, it doesn't make sense to have a single
static DPI value shared across all APZCTreeManagers. Instead, each
APZCTM should store its own DPI value for the display the window is on.
Since the DPI is only ever read from the controller thread, we can make
it bound to that thread, and update the setter code to also set it on
that thread.

As with the previous patch, the change in APZCTreeManagerParent is a
no-op but allows making some other thread in the GPU process the controller
thread. And the change in nsBaseWidget is a no-op everywhere except
Android.
2018-03-15 15:25:09 -04:00
Kartikaya Gupta
d59c0946db Bug 1445662 - Ensure the keyboard map access is threadsafe. r=rhunt
- The change in APZCTreeManagerParent is functionally a no-op because it
  only ever runs in the GPU process on the controller thread. But it
  allows moving the controller thread to some other thread.
- The change in nsBaseWidget is a no-op for desktop platforms, because
  in the UI process the main thread is the controller thread. But on
  Android it moves the call from the main thread to the Java UI thread.
2018-03-15 15:25:08 -04:00
Peter Bacalso
0445cb7bdd Bug 1443292 - Move TouchBehaviorFlags from APZUtils.h to LayersTypes.h. r=botond
--HG--
extra : rebase_source : 2b4b07718222f65d8e30342b6f52eec114358318
extra : amend_source : b4fe1d0570f7f8c19f545504cd6a33fe3345d476
2018-03-14 18:18:27 -04:00
Andrew Osmond
a53f4da6d7 Bug 1445802 - Disable broken asserts to unbreak Windows QR mda tests. r=aosmond 2018-03-15 06:42:19 -04:00
Ryan VanderMeulen
ca477b1e34 Bug 1445766 - Fix some non-unified build bustage in gfx/layers. r=lsalzman 2018-03-14 17:03:29 -04:00
Ryan Hunt
691f20afd2 Remove ReadLockHandle and ReadLockInit code (bug 1445008, r=aosmond)
This code is unused now that ReadLockDescriptors are not sent in layer transactions.

--HG--
extra : rebase_source : 8cd25541b22c3151e2dbd2f8ea6d1119e2f26c94
extra : source : 99a2d26d1ba82ad34a6c27641500a424cda015c3
2018-03-13 17:00:18 -05:00
sotaro
58a1b5e3d2 Bug 1443671 - Check aImageContainer in ImageBridgeChild::Connect() r=nical 2018-03-14 20:08:29 +09:00
sotaro
1c6ef8fcb9 Bug 1426588 - Add more check to CrossProcessCompositorBridgeParent::AllocPWebRenderBridgeParent() r=nical 2018-03-13 13:53:07 +09:00
Kartikaya Gupta
99522f2154 Bug 1258238 - Remove code that displays visibility visualization on the APZ minimap. r=mattwoodrow
This code was originally added to debug the frame visibility code.
However it wasn't architected correctly and makes the compositor use an
untrusted layers id from content. Instead of fixing this I'd rather just
delete it, since it's a big pile of code that is basically a debugging
tool that nobody owns anymore.

MozReview-Commit-ID: nPZqVeYsFp
2018-03-12 14:17:34 -04:00
Ryan Hunt
084c9b6f4c Allocate TextureReadLock at TextureClient creation and drop file handles immediately after. (bug 1416726, r=aosmond)
This changes the lifecycle and API for TextureReadLock to fix file descriptor exhaustion
crashes. These changes are partially superficial and mostly align the API of TextureReadLocks
with their actual usage.

The changes are:

1. Create the TextureReadLock in the TextureClient constructor so it's available before IPC creation
    a. This is superficial as EnableReadLock was always called before IPC creation
2. Send the ReadLockDescriptor in the PTextureConstructor message and close the file handle
3. Receive the ReadLockDescriptor in TextureHost and close the file handle
4. Send a boolean flag in layer transactions if the texture is read locked instead of a descriptor
5. Use a boolean flag in TextureHost to determine if the ReadLock must be unlocked instead of a nullptr

I believe that we can remove the InitReadLocks code from LayerTransaction as that was added to
prevent file descriptor limits in IPDL messages and is no longer needed with this change. But
that is a non-essential change and this patch is already big enough.

MozReview-Commit-ID: DzHujrOQejH

--HG--
extra : rebase_source : 3bdd7c9bc8edfdc386faad8a9e59ad7dc18ed91d
2018-03-12 08:10:13 -05:00
Kartikaya Gupta
f42d692541 Bug 1444374 - Make the LayerTransactionParent's mId always nonzero. r=mattwoodrow
We can easily populate the mId with the correct layers id, which is the
root layer tree id from the CompositorBridgeParent. This eliminates a
bunch of special-case handling.

MozReview-Commit-ID: FEkboAGEhYO

--HG--
extra : rebase_source : 01e73d516e5742d586cbf6d8b6bc5c9f7d64f141
2018-03-09 08:45:26 -05:00
Brindusan Cristian
eb51abf4fb Merge inbound to mozilla-central. a=merge 2018-03-08 20:00:36 +02:00
Nicolas Silva
0405d57c60 Bug 1352877 - Assert that the global compositor map is accessed on the right threads. r=mattwoodrow 2018-03-08 09:56:11 +01:00
Kartikaya Gupta
a205ba0c5f Bug 1443301 - Stop exposing mApzcTreeManager from CompositorBridgeParent. r=botond
MozReview-Commit-ID: 5Dq0HzLImTz

--HG--
extra : rebase_source : 9329303f382fa94b0a2f05226ad5e993c83490e6
2018-03-07 17:34:11 -05:00
Kartikaya Gupta
eb67d6cb7b Bug 1443301 - Update dynamic toolbar init codepath to not need an APZCTreeManager. r=botond
MozReview-Commit-ID: BthTS5k1PDW

--HG--
extra : rebase_source : 9f26d5e40f2ce4979cf55018844271350f11a6fa
2018-03-07 17:34:11 -05:00
Kartikaya Gupta
b9c7b63015 Bug 1443301 - Remove unused function. r=botond
MozReview-Commit-ID: I05MwCw8VdK

--HG--
extra : rebase_source : fdfac26097179513fa5189ec7892f158d1fe24f9
2018-03-07 17:34:10 -05:00
Kartikaya Gupta
ff4a47d56e Bug 1443187 - Avoid crashing if a previously-uncomposited layer tree gets adopted. r=botond
MozReview-Commit-ID: FZYwS7IwdKq

--HG--
extra : rebase_source : ea7b093df17887af841cb4ccdd64d47a69c016ad
2018-03-07 16:41:44 -05:00
Hiroyuki Ikezoe
be2fe6bf8c Bug 1437272 - Split nsTimingFunction into an independent header file. r=birtles
So that we don't need to include nsStyleStruct.h in gfx any more.

MozReview-Commit-ID: 6nOaAbssLCz

--HG--
extra : rebase_source : 9c195c90277a4584dc14a6949e9eea53bcd8487c
2018-03-08 18:22:45 +09:00
Kartikaya Gupta
98952dab6e Bug 1442627 - Stop exporting a few other apz/src headers. r=botond
These were mostly exported because APZCTreeManager included them and now
they don't need to be exported any more.

MozReview-Commit-ID: 8W3vKOvzYW3

--HG--
extra : rebase_source : 8da95a203692ab3a88d37e66071b914682b44f14
2018-03-06 10:25:39 -05:00
Kartikaya Gupta
45d31fa895 Bug 1442627 - Stop exporting APZCTreeManager.h in mozilla/layers/. r=botond
MozReview-Commit-ID: GC5fSWOYtF5

--HG--
extra : rebase_source : e2dfe679595bf9208e082699a99375cd509b66e3
2018-03-06 10:25:39 -05:00
Kartikaya Gupta
b18710abb6 Bug 1442627 - Move static helpers from APZCTreeManager to APZUtils. r=botond
This also includes unified build fixes that were needed as a result of
the shuffling around.

MozReview-Commit-ID: 1AGG3DHnN1m

--HG--
extra : rebase_source : 7399cea6dff2bd91ab305dee22d93b32382cc0be
2018-03-06 10:25:39 -05:00
Kartikaya Gupta
d437c0bee5 Bug 1442627 - Reduce exposure of the APZCTreeManager. r=botond
Callers should be using one of the more specific subinterfaces like
IAPZCTreeManager (for controller-API methods) or APZSampler (for
sampler-API methods). There's also a bunch of android-specific
dynamic toolbar code that uses this function - I don't want to
deal with that right now, so instead of removing it entirely we can just
make it Android-only.

MozReview-Commit-ID: I8DYWLYoFgP

--HG--
extra : rebase_source : 75e05825194f9c6843506bb5d82e1a0c6e2b08bb
2018-03-06 10:25:38 -05:00
Kartikaya Gupta
6107f5de3d Bug 1442627 - Add new APZSampler APIs to set the test scroll offset and zoom. r=botond
MozReview-Commit-ID: DrH1D42jfJx

--HG--
extra : rebase_source : 22c2546a8188c871bf106d5883452a1be32c482e
2018-03-06 10:25:37 -05:00
Kartikaya Gupta
551f604b60 Bug 1442627 - Don't use GetAPZCTreeManager in CrossProcessCompositorBridgeParent. r=botond
Although CrossProcessCompositorBridgeParent still needs to create a
dummy APZCTreeManager of its own in place, we can at least stop it from
grabbing the "real" APZCTreeManager from CompositorBridgeParent, which
allows access to methods that might not be properly guarded with respect
to thread safety.

MozReview-Commit-ID: Btvez3OkFPs

--HG--
extra : rebase_source : a4bec1769ff2fb899bb2e65f99f8e715f9a94c44
2018-03-06 10:25:36 -05:00
Nika Layzell
69042a522a Bug 1440511 - Part 8: Include ParamTraits impls which are used in ipdlh files, r=froydnj
MozReview-Commit-ID: 9AfzlhyTgsY
2018-03-05 16:00:03 -05:00
Kartikaya Gupta
7bb7b24179 Bug 1441916 - Introduce an APZSampler interface for APZCTreeManager. r=botond
This interface should be used for accessing any sampler-thread functions
on APZCTreeManager. Eventually the interface will handle thread
delegation so that if it is called from a thread that is not the sampler
thread it will redirect the calls appropriately. For now it just allows
to logically group the public APZCTreeManager methods that are to be run
on the sampler thread.

MozReview-Commit-ID: GArPvjfuYYr

--HG--
extra : rebase_source : 884cf6c3ce00f3df8ffe7dfa5fc12ef971f3cefc
2018-03-01 23:00:41 -05:00
Kartikaya Gupta
3565e0cee9 Bug 1441916 - Modify the static GetAPZCTreeManager to return an IAPZCTreeManager. r=botond
This static function has only two call sites. One (in GPUProcessManager)
is unused, so it can be removed. The other (in
InProcessCompositorSession) takes the returned APZCTreeManager and
exposes it as an IAPZCTreeManager. Instead of doing this, we can simply
expose it as an IAPZCTreeManager from CompositorBridgeParent itself, to
reduce the number of places that can potentially grab a handle to the
APZCTreeManager.

MozReview-Commit-ID: BjLf6GSsnKz

--HG--
extra : rebase_source : ab24190a12053db06192fab4d1b7a932fe2d1724
2018-03-01 23:00:41 -05:00
Kartikaya Gupta
bad638dcd9 Bug 1441916 - Introduce the notion of the APZ sampler thread. r=botond
The sampler thread is similar to the controller thread in that it doesn't
correspond to a particular actual thread, but instead introduces an
abstraction that allows us to reason about code flow and data ownership
that is logically grouped on a single thread. For now the sampler thread
remains mapped to the compositor thread, but eventually we will allow
it to be render backend thread when webrender is enabled.

MozReview-Commit-ID: D6i2t5lDvkv

--HG--
extra : rebase_source : 06211ad878973c76ca3fd618386bbbd0cfdd4821
2018-03-01 23:00:41 -05:00
Kartikaya Gupta
1f2c9f3565 Bug 1441916 - Move APZTestData from the LayerTreeState structure into the APZ. r=botond
This encapsulates the APZTestData better inside APZCTreeManager, which
we will want once we allow the hit-test tree update to happen on a
thread other than the compositor thread.

MozReview-Commit-ID: 66uSsagVfEu

--HG--
extra : rebase_source : 8e6ae809bfa0dde4e0e5fb2e321dd315174eafd6
2018-03-01 23:00:40 -05:00
Kartikaya Gupta
728f8af857 Bug 1441916 - Add hooks in APZCTreeManager to respond to layer tree changes. r=botond
MozReview-Commit-ID: 4dDYQ1YGOO

--HG--
extra : rebase_source : 819e53bde7b1ebf4a6d9d5df0f0f96956c0d0006
2018-03-01 23:00:40 -05:00
Zhang Junzhi
3492fb331e Bug 1438794 - Makes single-line text controls in vertical-writing mode vertically scrollable if they overflow vertically; and makes them horizontally unscrollable no matter whether they overflow horizontally. r=kats
As for now, the scrollable direction with a mouse wheel for a single-line text
control is hard-coded; that is, only horizontal wheel scrolls are able to take
effect while vertical ones aren't. However, this isn't the desired case for
vertical writing mode, where the opposite case definitely suits better.

This commit refines the hard-coded scrollable direction for a single-line text
control to be writing-mode-adaptive.

MozReview-Commit-ID: 4Zkoe2ExPCZ

--HG--
extra : rebase_source : 113b2ea80b6bbbcd2d8379b438de97eedd616551
2018-02-23 02:40:44 +08:00
Botond Ballo
9bafb4c0f9 Bug 1440112 - Support CompositorHitTestInfo::eRequiresTargetConfirmation with EventRegions-based hit testing. r=kats
This is only hooked up for the codepath where the event regions are built
from nsDisplayCompositorHitTestInfo display items, not for when they're
build from nsDisplayLayerEventRegions display items.

--HG--
extra : rebase_source : 4f6fedcd9522362e2e62678428987180399bb796
2018-02-23 17:37:55 -05:00