Commit Graph

49 Commits

Author SHA1 Message Date
Gopinath Elanchezhian
e5f28772ef Move Tradefed content provider installation in preparer.
Pushing sample file in /sdcard automatically installs the
content provider. This is done to reduce noise during the second
test in the test suite.

Bug: b/164992819

Test: atest MultiUserPerfTest
Change-Id: I1dd583acc850e1233f06af50e28e2ebb0adc0df1
2020-08-18 23:45:18 +00:00
Gopinath Elanchezhian
89c157c419 Update atest configs for multi user test.
1) Setup and collect the trace files per test.
2) Wait for the device to stabilize before invoking the test.

Bug: b/155805394

Test: atest android.multiuser.UserLifecycleTests#startUser

Change-Id: Iecce6db9796a27875d4b388f82b74e4ea213e454
2020-08-03 12:56:01 -07:00
TreeHugger Robot
9d4d7d15ab Merge "UserLifecycleTests - give proper errors on fail" 2020-06-24 10:05:26 +00:00
Adam Bookatz
b995a6b215 UserLifecycleTests - give proper errors on fail
More 'attestation' messages are added, which
provide logcat messages in the case of failed tests
while telling the benchmarkrunner to mark the test
as having failed (and return a value of -10).

Tests no longer throw checked exceptions; we catch
all such exceptions and log them properly.
The exception is RemoteException, which we have
allowed to throw for now but may handle in a future cl.

Test: atest UserLifecycleTests
Bug: 159650471
Change-Id: I4ca9d7186d195388f928f6a6037c6d4ccd79a0ea
2020-06-24 00:40:22 -07:00
TreeHugger Robot
e8703fcd67 Merge "Make UserLifecycleTests more robust to previous fails" 2020-06-24 06:49:33 +00:00
Adam Bookatz
b4e86c8c21 Make UserLifecycleTests more robust to previous fails
If a UserLifecycleTests test failed in a bad way, there could
potentially be users that it created lingering on the device,
which can cause future UserLifecycleTests to fail too. To prevent
this, we make all created test users with the name
UserLifecycleTests_test_user
and we remove all users with this name at the beginning of each test.

Test: atest UserLifecycleTests (including with previous failed users)
Bug: 159650471
Change-Id: I8a652c85fe1d73b2f785c7d16ebe8bfd39ea4710
2020-06-23 18:03:34 -07:00
Gopinath Elanchezhian
f3050aa0a9 Merge "Add collector library in multi user per test apk." into rvc-dev am: 3ed037cb40 am: f99536c399 am: d0da6a267b am: fa680b71fa
Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/base/+/11886051

Change-Id: I1c930cc29b67d0136f0c87ace8685a5b9b070547
2020-06-20 16:24:48 +00:00
Gopinath Elanchezhian
3745571a06 Add collector library in multi user per test apk.
Enable permissions needed to write the trace file in the device.

Bug: b/155805394

Test: make MultiUserPerfTests
Change-Id: I650307133c5325aa92aa6e12f2a77566f314f174
2020-06-16 15:09:08 -07:00
Adam Bookatz
a71fdb9ef7 UserLifecycleTests handles crashes
Previously, if a test failed or crashed, no results
would be returned. And if the test 'succeeded', but
with the wrong data (e.g. the secondary user actually
failed to be created), the results would simply display
bad data.

Here, we make it so that *any* test failure will officially
report a value of -10ms.
-10ms was chosen since it is clearly 'wrong' yet won't skew
the dashboard (since the value is not far from 0).

The actual runs will be allowed to proceed, so that more
detailed information will be available in the logs. But
the final reported Benchmark data will be a simple -10ms.

At this point, we take the approach that if one of the four
iterations fail, the entire test is declared to have failed.
This is to highlight failures, since we don't know their
frequency yet. We may change this in the future.

Test: atest UserLifecycleTests (and trigger some failures)
Bug: 137127051
Change-Id: Iab4e4d9c5194976af8e53bc8808a4a16918e0865
2020-05-13 11:16:39 -07:00
Philip P. Moltmann
12ac3f406f Rename featureId -> attributionTag
In the core functionality this changes everything including aidl's and
field names:
- Context
- ContentProvider
- AppOps*
- Package parsing

For the rest, this is a shallow change to only change to the changed
APIs. This keeps the change small-ish

Exempt-From-Owner-Approval: Rename
Fixes: 148792795
Test: TH
Change-Id: I2a2245fe76e09e62cb13d5785d2efb4a304ba54a
Merged-In: I2a2245fe76e09e62cb13d5785d2efb4a304ba54a
2020-03-12 19:26:10 +00:00
Philip P. Moltmann
8a06c2870e Rename featureId -> attributionTag
In the core functionality this changes everything including aidl's and
field names:
- Context
- ContentProvider
- AppOps*
- Package parsing

For the rest, this is a shallow change to only change to the changed
APIs. This keeps the change small-ish

Exempt-From-Owner-Approval: Rename
Fixes: 148792795
Test: TH
Change-Id: I2a2245fe76e09e62cb13d5785d2efb4a304ba54a
2020-03-11 23:52:32 +00:00
Philip P. Moltmann
ee29509ecd Revert "Revert "Activity start: Send featureId from context->AppOpsManager""
This reverts commit e7421e92d9.

Exempt-From-Owner-Approval: revert-revert and only piping anyway
Test: 1:1 revert-revert
Bug: 136595429
Change-Id: I44e5fa2019f5604c6e2c08bdd1967129c64a90a7
2020-02-12 18:51:53 +00:00
Philip P. Moltmann
e7421e92d9 Revert "Activity start: Send featureId from context->AppOpsManager"
Revert "Adjust monkey to changed internal APIs"

Revert "Test featureId is correctly used in startActivity"

Revert submission 10111030-activityStarter_featureId

Reason for revert: presubmit test breakage
Reverted Changes:
Ic7056b492: Activity start: Send featureId from context->AppOp...
I8e2a07da7: Adjust monkey to changed internal APIs
I7a6af6fb1: Test featureId is correctly used in startActivity

Change-Id: I48c55a962c990b22ea49e923baa7c73b121d179b
2020-02-10 16:14:12 +00:00
Philip P. Moltmann
9c5226fe36 Activity start: Send featureId from context->AppOpsManager
The expected usage pattern for noteOp is to get the
Context#getOpPackageName() and Context#getFeatureId() in the calling app
and the call

noteOp(callingPackageName, Binder.getCallingUid(), callingFeatureId)

As the featureId parameter is new this parameter has to been piped all
through from the ...Manager classes running in the app all way deep into
the bowels of the system server.

There is a special featureId==null for the "default" feature. This is
used in two cases:
- In case the system server (packageName == null || packageName ==
  "android") makes a call
- In the case there is no caller. In this case I left annotations in the
  code to make clear that the default feature is used

Raw binder interfaces (defined in AIDL files) are not supposed to be
used by apps. Still historically this has happened and we ended up with
@UnsupportedAppUsage tags in these files. Also AIDL does not support
two methods with the same name but different parameters. I.e. in the
case when I had to add a paramater to a method tagged as UnsupportedAppUsage I
- created a new method ...WithFeature with the additional paramter
- set a maxTargetSDK for the old method and mention the public API to
  use in the deprecation method
This is really not pretty. Once there is no more app using the old
internal API this hack can be removed.

Additionally this change removed all internal calls to
AppOpsService.noteOperation and AppOpsService.checkOperation and
replaces them with the public API equivalent. This sometimes means to
move the resolution of the mAppOpsManager to be lazy.

Exempt-From-Owner-Approval:: Just piping through arguments
Bug: 136595429
Test: atest --test-mapping frameworks/base/services/core/java/com/android/server/am/
      atest CtsAppOpsTestCases added test to cover activity start
      atest WmTests
Change-Id: Ic7056b492cb1c9a79158e6c2b4864898a0eb5b2a
2020-02-08 22:53:43 +00:00
jovanak
288a18ff21 Adding more granular startUser perf benchmarks.
Fixes: 146154399
Test: atest UserLifecycleTests
Change-Id: Ie781edc70a8a2fc0635e74350c139b5c09441dca
2019-12-19 14:34:35 -08:00
Bookatz
029832a951 Introduce user types
Introduces the notion of 'user types' to UserManager.
Previously, users only had properties, set by UserInfo flags. We now
solidify some of these as formal user types. Each user must be of
precisely one user type. The configuration of each type is defined
in a UserTypeDetails object.

Prior 'types' - namely Guest, Restricted, ManagedProfiles, Demo, and
'normal' - that were set via UserInfo flags are now controlled via
UserType. Previous UserInfo flag methods for categorizing these are
still supported as long as no user of of more than one type.

If a user was (e.g.) previously both Guest and Demo, it is now
invalid and will be prevented from upgrading. This should not be a
problem in AOSP, where these 'types' were assumed mutually exclusive.

UserTypeDetails is sufficiently general to support future non-managed
profiles. To this end, the logic for specifying badges and their
colors/labels is contained by UserTypeDetails, and therefore
UserManager is responsible for delivering the corresponding badge
information.

Bug: 142151520

Test: added new test class UserManagerServiceUserTypeTest
Test: added additional tests in UserManagerServiceUserInfoTest
Test: added additional tests in UserManagerTest
Test: added additional tests in UserManagerServiceCreateProfileTest
Test: created UserTests to run the various pm.User*Test's

Test: atest \
  com.android.server.pm.UserTests \
  UserLifecycleTests \
  ManagedUserContentResolverTest \
  CtsDevicePolicyManagerTestCases \
  CtsMultiUserHostTestCases \
  com.android.server.devicepolicy.DevicePolicyManagerTest \
  com.android.server.am.UserControllerTest \
  CreateManagedProfileTaskTest

Test: atest com.android.server.pm.UserManagerServiceCreateProfileTest
   using adb shell getprop persist.sys.max_profiles # for 5 and -1

Change-Id: Id1183a76055e9a7610965cf40b256d1392afe6f8
2019-11-14 10:00:50 -08:00
Bookatz
04d7ae5c6f Whitelist packages for user types
Creates a new SystemConfig xml entry which allows a device to whitelist
system packages to be installed on users when they are created, based on
the type of user.

System packages will be installed on users when they are created, or
during OTAs, based on this whitelist. The whitelist can be
enabled/disabled via a Config resource.

For any user type, system packages can be whitelisted or blacklisted.
If it is both (for the same user type), the blacklist takes priority.
If it is neither, it won't be installed (since it isn't whitelisted).

If a system package isn't mentioned in the whitelist file at all, for
any user, then its behaviour depends on the Config resource value, which
can optionally implicitly whitelist all such apps on all users.

For now, the list is mostly empty and the default config is set to be
enabled but implicitly whitelist all system packages that are not
mentioned.

Test: atest FrameworksServicesTests:SystemConfigTest
Test: atest com.android.server.pm.UserManagerServicePackageWhitelistTest
Test: manually test user 0 by flashall -w and checking packages
Test: manually test OTA by setting setprop persist.pm.mock-upgrade 1
Bug: 134605778

Change-Id: Ia098c1f597f66a1c946cfcc9b7771c25e8ceabf7
2019-09-24 09:38:58 -07:00
jovanak
6e6c6bfd92 Adding create user benchmark to UserLifecycleTests.
We already have createAndStartUser - but we should aim for more granular benchmarks as well, and this isolate create user timing only.

We'll keep createAndStartUser for now, since it contains all the historical data associated with it.

Bug: 140101272
Test: atest UserLifecycleTests
Change-Id: I0df72c90f7fd7bcdc8928d8510ffe36094a4d832
2019-09-04 14:40:18 -07:00
jovanak
5982cd90d0 Skipping managed profile tests for devices that don't support MANAGED_USERS.
Fixes: 13913456
Test: atest MultiUserPerfTests - on automotive, since it doesn't have managed users feature
Change-Id: I8dec1291ddeb6e1bfc6142fece08e1ab2779c89a
2019-08-08 11:27:56 -07:00
Robert Horvath
5f47c59103 Pass callingPackage in UserLifecycleTest#startApp
Calling IActivityTaskManager#startActivity requires the callingPackage
to be set correctly as of ag/8668823, otherwise a SecurityException is
thrown.

Bug: 138095678
Test: Enable multi-user by declaring the
      "android.software.managed_users" feature and setting
      "config_multiuserMaximumUsers" to greather than 1. Then:
      `atest android.multiuser.UserLifecycleTests#managedProfileUnlockAndLaunchApp`

Change-Id: Iab7cf0198a02a976ef5c54e4b87fb127aa7eac9a
2019-07-24 16:33:37 +02:00
TreeHugger Robot
0f68f48b82 Merge "PerftestMultiuserDummyApp > MultiUserPerfDummyApp" 2019-06-03 18:57:01 +00:00
Bookatz
5f87019157 Multiuser perf test: re-launching app in profile
Times starting (unlocking) and launching a previously-launched app
in an already-created, but no-longer-running, profile. This represents
how long it would take to immediately start a profile and launch an app
within it for a re-used profile.

Bug: 129857107
Test: atest multiuser.UserLifecycleTests#managedProfileUnlockAndLaunchApp_stopped
Change-Id: I34cc9aeef07ea6481f4d168cda47b5dea69a5a74
2019-05-31 13:34:04 -07:00
Bookatz
8bdf3a63a7 PerftestMultiuserDummyApp > MultiUserPerfDummyApp
Renames PerftestMultiuserDummyApp to MultiUserPerfDummyApp.
This dummy app will be added to the platform testing, and it's useful
for the name of the dummy app to be alphabetically adjacent to the
test app (MultiUserPerfTests).

Also removes an unnecessary Android.mk file in an empty directory.

Bug: 133510429
Test: atest multiuser.UserLifecycleTests#managedProfileUnlockAndLaunchApp
Change-Id: Ifcdaa36e39b6d2a5e42decd9277d9afbf3a75d78
2019-05-30 11:36:22 -07:00
TreeHugger Robot
7d1f25b8ca Merge "Fix multiuser.UserLifecycleTests dummy app" 2019-05-22 05:32:58 +00:00
Bookatz
e525bae925 Fix multiuser.UserLifecycleTests dummy app
The dummy app (used in managedProfileUnlockAndLaunchApp and
managedProfileCreateUnlockInstallAndLaunchApp) wasn't compiling
properly, so we fix that here.

Test: atest multiuser.UserLifecycleTests#managedProfileUnlockAndLaunchApp
Test: atest multiuser.UserLifecycleTests#managedProfileCreateUnlockInstallAndLaunchApp
Change-Id: I3456824e2d31c6f2d2f9f6b892703a02c141d91c
2019-05-21 14:06:21 -07:00
Philip P. Moltmann
bfcffa0851 Whitelist all perms on installExistingPackage
The code allows to also whitelist only a select set of permissions, but
this is not yet exposed in the API.

Also: Fix up shell commands for restricted permissions

Fixes: 132368462
Test: - Enabled app via device admin in secondary profile
        -> verified that permissions were whitelisted
      - Installed existing and new app using --restrictpermissions and
        not
	-> verified that permissions were whitelisted or not
      atest AppRestrictionsHelperTest
            RestrictedPermissionsTest
Change-Id: I9787e63d8beb8f6b1ba2d15532d4c0f69dbdf863
2019-05-15 11:12:47 -07:00
Bookatz
312da055c2 Multi-user profile perf-tests
Tests that time how long it takes to
create/start/install-an-app/launch-an-app in a secondary profile.

Also, in the test, adds newly created users to the remove list, so that
even if the test crashes, the user will get removed by test cleanup.

Test: atest multiuser.UserLifecycleTests
Bug: 129857107
Change-Id: I13f7cb1628bf4a97771cb1b143ab524d7d0a2073
2019-04-16 16:31:31 -07:00
Bookatz
5df3c64c9b Reordering UserLifecycleTests in prep for more
Will add more tests. Want the profile tests together. To make review
easier, moving a test away from the profile tests.

Test: N/A
Change-Id: Idf757414dd35acb46a41701a3981cdf37a7779eb
2019-04-11 09:22:49 -07:00
TreeHugger Robot
117d17b96f Merge "MultiUserPerfTest - test restart profile" 2019-04-03 22:03:51 +00:00
Bookatz
52b12ac7a1 MultiUserPerfTest test switch to pre-existing user
Creates two new MultiUserPerfTests, timing how long it takes to switch
to a pre-existing user, one for when the user is already-started, and
the other for when it is stopped.

Bug: 126745587
Test: make MultiUserPerfTests && adb install -r ${ANDROID_PRODUCT_OUT}/data/app/MultiUserPerfTests/MultiUserPerfTests.apk && adb shell am instrument -e class android.multiuser.UserLifecycleTests -w com.android.perftests.multiuser/androidx.test.runner.AndroidJUnitRunner
Change-Id: I734f4971ad992e906a0090f4ef328255ab2a0349
2019-03-29 10:46:09 -07:00
Bookatz
57908d9f2e MultiUserPerfTest - test restart profile
Creates a profile, starts it, stops it, then restarts it, timing how
long the restart takes. This gives an indication of how long it takes to
start a previously-initialized profile, and mimics toggling
setQuietModeEnabled.

Right now, this process is especially slow due to
RoleManagerService.onStartUser(), so it is worthwhile tracking this.

Bug: 129415917
Test: atest  android.multiuser.UserLifecycleTests#managedProfileUnlock_stopped
Change-Id: Ic7f3bdb6fa7daaab53cb23dbf8e8a68e293d23b2
2019-03-29 10:40:10 -07:00
Sudheer Shanka
c7dc355feb Merge "Don't change the order of test results." 2019-02-22 18:31:07 +00:00
Sasha Smundak
500db62bfa Convert Android.mk file to Android.bp
See build/soong/README.md for more information.

Bug: 122332340
Test: treehugger
Change-Id: I23d8d5a019155a0f3296f7ab75e9b44b7621f3c8
2019-02-19 13:46:51 -08:00
Sudheer Shanka
f69fc9c445 Don't change the order of test results.
Test: atest apct-tests/perftests/multiuser/src/android/multiuser/UserLifecycleTests.java
Change-Id: Ie21030581ae81509eaa5b3ec31d5e6978dcb23d4
2019-02-11 00:23:29 -08:00
KOUSHIK PANUGANTI
130f0a5c48 Migrate frameworks/base/apct-tests/perftests/multiuser to androidx.test
See go/jetpack-test-android-migration

Test: make checkbuild
Change-Id: I73fc89de69f1eb54896a2dc19cf93b22bc4f049d
2018-12-17 14:41:06 -08:00
Felipe Leme
6378b48f23 Initial PERF tests for autofill.
These tests render an activity that has 2 autofillable views (username and
password) and keep focusing between then, observing what happens in 4 scenarios:

1. No autofill service (baseline)
2. Autofill service returning no datasets.
3. Autofill service returning a dataset with username and password.
4. Autofill service returning a dataset with just username.

Because this change introduced a helper class to run shell commands without
needing the UiAutomator package, it also changed the MultiUserPerfTests to use
such helper.

Test: mmma -j ./frameworks/base/apct-tests/perftests/core/ &&  \
  adb install -r $OUT/data/app/CorePerfTests/CorePerfTests.apk && \
  adb shell am instrument -w -e class android.view.autofill.AutofillPerfTest \
  com.android.perftests.core/android.support.test.runner.AndroidJUnitRunner
Test: mmma -j ./frameworks/base/apct-tests/perftests/multiuser && \
  adb install -r $OUT/data/app/MultiUserPerfTests/MultiUserPerfTests.apk && \
  adb shell am instrument -w -e class android.multiuser.UserLifecycleTests \
  com.android.perftests.multiuser/android.support.test.runner.AndroidJUnitRunner

Bug: 38345816

Change-Id: Ie283dff8dd19c38ea829de9164b23aae2bfeb015
2018-05-01 12:40:33 -07:00
Nicolas Geoffray
eff3f44260 Exempt two performance tests from hidden API checks.
Bug: 64382372
Bug: 74963051
Bug: 76162083

Test: m
Change-Id: I50f2c8993cfb8fc7b78dc8c87b2cd8d9ee92d98e
2018-04-06 09:20:33 +01:00
jdesprez
3e09705662 Add the CorePerfTests and MultiUserPerfTests to APCT metrics
Add them to the suite version of APCT metric instrumentation.

Test: atest CorePerfTests
Bug: 77280599
Change-Id: Ia8f0c44fcb9fd21869ed64e54483aa87556a469d
2018-03-29 12:17:50 -07:00
Anton Hansson
ab6ec61251 frameworks/base: Set LOCAL_SDK_VERSION where possible.
This change sets LOCAL_SDK_VERSION for all packages where
this is possible without breaking the build, and
LOCAL_PRIVATE_PLATFORM_APIS := true otherwise.

Setting one of these two will be made required soon, and this
is a change in preparation for that. Not setting LOCAL_SDK_VERSION
makes the app implicitly depend on the bootclasspath, which is
often not required. This change effectively makes depending on
private apis opt-in rather than opt-out.

Test: make relevant packages
Bug: 73535841
Change-Id: I4233b9091d9066c4fa69f3d24aaf367ea500f760
2018-02-28 15:13:23 +00:00
Fyodor Kupolov
3de2b2e14e Wait for broadcast queue to become idle between test runs
Test: bit MultiUserPerfTests:android.multiuser.UserLifecycleTests
Bug: 64165549
Change-Id: I593885d737fab1ef717a166f6219129809ccfd99
2017-10-05 14:26:00 -07:00
Sudheer Shanka
2d0278b09f Update user perf tests to report only mean.
Test: bit MultiUserPerfTests:android.multiuser.UserLifecycleTests
Change-Id: Ib70123217c54b469844ce65ec52b7e7ed5b5998d
2017-07-12 18:15:02 -07:00
Sudheer Shanka
a319f8b35d Update test names in UserLifecycleTest.
Test: bit MultiUserPerfTests:android.multiuser.UserLifecycleTest
Change-Id: I49908f8da023a419b79124cc2f366f6d5e8a066d
2017-07-11 15:28:48 -07:00
Sudheer Shanka
5f76e1fa85 Fix UserLifecycleTest.
Bug: 62058707
Test: bit MultiUserPerfTests:android.multiuser.UserLifecycleTest
Change-Id: I8667190f001f609040a977a19aa956d7064ccc18
2017-06-29 12:08:48 -07:00
Tony Mak
ec7c6963bd Increase the timeout and add stopping managed profile test
The dashbaord suggests that multiple tests are always capped at the same
value due to the timeout. To collect the actual metric, set a larger
timeout value, 10s for now.

Also, added a test to stop managed profile user. However, the test is
still finishing surprisingly fast because of the empty broadcast queue.


Bug: 62096041

Test: adb shell am instrument -e class android.multiuser.UserLifecycleTest -w com.android.perftests.multiuser/android.support.test.runner.AndroidJUnitRunner

Change-Id: Ia52db17525d9eb960c9a8c860cdb52c0f487e5f1
2017-05-31 16:06:02 +01:00
Sudheer Shanka
dc589ac82b Update usage of ActivityManagerNative.
- Remove references to ActivityManagerProxy.
- Add isSystemReady to ActivityManager.

Bug: 30977067
Test: cts/hostsidetests/services/activityandwindowmanager/util/run-test android.server.cts
      adb shell am instrument -e class com.android.server.am.ActivityManagerTest,com.android.server.am.TaskStackChangedListenerTest \
          -w com.android.frameworks.servicestests/android.support.test.runner.AndroidJUnitRunner
Change-Id: I07390b6124fb1515821f5c0b37baf6ae74adc8fa
2016-11-14 11:27:12 -08:00
John Reck
62e5fea855 Greatly reduce BenchmarkState overhead
CL reduces BenchmarkState to minimal levels. It also adds
a warmup loop to get things going first before starting measurements.

With this change with clocks /not/ locked on bullhead the test for
RenderNodeJniOverhead is showing a stable (0ns std dev) result
of 54ns, which is approximately the expected amount.

Test: Ran a few perf benchmarks

Change-Id: If01e455884711ebd9cfb89f076efa19dc0b5436d
2016-10-13 08:41:35 -07:00
Sudheer Shanka
2c4522cc1b Add usermanager related perf tests - part2
- Add onLockedBootComplete callback to UserSwitchObserver.

Bug: 30948225
Test: adb shell am instrument -e class android.multiuser.UserLifecycleTest -w com.android.perftests.multiuser/android.support.test.runner.AndroidJUnitRunner
Change-Id: I87533094805a81fbd85d4f492e637b3304ecd5e2
2016-09-08 13:30:34 -07:00
John Reck
7a9a4eca14 Merge & fix package names
Merge core, graphics, and misc into one
test suite as the split is unneccessary.

Also cleans up package names

Change-Id: I82da6cd69b3a52c63770465780ac98628af334ca
2016-08-26 09:43:03 -07:00
Sudheer Shanka
53c23fdd5c Add usermanager related perf tests - part1
Bug: 30948225
Change-Id: I0668a012435e9954729e5085fdb4b1f5ce422d97
2016-08-19 16:36:23 -07:00