Commit Graph

2965 Commits

Author SHA1 Message Date
Fred Gylys-Colwell
bbb89c2d7f Fix whitespace and copyrights
There were some mistakes in previous merges from pi-dev to master in
whitespace and copyright notices. This fixes them.

Test: tested as part of http://go/ag/4674759
Change-Id: Iae46c121de59233b62925a4d8c97f2b370e3e7f1
2018-09-09 11:37:48 -07:00
Fred Gylys-Colwell
0099f8d08b Remove Remaining OPENSSL_VERSION_NUMBER Conditional Compiles
Some of http://go/wvgerrit/46251 from Widevine repo.
The rest was merged in the oemcrypto refactor.

When we standardized on BoringSSL, these conditional compilations that
had been added as a stopgap for OpenSSL became unneeded. However, they
were not noticed and removed at the time.

Bug: 72459799
Test: CE CDM Unit Tests
Test: tested as part of http://go/ag/4674759

Change-Id: I693f691ffcb255e03660edaa6743cd0fb9ef12c6
2018-09-09 11:37:48 -07:00
Fred Gylys-Colwell
b62a8f1652 Use GetDeviceID to determine SPOID's unique id
Merge from Widevine repo of http://go/wvgerrit/45940

Since the Level 3 OEMCrypto is being updated to Provisioning 3.0, its
SPOID would be derived from its OEM Certificate, breaking backwards
compatibility. This CL changes how we determine what unique id to use
for SPOIDs by checking to see if OEMCrypto_GetDeviceID is implemented,
and if so, using the id returned from that call. If not and the root
of trust is an OEM Cert, we continue to use that OEM Cert.

This allows Level 3 devices to keep the same SPOID when they undergo a
field update to Provisioning 3.0.

Also, the Level 3 OEMCrypto will share a single OEM certificate across
all devices with the same architecture.  Since the OEM Cert is not
unique, it cannot be used to derive a unique id.  By using the unique
id returned by OEMCrypto_GetDeviceID, we can generate a unique SPOID.

The id from OEMCrypto_GetDeviceID has always been required to be
unique for devices with keyboxes.  The functionality and use of this
function for Provisioning 3.0 devices was introduced in OEMCrypto API
version 14.1.

Test: tested as part of http://go/ag/4674759

Change-Id: I65af8246c9312c75c570a2d518caa3de633007c4
2018-09-09 11:37:48 -07:00
Fred Gylys-Colwell
de8d11b8de Remove WrongMessageTest
Merge from Widevine repo of http://go/wvgerrit/48841

This test is not providing value to the CDM, as it seems to exist
primarily to validate server behavior. However, it is not doing what
it says it is (the request is rejected because it is using unparseable
garbage data, not because its key ID is unknown) and according to
tinskip@, the behavior it claims to be testing is not valid. (The
licensing service will not fail just because the key ID is unknown.
Indeed, if the test data is fixed to use a valid payload with an
unknown key ID, the test fails because the server does not.)

Bug: 78640287
Test: CE CDM Unit Tests
Test: Android Unit Tests
Test: tested as part of http://go/ag/4674759

Change-Id: Idfcff15ab3d15fdfb6eb111b5dff68aa5a23fb37
2018-09-09 11:37:48 -07:00
Fred Gylys-Colwell
1299fe883c GTest compiler warnings
Merge from Widevine repo of http://go/wvgerrit/50560

There were some compiler warnings about converting true and false to
integers in EXPECT_EQ which were solved by using EXPECT_TRUE and
EXPECT_FALSE.

Test: tested as part of http://go/ag/4674759
Change-Id: Ie55b53ce48301af64ee2dff04642cbda02c1c41e
2018-09-09 11:37:48 -07:00
Fred Gylys-Colwell
d36ab56575 Sync the definition of WidevinePssh data
Merge from Widevine repo of http://go/wvgerrit/43202

Sync the definition of WidevinePssh data with the latest in support of
entitlement keys.

bug: 73297961 Fix or remove sublicense support.
Test: tested as part of http://go/ag/4674759
Change-Id: Ia9faf82732854a705b4b14430169ce4c8ecbcfcd
2018-09-09 11:37:48 -07:00
Fred Gylys-Colwell
6000f834a0 Entitled Key Management
Merge from Widevine repo of http://go/wvgerrit/53883

Note: this CL does not modify license_key_status.cpp because the
previous CL already included those changes.

OEMCrypto v14 only supports one entitled key per entitlement key at a
time. Unfortunately, some partners have use cases that require using
old entitlement keys after the new keys have been loaded. Most
notably, when a key rotation occurs, the new PSSH will often be loaded
before the playback position catches up to the PSSH in the stream,
meaning that decryption will need to continue using the old keys for a
bit.

To fix this, EntitlementKeySession now caches the entitled keys when
they are loaded and only loads them under their matching entitlement
key when SelectKey() is called. This ensures that the right entitled
key is loaded for a given entitlement key before decryption.

The entitlement key integration tests have been updated to verify that
the old entitled keys still work even after loading new entitled keys.
Also, several places in the code that assumed loading new entitled
keys would wipe out the old keys have had to be modified.

Bug: 78652567
Test: CE CDM Unit Tests
Test: tested as part of http://go/ag/4674759
Change-Id: I6fac9dfe2b170ad68fb7cdb5bc8d6a2f35a20c2c
2018-09-09 11:36:49 -07:00
Fred Gylys-Colwell
d5bb64a60c Strip padding from entitlement keys.
Merge from Widevine repo of http://go/wvgerrit/47540

Bug: 77364593
Test: tested as part of http://go/ag/4674759

Change-Id: If1063d410153eb49584c94156e2d98af9e08c060
2018-09-02 11:45:16 -07:00
Fred Gylys-Colwell
fc4186e4fd Add initial support for key rotation through ce cdm interface.
Merge from Widevine repo of http://go/wvgerrit/42941

Bug: 72168544
Test: tested as part of http://go/ag/4674759
Change-Id: I1a2d0f49371e5b3edf1d9dff85b85593f981d1f5
2018-09-02 11:45:16 -07:00
Fred Gylys-Colwell
d17199fb83 Update comments on copying old usage entries
Merge from Widevine repo of http://go/wvgerrit/49003

CopyOldUsageEntry currently needs the old usage table to be loaded via
CreateOldUsageEntry. The CDM uses a workaround by creating a dummy old
entry, but the OEMCrypto code should be responsible for this. However,
since there have been several versions released with the current
OEMCrypto spec, the CDM code would have to still exist to support
implementations of that spec. Therefore, in order to avoid having to
support both a CDM with this workaround removed (as well as updating
the spec) and a CDM with it still in place, this workaround should be
canonicalized.

b/65730828
Test: tested as part of http://go/ag/4674759
Change-Id: I4619c551b79a53746683519d284663bf513ec38d
2018-09-02 11:45:16 -07:00
Fred Gylys-Colwell
8639842ff5 Clarify that Properties::Init is called multiple times
Merge from Widevine repo of http://go/wvgerrit/53465

It may not be clear that Properties::Init is called multiple
times. This CL adds an explanation in the header file.  The function
itself is platform specific.

Test: tested as part of http://go/ag/4674759

Change-Id: I68010c594ec146e36161ae0f4f44d53caefa1896
2018-09-02 11:45:16 -07:00
Fred Gylys-Colwell
0936f1b875 Improve SSL Error Handling in HttpSocket::Read()
Merge from Widevine repo of http://go/wvgerrit/53640

While HttpSocket supports both secure and insecure requests, the
error-handling code in HttpSocket::Read() was written assuming that
the insecure code path was previously taken. This resulted in spurious
and misleading error messages being printed when an SSL error
occurred, and it also meant that retryable SSL responses were not
being retried. Also, the code for detecting a closed connection was
technically incorrect, although a quirk of BoringSSL meant that it
happened to work well enough to go unnoticed.

This patch adds separate SSL error handling from the non-secure error
handling. It correctly checks for a closed connection. It will retry
retryable errors after a delay. And it prints the correct BoringSSL
error when an unrecoverable error occurs. There should be no change in
behavior for insecure connections.

Bug: 77338045
Test: CE CDM Unit Tests
Test: tested as part of http://go/ag/4674759

Change-Id: I8c45ca5771f22c11716d2e3649de91ab1acc1954
2018-09-02 11:45:16 -07:00
Fred Gylys-Colwell
22d9160219 Revert of "Prevent race conditions between decrypt and close session"
Merge from Widevine repo of http://go/wvgerrit/50481
Original CL http://go/wvgerrit/47520

The original CL was not completely merged to master on Android, so
this CL only reverts the left-over bits.

The original fix was not sufficient to address all race conditions.  A
subsequent CL will address them.

Bug: 73781703
Bug: 79158083
Bug: 79262108
Test: tested as part of http://go/ag/4674759

Change-Id: Ib6c55ab5434e08fe61e0f65623ac8c7b2dc5aaa1
2018-09-02 11:45:16 -07:00
Fred Gylys-Colwell
147f40a5ef Explicitly Pass NULL Character in ProvisioningServiceCertificateInvalidTest
Merge from Widevine repo of http://go/wvgerrit/53625

Passing the third parameter to std::string::insert() as an integer
technically makes for an ambiguous method call, as there are two
overloads that could accept these arguments. While baseline GCC and
Clang discern our intent here correctly, seawardt@ discovered that
XCode is more pedantic and requires that we pass the third parameter
as a char to disambiguate.

Test: WvCdmEnginePreProvTestUat.ProvisioningServiceCertificateInvalidTest
Test: tested as part of http://go/ag/4674759
Change-Id: I65a2506209215cd081c685faac26e08bae486d5e
2018-09-02 11:45:16 -07:00
Fred Gylys-Colwell
1d594f3140 Assorted Key Session Code Cleanup
Merge from Widevine repo of http://go/wvgerrit/53202
and
Merge from Widevine repo of http://go/wvgerrit/53624

This change contains a variety of small tweaks to the
ContentKeySession and EntitlementKeySession classes that were
discovered while fixing b/78652567. There should be no change in
behavior from this patch. The fixes are:

1) Added missing headers and removed unnecessary headers.

2) Removed the unused keys_ member from EntitlementKeySession.

3) Renamed ContentKeySession's protected member function so that it is
not an overload of the public LoadKeys() function. This makes it
clearer what EntitlementKeySession::LoadKeys() is doing.

4) Added missing "virtual" and "OVERRIDE" keywords.

5) Added missing copyright headers.

6) Ran clang-format with Google style.

7) Correct missing OVERRIDE keywords.

Test: tested as part of http://go/ag/4674759

Change-Id: Icb0af886d7d3eb097b5dffbb716be6ac28f0916d
2018-09-02 11:45:16 -07:00
Fred Gylys-Colwell
f573bfc7b0 Address build breaks
Merge from Widevine repo of http://go/wvgerrit/53160

Note: WVDrmPlugin.cpp was already modified in
http://go/ag/3995618

Test: tested as part of http://go/ag/4674759

Change-Id: I12d00b73bec140412615f1f843d20b375ba93fa3
2018-09-02 11:45:16 -07:00
Fred Gylys-Colwell
08c57e7a8e Support Dual PSSHs
Merge from Widevine repo of http://go/wvgerrit/48842

In order to work around a limitation of some versions of OEMCrypto,
the packager is going to start generating files with multiple Widevine
PSSH boxes. For backwards-compatibility, the first PSSH will be a
SINGLE-type PSSH while the ENTITLED_KEYS-type PSSH (if any) will come
later. In order to use entitlement licenses, then, the CDM needs to
change how it selects PSSHs from the init data blob.

Previously, the CDM always took the first Widevine PSSH it found. Now,
it must find all the Widevine PSSHs and select the appropriate PSSH
for the OEMCrypto implementation. ENTITLTED_KEYS will be used on OEC
v14 and later, if available, while SINGLE will be preferred on earlier
OEMCrypto versions.

As a side-effect of this, the CDM is now stricter about what PSSH
payloads it will accept. Previously, it would blindly accept the
payload of any PSSH where the wrapper was not malformed. Now, it
sometimes has to actually parse the payload, and therefore PSSHs that
have corrupted payloads will be rejected. This affected a few unit
tests which used PSSHs that were malformed. These tests have been
updated to use PSSHs that do not fail to parse.

Bug: 78142219
Test: CE CDM Unit Tests
Test: Android Unit Tests
Test: Android Google Play & Netflix
Test: tested as part of http://go/ag/4674759
Change-Id: Ia70d627a914299bfbae84b4cb46f100dc5c7a501
2018-09-02 11:45:16 -07:00
Fred Gylys-Colwell
a242a32bba Implement Method to Release Licenses Without a Server Roundtrip
Merge from Widevine repo of http://go/wvgerrit/52480

Partners have asked for a way to release offline licenses without
using a release message. This is typically used by cable partners who
are caching licenses ahead of time and do not care about usage
statistics.

As part of implementing this request, CdmSession::DeleteLicense() was
renamed to reflect that it only deletes the *files* associated with a
license, and a new CdmSession::DeleteLicense() has been written that
also cleans up other related data.

Bug: 77955334
Test: CE CDM Unit Tests
Test: tested as part of http://go/ag/4674759
Change-Id: I00d6e20935c5fecb3ac9be6757c0f191d85c6bd6
2018-09-02 11:45:16 -07:00
Fred Gylys-Colwell
240652afcf Do Not Unprovision Baked-In DRM Certs
Merge from Widevine repo of http://go/wvgerrit/49820

Devices with baked-in DRM certs cannot be reprovisioned. As such, we
must protect them against being unprovisioned. Currently, our unit
tests break such devices by attempting to unprovision them. This patch
adds code to block the Unprovision() call on these devices.

Bug: 69264798
Test: CE CDM Unit Tests
Test: tested as part of http://go/ag/4674759
Change-Id: I49322dcb2d3d5c7953e870eb91a9e0b978d4dabe
2018-09-02 11:45:16 -07:00
Fred Gylys-Colwell
13a76d1236 Merge Forgotten Cleanup from CE CDM v3.5.0
This CL just updates some comments from the http://go/wvgerrit/51680.  Changes
in that CL made to oemcrypto are in the refactor CL.

Test: tested as part of http://go/ag/4674759

Change-Id: Ia619089e146ea635c5a73a53bc81973bb42b42f7
2018-09-02 11:45:16 -07:00
Fred Gylys-Colwell
299623e148 Use different time call in TimeRollbackPrevention test
Merge from widevine of http://go/wvgerrit/48885

iOS prohibits using clock_settime. In order to make the test consistent,
we set time using settimeofday instead.

Test: tested as part of http://go/ag/4674759

Change-Id: I8812b9b099fa8160591fafece070c34afeed82fa
2018-09-02 11:45:16 -07:00
Fred Gylys-Colwell
947531a6a9 Refactor oemcrypto mock into stand alone reference code
Merge from Widevine repo of http://go/wvgerrit/46204
Refactor utility code - split the mock, step 1

Merge from Widevine repo of http://go/wvgerrit/46205
Move some OEMCrypto types to common header - split the mock, step 2

Merge from Widevine repo of http://go/wvgerrit/46206
Split mock into two -- step 3

Merge from Widevine repo of http://go/wvgerrit/47460
Split the mock into two -- step 3.5

The CL moves several files used by oemcrypto and cdm into a common
subdirectory, so that it may more easily be shared with partners.

The CORE_DISALLOW_COPY_AND_ASSIGN macro was moved to its own header in
the util/include directory.

This CL removes some references to the mock from other code, and puts
some constants and types, such as the definition of the keybox, into a
header in oemcrypto.

Test: tested as part of http://go/ag/4674759
bug: 76393338
Change-Id: I75b4bde7062ed8ee572c97ebc2f4da018f4be0c9
2018-09-02 11:45:16 -07:00
Rahul Frias
b8091eaa7d Merge "Delete usage information on insufficient resources" into pi-dev am: b4b02e7762
am: 4540d4eba3

Change-Id: I617db9b5b8ee69681036456d8e2a7b4711b2d926
2018-08-29 20:45:55 -07:00
Rahul Frias
4540d4eba3 Merge "Delete usage information on insufficient resources" into pi-dev
am: b4b02e7762

Change-Id: I902ddd96e3bfabc4fc17f0f329d31060106452a3
2018-08-29 20:41:55 -07:00
TreeHugger Robot
b4b02e7762 Merge "Delete usage information on insufficient resources" into pi-dev 2018-08-30 03:31:52 +00:00
Fred Gylys-Colwell
15ecbe09bd Refine TwoHundredEntries tests am: a963e90bb8
am: 5b74e3186a

Change-Id: Ifbdc769685d3e6f96222ca180696dc18022d84d1
2018-08-29 18:29:35 -07:00
Fred Gylys-Colwell
5b74e3186a Refine TwoHundredEntries tests
am: a963e90bb8

Change-Id: I38d4ccb9c7e517e72a2b4555557db0de01f01302
2018-08-29 18:10:22 -07:00
Rahul Frias
299b100fc8 Delete usage information on insufficient resources
[ Merge of http://go/wvgerrit/58460 ]

If OEMCrypto runs out of space in the usage table header+entries adding
a new license or loading/using an existing one might fail. This CL makes
two modifications to handle this scenario.

* OEMCrypto_ERROR_INSUFFICIENT_RESOURCES will be returned from
  OEMCrypto_CreateNewUsageEntry or OEMCrypto_LoadUsageEntry. An attempt
  will be made to release a LRU entry from the usage table and retry
  the operation. This may be retried 3 times unless success
  occurs earlier.

* On initialization, the usage table header is loaded. If there are more than
  the minimum number of usage entries (200), an attempt is made to
  add a usage entry. If this fails, we are likely in an unrecoverable
  state. We then delete all offline licenses, usage information and
  recreate the usage table header. This will allow future playback
  attempts to succeed and offline licenses to be able to be downloaded
  but will lose all current offline licenses and secure stops.

Bug: 112486006
Test: WV unit/integration tests, GtsMediaDrmTest
      Playback tests using Netflix and Play movies.

Change-Id: I41a18d69a329f8a96c7b607d299ce73af3d56177
2018-08-29 17:38:43 -07:00
Fred Gylys-Colwell
a963e90bb8 Refine TwoHundredEntries tests
Merge from Widevine repo of http://go/wvgerrit/58440

This CL modifies the oemcrypto test TwoHundredEntries so that it
attempts to create more than 200 entries.  A device is allowed to fail
when such an attempt is made, but it must return an insufficient
resources error.

The test then verifies that each of the entries that were succesfully
created can be used to reload its license and the keys can be used for
decryption.

It then shrinks the usage table header, and verifies that the
remaining licenses can still be used for decryption.

bug: 112486006
test: unit tests (test code only)
Change-Id: I6e6edfb00f0553724e0f99fb4e5ea5c817450937
2018-08-29 14:54:25 -07:00
Rahul Frias
760e938384 Merge "Use new play license service URI" 2018-08-14 17:06:33 +00:00
Haibo Huang
e7703c90e3 [automerger skipped] Remove std::tr1::
am: 3513db8f73  -s ours

Change-Id: Ie7249e936ea64b13ee9ec5322e64cd2be6372a2e
2018-08-10 17:23:49 -07:00
Haibo Huang
3513db8f73 Remove std::tr1::
To be compatible with latest googletest.

Test: compile
Change-Id: I15d857ce7b9b28ba5f75c84c61f1c6a970012ca7
Merged-In: I15d857ce7b9b28ba5f75c84c61f1c6a970012ca7
2018-08-10 21:37:50 +00:00
Rahul Frias
7b7d5edd7c Use new play license service URI
[ Merge of http://go/wvgerrit/54802 ]

BUG: 110954967
BUG: 110960064

Test: WV unit/integration tests.

Change-Id: I3c5263f304ec9c9734a6761cbd7db46ccb476e9e
2018-08-01 13:41:54 -07:00
Haibo Huang
531b6d3d10 Remove std::tr1::
To be compatible with latest googletest.

Test: compile
Change-Id: I15d857ce7b9b28ba5f75c84c61f1c6a970012ca7
2018-07-23 18:24:15 +00:00
John W. Bruce
c28cea3637 Add Missing Parameter to License Keys Unit-Test
(This is a merge of http://go/wvgerrit/55265)

Compiling with GCC 7 revealed that a function call in this test was
missing an argument. It meant to be passing the output protection level
to the function, but because of optional arguments, it was instead
passing it as the fourth argument.

Fixing this revealed that the test cases for the test were incorrect in
one case, which has been fixed to expect the correct results.
Thankfully, this part of the code does not appear to have been broken
while the tests had this hole.

Bug: 111648438
Test: build_and_run_all_unit_tests.sh
Change-Id: I6c13d5fecdccc4185ca5e8698fc845929ff16cb1
2018-07-19 12:49:40 -07:00
Fred Gylys-Colwell
44d2d2653e Delete old provisioning doc
Merge from Widevine repo of http://go/wvgerrit/53980

The provisioning doc changed names, and I accidentally added the new one
without deleting the old one.

I also added a watermark to the newer one.

Change-Id: Ib6e553aa5222c0c59dc03a897229645d37e4189e
2018-06-29 13:59:42 -07:00
Rahul Frias
52a1d1681c Recover when stored information is corrupted am: a20034e3a2
am: 0dc79e547f

Change-Id: I68795d284dfcde4ccd8484bdccf3ddf3a9ee0882
2018-06-06 20:56:39 -07:00
Rahul Frias
0dc79e547f Recover when stored information is corrupted
am: a20034e3a2

Change-Id: I064f71dc63da3771e5ce70f7656eb7a45a9843c1
2018-06-06 14:10:20 -07:00
Rahul Frias
a20034e3a2 Recover when stored information is corrupted
[ Merge of http://go/wvgerrit/52040 ]

Information stored in files are serialized and protected by an MD5 hash.
When files cannot be read because the MD5 hash computed over it
fails verification, the file is deleted. This allows for recovery.

However if the protobuf deserialization fails we return an error
but do not delete the file. When errors of this sort occur
with usage information files, the CDM cannot recover.
removeAllSecureStops() will fail as well and new licenses
with PSTs cannot be processed. In order to recover the file will
be deleted when a protobuf deserialization error occurs.

Bug: 109765590
Test: WV unit, integration tests. GTS tests. Netflix and Play Movies playback
Change-Id: I408914924e644d5c22b2ba7865d3a7d598788ee6
2018-06-06 00:57:31 -07:00
Rahul Frias
9af88e1c59 Address deadlock am: d401baa236
am: 2d7e47508b

Change-Id: Iffe367f44be7049b013ce1fda7394de924dd83ae
2018-05-30 00:06:13 -07:00
Rahul Frias
2d7e47508b Address deadlock
am: d401baa236

Change-Id: Idfa0ee7dc493cc40a0c2500e8377257ce6dcbc80
2018-05-30 00:01:12 -07:00
Rahul Frias
d401baa236 Address deadlock
[ Merge of http://go/wvgerrit/51322 ]

This avoids taking the session_map_lock_ twice.

Bug: 80248149
Test: WV unit/integration tests, GtsMediaTestCases,
      2 days of netflix playback.

Change-Id: Iea1c7b7ba08d7d40c227d21c5abfce13c0a8b395
2018-05-28 12:41:19 -07:00
Fred Gylys-Colwell
a5b89dc5eb Merge "Update Docs for OEMCrypto v14.1" into pi-dev am: 7d90a07c08
am: b94b13107d

Change-Id: I4bb3ba3a6e176d026725e097f3bae0bd234723bc
2018-05-26 11:09:30 -07:00
Fred Gylys-Colwell
b94b13107d Merge "Update Docs for OEMCrypto v14.1" into pi-dev
am: 7d90a07c08

Change-Id: I5010de40e77e0325262d7182340abc744ac2015a
2018-05-26 11:02:51 -07:00
TreeHugger Robot
7d90a07c08 Merge "Update Docs for OEMCrypto v14.1" into pi-dev 2018-05-26 17:54:12 +00:00
Fred Gylys-Colwell
23efd73969 Merge "Update Android Integration Guide" into pi-dev am: d19f86c153
am: 8ac6b598dd

Change-Id: Ic9a7c9e4d9ea8a7fc70042289f73387ba4eb8b9e
2018-05-26 10:13:57 -07:00
Fred Gylys-Colwell
8ac6b598dd Merge "Update Android Integration Guide" into pi-dev
am: d19f86c153

Change-Id: Ica63db685b8564fe0785fed262b5f49e44348223
2018-05-26 10:07:56 -07:00
Fred Gylys-Colwell
d19f86c153 Merge "Update Android Integration Guide" into pi-dev 2018-05-26 16:56:57 +00:00
Fred Gylys-Colwell
36be81af8b Merge "Document Version Compatibility" into pi-dev am: 67c140641e
am: b83fe36a09

Change-Id: I932e569de9006108944526a8888e8d68ba8aa8d6
2018-05-25 05:16:56 -07:00
John W. Bruce
ee74b98530 Make Defensive Copies in CopyBufferInChunks am: b305d99d3b
am: f3b5d0408b

Change-Id: I02471e84c5b9ee4339daccdc3df1a38038f5949e
2018-05-25 05:12:22 -07:00