Snap for 9068117 from 112561d2ef6a0e1c6779f205932f410f147fa54b to mainline-neuralnetworks-release
Change-Id: Ife9b73b85a032cba5d3f8666f324c1ef14069fb2
diff --git a/apps/CtsVerifier/res/values/strings.xml b/apps/CtsVerifier/res/values/strings.xml
index b49337c..631f823 100644
--- a/apps/CtsVerifier/res/values/strings.xml
+++ b/apps/CtsVerifier/res/values/strings.xml
@@ -2138,10 +2138,6 @@
device was p2p device. Check the test case on the other device.</string>
<string name="p2p_connection_error">
Test failed.\n\nFailed to establish a p2p connection.</string>
- <string name="p2p_connection_latency_error">
- Test failed. \n\nConnection was expected to be established within %1$dms. But took=%2$dms.
- \n\nPlease ensure that the Group Owner is ready on the other device before running
- this test</string>
<string name="p2p_detect_disconnection_error">
Test failed.\n\nFailed to detect client disconnection.</string>
<string name="p2p_disconnect_error">
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/p2p/testcase/ConnectReqTestCase.java b/apps/CtsVerifier/src/com/android/cts/verifier/p2p/testcase/ConnectReqTestCase.java
index f0c62c4..20ce5ac 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/p2p/testcase/ConnectReqTestCase.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/p2p/testcase/ConnectReqTestCase.java
@@ -23,9 +23,7 @@
import android.net.wifi.p2p.WifiP2pGroup;
import android.net.wifi.p2p.WifiP2pInfo;
import android.net.wifi.p2p.WifiP2pManager;
-import android.os.Build;
-import com.android.compatibility.common.util.PropertyUtil;
import com.android.cts.verifier.R;
import java.lang.reflect.Method;
@@ -189,11 +187,21 @@
* @throws InterruptedException
*/
protected boolean connectTest(WifiP2pConfig config) throws InterruptedException {
+ notifyTestMsg(R.string.p2p_searching_target);
+
+ /*
+ * Search target device and check its capability.
+ */
ActionListenerTest actionListener = new ActionListenerTest();
+ mP2pMgr.discoverPeers(mChannel, actionListener);
+ if (!actionListener.check(ActionListenerTest.SUCCESS, TIMEOUT)) {
+ mReason = mContext.getString(R.string.p2p_discover_peers_error);
+ return false;
+ }
+
/*
* Try to connect the target device.
*/
- long startTime = System.currentTimeMillis();
mP2pMgr.connect(mChannel, config, actionListener);
if (!actionListener.check(ActionListenerTest.SUCCESS, TIMEOUT)) {
mReason = mContext.getString(R.string.p2p_connect_error);
@@ -216,15 +224,6 @@
WifiP2pGroup group = mReceiverTest.getWifiP2pGroup();
if (group != null) {
if (!group.isGroupOwner()) {
- long endTime = System.currentTimeMillis();
- long connectionLatency = endTime - startTime;
- if (PropertyUtil.isVndkApiLevelAtLeast(Build.VERSION_CODES.TIRAMISU)
- && connectionLatency
- > MAXIMUM_EXPECTED_CONNECTION_LATENCY_WITH_CONFIG_MS) {
- mReason = mContext.getString(R.string.p2p_connection_latency_error,
- MAXIMUM_EXPECTED_CONNECTION_LATENCY_WITH_CONFIG_MS, connectionLatency);
- return false;
- }
setTargetAddress(group.getOwner().deviceAddress);
} else {
mReason = mContext.getString(R.string.p2p_connection_error);
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/p2p/testcase/TestCase.java b/apps/CtsVerifier/src/com/android/cts/verifier/p2p/testcase/TestCase.java
index 2117419..7f608c5 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/p2p/testcase/TestCase.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/p2p/testcase/TestCase.java
@@ -44,7 +44,6 @@
protected static final int TIMEOUT = 25000;
protected static final int TIMEOUT_FOR_USER_ACTION = 60000;
- protected static final int MAXIMUM_EXPECTED_CONNECTION_LATENCY_WITH_CONFIG_MS = 1500;
protected static final int SUCCESS = 0;
protected Context mContext;
diff --git a/common/device-side/util-axt/src/com/android/compatibility/common/util/UiAutomatorUtils.java b/common/device-side/util-axt/src/com/android/compatibility/common/util/UiAutomatorUtils.java
index 3f42e32..a9543c2 100644
--- a/common/device-side/util-axt/src/com/android/compatibility/common/util/UiAutomatorUtils.java
+++ b/common/device-side/util-axt/src/com/android/compatibility/common/util/UiAutomatorUtils.java
@@ -21,6 +21,7 @@
import android.graphics.Rect;
import android.support.test.uiautomator.By;
import android.support.test.uiautomator.BySelector;
+import android.support.test.uiautomator.StaleObjectException;
import android.support.test.uiautomator.UiDevice;
import android.support.test.uiautomator.UiObject2;
import android.support.test.uiautomator.UiObjectNotFoundException;
@@ -28,6 +29,7 @@
import android.support.test.uiautomator.UiSelector;
import android.support.test.uiautomator.Until;
import android.util.TypedValue;
+import android.util.Log;
import androidx.test.InstrumentationRegistry;
import androidx.test.core.app.ApplicationProvider;
@@ -37,6 +39,8 @@
public class UiAutomatorUtils {
private UiAutomatorUtils() {}
+ private static final String LOG_TAG = "UiAutomatorUtils";
+
/** Default swipe deadzone percentage. See {@link UiScrollable}. */
private static final double DEFAULT_SWIPE_DEADZONE_PCT = 0.1;
@@ -86,7 +90,15 @@
final int minViewHeightPx = convertDpToPx(MIN_VIEW_HEIGHT_DP);
while (view == null && start + timeoutMs > System.currentTimeMillis()) {
- view = getUiDevice().wait(Until.findObject(selector), 1000);
+ try {
+ view = getUiDevice().wait(Until.findObject(selector), 1000);
+ } catch (StaleObjectException exception) {
+ // UiDevice.wait() may cause StaleObjectException if the {@link View} attached to
+ // UiObject2 is no longer in the view tree.
+ Log.v(LOG_TAG, "UiObject2 view is no longer in the view tree.", exception);
+ getUiDevice().waitForIdle();
+ continue;
+ }
if (view == null || view.getVisibleBounds().height() < minViewHeightPx) {
final double deadZone = !(FeatureUtil.isWatch() || FeatureUtil.isTV())
diff --git a/tests/PhotoPicker/src/android/photopicker/cts/RemoteVideoPreviewTest.java b/tests/PhotoPicker/src/android/photopicker/cts/RemoteVideoPreviewTest.java
index b6eb8f3..db60d7d 100644
--- a/tests/PhotoPicker/src/android/photopicker/cts/RemoteVideoPreviewTest.java
+++ b/tests/PhotoPicker/src/android/photopicker/cts/RemoteVideoPreviewTest.java
@@ -21,12 +21,18 @@
import static android.photopicker.cts.PickerProviderMediaGenerator.syncCloudProvider;
import static android.photopicker.cts.util.PhotoPickerFilesUtils.deleteMedia;
import static android.photopicker.cts.util.PhotoPickerUiUtils.REGEX_PACKAGE_NAME;
+import static android.photopicker.cts.util.PhotoPickerUiUtils.SHORT_TIMEOUT;
+import static android.photopicker.cts.util.PhotoPickerUiUtils.clickAndWait;
import static android.photopicker.cts.util.PhotoPickerUiUtils.findAddButton;
import static android.photopicker.cts.util.PhotoPickerUiUtils.findItemList;
import static android.photopicker.cts.util.PhotoPickerUiUtils.findPreviewAddButton;
+import static android.provider.CloudMediaProvider.CloudMediaSurfaceStateChangedCallback.PLAYBACK_STATE_BUFFERING;
+import static android.provider.CloudMediaProvider.CloudMediaSurfaceStateChangedCallback.PLAYBACK_STATE_ERROR_PERMANENT_FAILURE;
+import static android.provider.CloudMediaProvider.CloudMediaSurfaceStateChangedCallback.PLAYBACK_STATE_ERROR_RETRIABLE_FAILURE;
import static android.provider.CloudMediaProvider.CloudMediaSurfaceStateChangedCallback.PLAYBACK_STATE_READY;
import static com.google.common.truth.Truth.assertThat;
+import static com.google.common.truth.Truth.assertWithMessage;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyInt;
@@ -219,6 +225,41 @@
// test the remote preview APIs
}
+ @Test
+ public void testVideoPreviewProgressIndicator() throws Exception {
+ initCloudProviderWithVideo(Arrays.asList(Pair.create(null, CLOUD_ID1)));
+ launchPreviewMultiple(/* count */ 1);
+
+ // Remote Preview displays circular progress indicator when playback state is
+ // PLAYBACK_STATE_BUFFERING.
+ verifyProgressIndicatorShowsWhenBuffering(/* surfaceId */ 0);
+ }
+
+ @Test
+ public void testVideoPreviewPermanentError() throws Exception {
+ initCloudProviderWithVideo(Arrays.asList(Pair.create(null, CLOUD_ID1)));
+ launchPreviewMultiple(/* count */ 1);
+
+ // Remote Preview displays Snackbar to notify the user of an error when playback state is
+ // PLAYBACK_STATE_ERROR_PERMANENT_FAILURE.
+ verifySnackbarShowsWhenPermanentError(/* surfaceId */ 0);
+ }
+
+ @Test
+ public void testVideoPreviewRetriableError() throws Exception {
+ initCloudProviderWithVideo(Arrays.asList(Pair.create(null, CLOUD_ID1)));
+ final int surfaceId = 0;
+ launchPreviewMultiple(/* count */ 1);
+
+ // Remote Preview displays an AlertDialog to notify the user of an error when playback state
+ // is PLAYBACK_STATE_ERROR_RETRIABLE_FAILURE.
+ verifyAlertDialogShowsWhenRetriableError(surfaceId);
+
+ // Remote Preview calls onMediaPlay when user clicks the retry button in the retriable error
+ // AlertDialog.
+ verifyAlertDialogRetry(surfaceId);
+ }
+
/**
* Verify surface controller interactions on swiping from one video to another.
* Note: This test assumes that the first video is in playing state.
@@ -269,6 +310,54 @@
mAssertInOrder.verify(mSurfaceControllerListener).onMediaPlay(eq(surfaceId));
}
+ private void verifyProgressIndicatorShowsWhenBuffering(int surfaceId) throws Exception {
+ CloudProviderPrimary.setPlaybackState(surfaceId, PLAYBACK_STATE_BUFFERING);
+ // Wait for photo picker to receive the event and invoke media play via binder calls.
+ MediaStore.waitForIdle(mContext.getContentResolver());
+ assertWithMessage("Expected circular progress indicator to be visible when state is "
+ + "buffering").that(findPreviewProgressIndicator().waitForExists(SHORT_TIMEOUT))
+ .isTrue();
+ }
+
+ private void verifySnackbarShowsWhenPermanentError(int surfaceId) throws Exception {
+ CloudProviderPrimary.setPlaybackState(surfaceId, PLAYBACK_STATE_ERROR_PERMANENT_FAILURE);
+ // Wait for photo picker to receive the event and invoke media play via binder calls.
+ MediaStore.waitForIdle(mContext.getContentResolver());
+ assertWithMessage("Expected snackbar to be visible when state is permanent error")
+ .that(findPreviewErrorSnackbar().waitForExists(SHORT_TIMEOUT)).isTrue();
+ }
+
+ private void verifyAlertDialogShowsWhenRetriableError(int surfaceId) throws Exception {
+ CloudProviderPrimary.setPlaybackState(surfaceId, PLAYBACK_STATE_ERROR_RETRIABLE_FAILURE);
+ // Wait for photo picker to receive the event and invoke media play via binder calls.
+ MediaStore.waitForIdle(mContext.getContentResolver());
+
+ assertWithMessage("Expected alert dialog with title to be visible when state is retriable "
+ + "error").that(findPreviewErrorAlertDialogTitle().waitForExists(SHORT_TIMEOUT))
+ .isTrue();
+ assertWithMessage("Expected alert dialog with text body to be visible when state is "
+ + "retriable error").that(findPreviewErrorAlertDialogBody().exists()).isTrue();
+ assertWithMessage("Expected alert dialog with retry button to be visible when state is "
+ + "retriable error").that(findPreviewErrorAlertDialogRetryButton().exists())
+ .isTrue();
+ assertWithMessage("Expected alert dialog with cancel button to be visible when state is "
+ + "retriable error").that(findPreviewErrorAlertDialogCancelButton().exists())
+ .isTrue();
+ }
+
+ private void verifyAlertDialogRetry(int surfaceId) throws Exception {
+ CloudProviderPrimary.setPlaybackState(surfaceId, PLAYBACK_STATE_ERROR_RETRIABLE_FAILURE);
+ // Wait for photo picker to receive the event and invoke media play via binder calls.
+ MediaStore.waitForIdle(mContext.getContentResolver());
+
+ assertWithMessage("Expected alert dialog with retry button to be visible when state is "
+ + "retriable error")
+ .that(findPreviewErrorAlertDialogRetryButton().waitForExists(SHORT_TIMEOUT))
+ .isTrue();
+ clickAndWait(mDevice, findPreviewErrorAlertDialogRetryButton());
+ mAssertInOrder.verify(mSurfaceControllerListener).onMediaPlay(eq(surfaceId));
+ }
+
private void initCloudProviderWithImage(List<Pair<String, String>> mediaPairs)
throws Exception {
for (Pair<String, String> pair : mediaPairs) {
@@ -348,4 +437,29 @@
// Wait for CloudMediaProvider binder calls to finish.
MediaStore.waitForIdle(mContext.getContentResolver());
}
+
+ private static UiObject findPreviewProgressIndicator() {
+ return new UiObject(new UiSelector().resourceIdMatches(
+ REGEX_PACKAGE_NAME + ":id/preview_progress_indicator"));
+ }
+
+ private static UiObject findPreviewErrorAlertDialogTitle() {
+ return new UiObject(new UiSelector().text("Trouble playing video"));
+ }
+
+ private static UiObject findPreviewErrorAlertDialogBody() {
+ return new UiObject(new UiSelector().text("Check your internet connection and try again"));
+ }
+
+ private static UiObject findPreviewErrorAlertDialogRetryButton() {
+ return new UiObject(new UiSelector().textMatches("R(etry|ETRY)"));
+ }
+
+ private static UiObject findPreviewErrorAlertDialogCancelButton() {
+ return new UiObject(new UiSelector().textMatches("C(ancel|ANCEL)"));
+ }
+
+ private static UiObject findPreviewErrorSnackbar() {
+ return new UiObject(new UiSelector().text("Can't play video"));
+ }
}
diff --git a/tests/tests/security/AndroidManifest.xml b/tests/tests/security/AndroidManifest.xml
index 4ddeca0..2c5e248 100644
--- a/tests/tests/security/AndroidManifest.xml
+++ b/tests/tests/security/AndroidManifest.xml
@@ -201,9 +201,34 @@
</intent-filter>
</activity>
+ <receiver android:name="android.security.cts.CVE_2022_20420.PocDeviceAdminReceiver"
+ android:exported="true"
+ android:permission="android.permission.BIND_DEVICE_ADMIN">
+ <meta-data android:name="android.app.device_admin"
+ android:resource="@xml/device_admin_CVE_2022_20420" />
+ <intent-filter>
+ <action android:name="android.app.action.DEVICE_ADMIN_ENABLED" />
+ </intent-filter>
+ </receiver>
+
<activity android:name="android.security.cts.ActivityManagerTest$ActivityOptionsActivity" />
<activity android:name="android.security.cts.ActivityManagerTest$BaseActivity" />
+ <provider android:name="android.security.cts.CVE_2022_20358.PocContentProvider"
+ android:authorities="android.security.cts.CVE_2022_20358.provider"
+ android:enabled="true"
+ android:exported="true" />
+
+ <service android:name="android.security.cts.CVE_2022_20358.PocSyncService"
+ android:enabled="true"
+ android:exported="true">
+ <intent-filter>
+ <action android:name="android.content.SyncAdapter" />
+ </intent-filter>
+ <meta-data android:name="android.content.SyncAdapter"
+ android:resource="@xml/syncadapter" />
+ </service>
+
</application>
<instrumentation android:name="androidx.test.runner.AndroidJUnitRunner"
diff --git a/tests/tests/security/res/raw/cve_2022_22084.qcp b/tests/tests/security/res/raw/cve_2022_22084.qcp
new file mode 100644
index 0000000..c41d21e
--- /dev/null
+++ b/tests/tests/security/res/raw/cve_2022_22084.qcp
Binary files differ
diff --git a/tests/tests/security/res/raw/cve_2022_22085.dts b/tests/tests/security/res/raw/cve_2022_22085.dts
new file mode 100644
index 0000000..3a88631
--- /dev/null
+++ b/tests/tests/security/res/raw/cve_2022_22085.dts
Binary files differ
diff --git a/tests/tests/security/res/raw/cve_2022_22086.3gp b/tests/tests/security/res/raw/cve_2022_22086.3gp
new file mode 100644
index 0000000..715d10c
--- /dev/null
+++ b/tests/tests/security/res/raw/cve_2022_22086.3gp
Binary files differ
diff --git a/tests/tests/security/res/raw/cve_2022_25659.mkv b/tests/tests/security/res/raw/cve_2022_25659.mkv
new file mode 100644
index 0000000..9eda647
--- /dev/null
+++ b/tests/tests/security/res/raw/cve_2022_25659.mkv
Binary files differ
diff --git a/tests/tests/security/res/xml/device_admin_CVE_2022_20420.xml b/tests/tests/security/res/xml/device_admin_CVE_2022_20420.xml
new file mode 100644
index 0000000..cb567e3
--- /dev/null
+++ b/tests/tests/security/res/xml/device_admin_CVE_2022_20420.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright 2022 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+<device-admin>
+ <uses-policies>
+ </uses-policies>
+</device-admin>
diff --git a/tests/tests/security/res/xml/syncadapter.xml b/tests/tests/security/res/xml/syncadapter.xml
new file mode 100644
index 0000000..478fad5
--- /dev/null
+++ b/tests/tests/security/res/xml/syncadapter.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright 2022 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+<sync-adapter xmlns:android="http://schemas.android.com/apk/res/android"
+ android:accountType="CVE_2022_20358_acc"
+ android:isAlwaysSyncable="true" />
diff --git a/tests/tests/security/src/android/security/cts/CVE_2022_20358/CVE_2022_20358.java b/tests/tests/security/src/android/security/cts/CVE_2022_20358/CVE_2022_20358.java
new file mode 100644
index 0000000..b1ff168
--- /dev/null
+++ b/tests/tests/security/src/android/security/cts/CVE_2022_20358/CVE_2022_20358.java
@@ -0,0 +1,120 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.security.cts.CVE_2022_20358;
+
+import static org.junit.Assert.fail;
+import static org.junit.Assume.assumeNoException;
+import static org.junit.Assume.assumeTrue;
+
+import android.accounts.Account;
+import android.app.Instrumentation;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.ISyncAdapter;
+import android.content.Intent;
+import android.content.ServiceConnection;
+import android.os.Bundle;
+import android.os.IBinder;
+import android.os.RemoteCallback;
+import android.platform.test.annotations.AsbSecurityTest;
+
+import androidx.test.InstrumentationRegistry;
+import androidx.test.runner.AndroidJUnit4;
+
+import com.android.sts.common.util.StsExtraBusinessLogicTestCase;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.util.concurrent.CompletableFuture;
+import java.util.concurrent.Semaphore;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.TimeoutException;
+
+@RunWith(AndroidJUnit4.class)
+public class CVE_2022_20358 extends StsExtraBusinessLogicTestCase implements ServiceConnection {
+ static final int TIMEOUT_SEC = 10;
+ Semaphore mWaitResultServiceConn;
+ boolean mIsAssumeFail = false;
+ String mAssumeFailMsg = "";
+
+ @AsbSecurityTest(cveBugId = 203229608)
+ @Test
+ public void testPocCVE_2022_20358() {
+ try {
+ // Bind to the PocSyncService
+ Instrumentation instrumentation = InstrumentationRegistry.getInstrumentation();
+ Context context = instrumentation.getContext();
+ Intent intent = new Intent(context, PocSyncService.class);
+ intent.setAction("android.content.SyncAdapter");
+ CompletableFuture<String> callbackReturn = new CompletableFuture<>();
+ RemoteCallback cb = new RemoteCallback((Bundle result) -> {
+ callbackReturn.complete(result.getString("fail"));
+ });
+ intent.putExtra("callback", cb);
+ context.bindService(intent, this, Context.BIND_AUTO_CREATE);
+
+ // Wait for some result from the PocSyncService
+ mWaitResultServiceConn = new Semaphore(0);
+ assumeTrue(mWaitResultServiceConn.tryAcquire(TIMEOUT_SEC, TimeUnit.SECONDS));
+ assumeTrue(mAssumeFailMsg, !mIsAssumeFail);
+
+ // Wait for a result to be set from onPerformSync() of PocSyncAdapter
+ callbackReturn.get(TIMEOUT_SEC, TimeUnit.SECONDS);
+
+ // In presence of vulnerability, the above call succeeds and TimeoutException is not
+ // triggered so failing the test
+ fail("Vulnerable to b/203229608!!");
+ } catch (Exception e) {
+ if (e instanceof TimeoutException) {
+ // The fix is present so returning from here
+ return;
+ }
+ assumeNoException(e);
+ }
+ }
+
+ @Override
+ public void onServiceConnected(ComponentName name, IBinder service) {
+ try {
+ if (mWaitResultServiceConn == null) {
+ mWaitResultServiceConn = new Semaphore(0);
+ }
+ ISyncAdapter adapter = ISyncAdapter.Stub.asInterface(service);
+ Account account = new Account("CVE_2022_20358_user", "CVE_2022_20358_acc");
+ adapter.startSync(null, "android.security.cts.CVE_2022_20358.provider", account, null);
+ mWaitResultServiceConn.release();
+ } catch (Exception e) {
+ try {
+ mWaitResultServiceConn.release();
+ mAssumeFailMsg = e.getMessage();
+ mIsAssumeFail = true;
+ } catch (Exception ex) {
+ // ignore all exceptions
+ }
+ }
+ }
+
+ @Override
+ public void onServiceDisconnected(ComponentName name) {
+ try {
+ mWaitResultServiceConn.release();
+ } catch (Exception e) {
+ // ignore all exceptions
+ }
+ }
+}
diff --git a/tests/tests/security/src/android/security/cts/CVE_2022_20358/PocContentProvider.java b/tests/tests/security/src/android/security/cts/CVE_2022_20358/PocContentProvider.java
new file mode 100644
index 0000000..0bc8c2c
--- /dev/null
+++ b/tests/tests/security/src/android/security/cts/CVE_2022_20358/PocContentProvider.java
@@ -0,0 +1,56 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.security.cts.CVE_2022_20358;
+
+import android.content.ContentProvider;
+import android.content.ContentValues;
+import android.database.Cursor;
+import android.net.Uri;
+
+public class PocContentProvider extends ContentProvider {
+
+ @Override
+ public int delete(Uri uri, String selection, String[] selectionArgs) {
+ return 0;
+ }
+
+ @Override
+ public String getType(Uri uri) {
+ return null;
+ }
+
+ @Override
+ public Uri insert(Uri uri, ContentValues values) {
+ return null;
+ }
+
+ @Override
+ public boolean onCreate() {
+ return true;
+ }
+
+ @Override
+ public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs,
+ String sortOrder) {
+ return null;
+ }
+
+ @Override
+ public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) {
+ return 0;
+ }
+}
diff --git a/tests/tests/security/src/android/security/cts/CVE_2022_20358/PocSyncService.java b/tests/tests/security/src/android/security/cts/CVE_2022_20358/PocSyncService.java
new file mode 100644
index 0000000..08fbf92
--- /dev/null
+++ b/tests/tests/security/src/android/security/cts/CVE_2022_20358/PocSyncService.java
@@ -0,0 +1,79 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.security.cts.CVE_2022_20358;
+
+import android.accounts.Account;
+import android.app.Service;
+import android.content.AbstractThreadedSyncAdapter;
+import android.content.ContentProviderClient;
+import android.content.Context;
+import android.content.Intent;
+import android.content.SyncResult;
+import android.os.Bundle;
+import android.os.IBinder;
+import android.os.RemoteCallback;
+
+public class PocSyncService extends Service {
+ private static PocSyncAdapter sSyncAdapter = null;
+ private static final Object sSyncAdapterLock = new Object();
+ RemoteCallback mCb;
+
+ @Override
+ public void onCreate() {
+ try {
+ synchronized (sSyncAdapterLock) {
+ if (sSyncAdapter == null) {
+ sSyncAdapter = new PocSyncAdapter(this);
+ }
+ }
+ } catch (Exception e) {
+ // ignore all exceptions
+ }
+ }
+
+ @Override
+ public IBinder onBind(Intent intent) {
+ try {
+ mCb = (RemoteCallback) intent.getExtra("callback");
+ } catch (Exception e) {
+ // ignore all exceptions
+ }
+ return sSyncAdapter.getSyncAdapterBinder();
+ }
+
+ public class PocSyncAdapter extends AbstractThreadedSyncAdapter {
+
+ public PocSyncAdapter(Context context) {
+ super(context, false);
+ }
+
+ @Override
+ public void onPerformSync(Account account, Bundle extras, String authority,
+ ContentProviderClient provider, SyncResult syncResult) {
+ try {
+ if (account.type.equals("CVE_2022_20358_acc")
+ && account.name.equals("CVE_2022_20358_user")) {
+ Bundle res = new Bundle();
+ res.putString("fail", "");
+ mCb.sendResult(res);
+ }
+ } catch (Exception e) {
+ // ignore all exceptions
+ }
+ }
+ }
+}
diff --git a/tests/tests/security/src/android/security/cts/CVE_2022_20420/CVE_2022_20420.java b/tests/tests/security/src/android/security/cts/CVE_2022_20420/CVE_2022_20420.java
new file mode 100644
index 0000000..1bf6a78
--- /dev/null
+++ b/tests/tests/security/src/android/security/cts/CVE_2022_20420/CVE_2022_20420.java
@@ -0,0 +1,112 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.security.cts.CVE_2022_20420;
+
+import static androidx.test.platform.app.InstrumentationRegistry.getInstrumentation;
+
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assume.assumeNoException;
+import static org.junit.Assume.assumeTrue;
+
+import android.app.ActivityManager;
+import android.app.UiAutomation;
+import android.app.admin.DevicePolicyManager;
+import android.content.BroadcastReceiver;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.os.IDeviceIdleController;
+import android.os.PowerExemptionManager;
+import android.os.Process;
+import android.os.ServiceManager;
+import android.platform.test.annotations.AsbSecurityTest;
+
+import androidx.test.runner.AndroidJUnit4;
+
+import com.android.sts.common.util.StsExtraBusinessLogicTestCase;
+
+import org.junit.After;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.util.concurrent.CompletableFuture;
+import java.util.concurrent.TimeUnit;
+
+@RunWith(AndroidJUnit4.class)
+public class CVE_2022_20420 extends StsExtraBusinessLogicTestCase {
+ private static final int TIMEOUT_MS = 10000;
+ private static final int USER_ID = 0;
+ private Context mContext;
+ private DevicePolicyManager mPolicyManager;
+ private ComponentName mComponentName;
+ private UiAutomation mAutomation;
+
+ @After
+ public void tearDown() {
+ try {
+ mAutomation.dropShellPermissionIdentity();
+ mPolicyManager.removeActiveAdmin(mComponentName);
+ } catch (Exception ignored) {
+ // ignore all exceptions as the test has been completed.
+ }
+ }
+
+ @AsbSecurityTest(cveBugId = 238477311)
+ @Test
+ public void testDeviceAdminAppRestricted() {
+ try {
+ // Add test app to Power Save Whitelist.
+ mContext = getInstrumentation().getTargetContext();
+ mAutomation = getInstrumentation().getUiAutomation();
+ mAutomation.adoptShellPermissionIdentity(android.Manifest.permission.DEVICE_POWER,
+ android.Manifest.permission.MANAGE_DEVICE_ADMINS,
+ android.Manifest.permission.INTERACT_ACROSS_USERS_FULL);
+ IDeviceIdleController mDeviceIdleService =
+ IDeviceIdleController.Stub.asInterface(ServiceManager.getService("deviceidle"));
+ mDeviceIdleService.addPowerSaveWhitelistApp(mContext.getPackageName());
+
+ // Set test app as "Active Admin".
+ mPolicyManager = mContext.getSystemService(DevicePolicyManager.class);
+ mComponentName = new ComponentName(mContext, PocDeviceAdminReceiver.class);
+ mPolicyManager.setActiveAdmin(mComponentName, true, USER_ID);
+ CompletableFuture<Boolean> future = new CompletableFuture<>();
+ BroadcastReceiver broadcastReceiver = new BroadcastReceiver() {
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ future.complete(true);
+ }
+ };
+ mContext.registerReceiver(broadcastReceiver,
+ new IntentFilter("broadcastCVE_2022_20420"));
+ future.get(TIMEOUT_MS, TimeUnit.MILLISECONDS);
+
+ // Call vulnerable function getBackgroundRestrictionExemptionReason()
+ ActivityManager activityManager = mContext.getSystemService(ActivityManager.class);
+ int reason = activityManager.getBackgroundRestrictionExemptionReason(Process.myUid());
+ assumeTrue(
+ "Reason code other than REASON_ACTIVE_DEVICE_ADMIN/REASON_ALLOWLISTED_PACKAGE"
+ + " returned by getBackgroundRestrictionExemptionReason() = " + reason,
+ reason == PowerExemptionManager.REASON_ACTIVE_DEVICE_ADMIN
+ || reason == PowerExemptionManager.REASON_ALLOWLISTED_PACKAGE);
+ assertFalse("Vulnerable to b/238377411 !!",
+ reason == PowerExemptionManager.REASON_ALLOWLISTED_PACKAGE);
+ } catch (Exception e) {
+ assumeNoException(e);
+ }
+ }
+}
diff --git a/tests/tests/security/src/android/security/cts/CVE_2022_20420/PocDeviceAdminReceiver.java b/tests/tests/security/src/android/security/cts/CVE_2022_20420/PocDeviceAdminReceiver.java
new file mode 100644
index 0000000..c9c1b6f
--- /dev/null
+++ b/tests/tests/security/src/android/security/cts/CVE_2022_20420/PocDeviceAdminReceiver.java
@@ -0,0 +1,33 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.security.cts.CVE_2022_20420;
+
+import android.app.admin.DeviceAdminReceiver;
+import android.content.Context;
+import android.content.Intent;
+
+public class PocDeviceAdminReceiver extends DeviceAdminReceiver {
+
+ @Override
+ public void onEnabled(Context context, Intent intent) {
+ try {
+ context.sendBroadcast(new Intent("broadcastCVE_2022_20420"));
+ } catch (Exception e) {
+ // ignore all exceptions.
+ }
+ }
+}
diff --git a/tests/tests/security/src/android/security/cts/CVE_2022_20452/CVE_2022_20452.java b/tests/tests/security/src/android/security/cts/CVE_2022_20452/CVE_2022_20452.java
new file mode 100644
index 0000000..af581a1
--- /dev/null
+++ b/tests/tests/security/src/android/security/cts/CVE_2022_20452/CVE_2022_20452.java
@@ -0,0 +1,71 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+// This PoC has been written taking reference from:
+// File: frameworks/base/core/tests/coretests/src/android/os/BundleTest.java
+// Function: readFromParcelWithRwHelper_whenThrowingAndDefusing_returnsNull()
+
+package android.security.cts.CVE_2022_20452;
+
+import static org.junit.Assert.assertNull;
+import static org.junit.Assume.assumeNoException;
+
+import android.os.Bundle;
+import android.os.Parcel;
+import android.os.Parcelable;
+import android.platform.test.annotations.AsbSecurityTest;
+
+import androidx.test.runner.AndroidJUnit4;
+
+import com.android.sts.common.util.StsExtraBusinessLogicTestCase;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@RunWith(AndroidJUnit4.class)
+public class CVE_2022_20452 extends StsExtraBusinessLogicTestCase {
+
+ @AsbSecurityTest(cveBugId = 240138318)
+ @Test
+ public void testPocCVE_2022_20452() {
+ try {
+ // Create a bundle with some parcelable object and a random string
+ Bundle bundle = new Bundle();
+ Parcelable parcelable = new CustomParcelable();
+ bundle.putParcelable("keyParcelable", parcelable);
+ bundle.putString("keyStr", "valStr");
+
+ // Read bundle contents into a parcel and also set read write helper for the parcel
+ Parcel parcelledBundle = Parcel.obtain();
+ bundle.writeToParcel(parcelledBundle, 0);
+ parcelledBundle.setDataPosition(0);
+ parcelledBundle.setReadWriteHelper(new Parcel.ReadWriteHelper());
+
+ // First set 'shouldDefuse' to true, then read contents of parcel into a bundle.
+ // In presence of fix, this will cause a ClassNotFoundException because bundle will not
+ // be able to find the class for 'CustomParcelable' as the class loader is not set, so
+ // Parcel will not be read properly and the code will return without reading the string.
+ Bundle.setShouldDefuse(true);
+ Bundle testBundle = new Bundle();
+ testBundle.readFromParcel(parcelledBundle);
+
+ // If the vulnerability is active, we will be able to read string from bundle.
+ assertNull("Vulnerable to b/240138318 !!", testBundle.getString("keyStr"));
+ } catch (Exception e) {
+ assumeNoException(e);
+ }
+ }
+}
diff --git a/tests/tests/security/src/android/security/cts/CVE_2022_20452/CustomParcelable.java b/tests/tests/security/src/android/security/cts/CVE_2022_20452/CustomParcelable.java
new file mode 100644
index 0000000..f076eee
--- /dev/null
+++ b/tests/tests/security/src/android/security/cts/CVE_2022_20452/CustomParcelable.java
@@ -0,0 +1,50 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.security.cts.CVE_2022_20452;
+
+import android.os.Parcel;
+import android.os.Parcelable;
+
+public class CustomParcelable implements Parcelable {
+ private boolean mDummyValue = true;
+
+ CustomParcelable() {
+ }
+
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+ @Override
+ public void writeToParcel(Parcel out, int flags) {
+ out.writeBoolean(mDummyValue);
+ }
+
+ public static final Creator<CustomParcelable> CREATOR =
+ new Creator<CustomParcelable>() {
+ @Override
+ public CustomParcelable createFromParcel(Parcel in) {
+ return new CustomParcelable();
+ }
+
+ @Override
+ public CustomParcelable[] newArray(int size) {
+ return new CustomParcelable[size];
+ }
+ };
+}
diff --git a/tests/tests/security/src/android/security/cts/StagefrightTest.java b/tests/tests/security/src/android/security/cts/StagefrightTest.java
index 7706081..307a3e7 100644
--- a/tests/tests/security/src/android/security/cts/StagefrightTest.java
+++ b/tests/tests/security/src/android/security/cts/StagefrightTest.java
@@ -1809,6 +1809,30 @@
before any existing test methods
***********************************************************/
@Test
+ @AsbSecurityTest(cveBugId = 223209306)
+ public void testStagefright_cve_2022_22085() throws Exception {
+ doStagefrightTest(R.raw.cve_2022_22085);
+ }
+
+ @Test
+ @AsbSecurityTest(cveBugId = 223209816)
+ public void testStagefright_cve_2022_22084() throws Exception {
+ doStagefrightTest(R.raw.cve_2022_22084);
+ }
+
+ @Test
+ @AsbSecurityTest(cveBugId = 223211218)
+ public void testStagefright_cve_2022_22086() throws Exception {
+ doStagefrightTest(R.raw.cve_2022_22086);
+ }
+
+ @Test
+ @AsbSecurityTest(cveBugId = 228101819)
+ public void testStagefright_cve_2022_25659() throws Exception {
+ doStagefrightTest(R.raw.cve_2022_25659);
+ }
+
+ @Test
@AsbSecurityTest(cveBugId = 223210917)
public void testStagefright_cve_2022_22083() throws Exception {
doStagefrightTest(R.raw.cve_2022_22083);
diff --git a/tests/tests/wifi/src/android/net/wifi/cts/ConcurrencyTest.java b/tests/tests/wifi/src/android/net/wifi/cts/ConcurrencyTest.java
index fad09f4..c0e5624 100644
--- a/tests/tests/wifi/src/android/net/wifi/cts/ConcurrencyTest.java
+++ b/tests/tests/wifi/src/android/net/wifi/cts/ConcurrencyTest.java
@@ -291,10 +291,8 @@
|| state == NetworkInfo.DetailedState.DISCONNECTED) {
state = waitForNextNetworkState();
}
- if (ApiLevelUtil.isAtLeast(Build.VERSION_CODES.TIRAMISU)) {
- if (state != NetworkInfo.DetailedState.CONNECTING) {
- return false;
- }
+ if (ApiLevelUtil.isAtLeast(Build.VERSION_CODES.TIRAMISU)
+ && state == NetworkInfo.DetailedState.CONNECTING) {
state = waitForNextNetworkState();
}
return state == NetworkInfo.DetailedState.CONNECTED;
diff --git a/tests/tests/wifi/src/android/net/wifi/rtt/cts/WifiRttTest.java b/tests/tests/wifi/src/android/net/wifi/rtt/cts/WifiRttTest.java
index 6205ee8..41cc640 100644
--- a/tests/tests/wifi/src/android/net/wifi/rtt/cts/WifiRttTest.java
+++ b/tests/tests/wifi/src/android/net/wifi/rtt/cts/WifiRttTest.java
@@ -562,7 +562,7 @@
*/
@Test
public void testAwareRttWithPeerHandle() throws InterruptedException {
- if (WifiFeature.isAwareSupported(getContext())) {
+ if (!WifiFeature.isAwareSupported(getContext())) {
return;
}
PeerHandle peerHandle = mock(PeerHandle.class);