diff options
Diffstat (limited to 'core/tests')
7 files changed, 150 insertions, 6 deletions
diff --git a/core/tests/bugreports/src/com/android/os/bugreports/tests/BugreportManagerTest.java b/core/tests/bugreports/src/com/android/os/bugreports/tests/BugreportManagerTest.java index f9e3bc60561c..222471a830b1 100644 --- a/core/tests/bugreports/src/com/android/os/bugreports/tests/BugreportManagerTest.java +++ b/core/tests/bugreports/src/com/android/os/bugreports/tests/BugreportManagerTest.java @@ -23,7 +23,10 @@ import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; import android.Manifest; +import android.content.BroadcastReceiver; import android.content.Context; +import android.content.Intent; +import android.content.IntentFilter; import android.os.BugreportManager; import android.os.BugreportManager.BugreportCallback; import android.os.BugreportParams; @@ -31,7 +34,9 @@ import android.os.FileUtils; import android.os.Handler; import android.os.HandlerThread; import android.os.ParcelFileDescriptor; +import android.os.Process; import android.os.StrictMode; +import android.text.TextUtils; import android.util.Log; import androidx.annotation.NonNull; @@ -53,10 +58,11 @@ import org.junit.runner.RunWith; import org.junit.runners.JUnit4; import java.io.File; +import java.io.IOException; +import java.util.concurrent.CountDownLatch; import java.util.concurrent.Executor; import java.util.concurrent.TimeUnit; - /** * Tests for BugreportManager API. */ @@ -67,8 +73,16 @@ public class BugreportManagerTest { private static final String TAG = "BugreportManagerTest"; private static final long BUGREPORT_TIMEOUT_MS = TimeUnit.MINUTES.toMillis(10); + private static final long DUMPSTATE_STARTUP_TIMEOUT_MS = TimeUnit.SECONDS.toMillis(10); private static final long UIAUTOMATOR_TIMEOUT_MS = TimeUnit.SECONDS.toMillis(10); + // Sent by Shell when its bugreport finishes (contains final bugreport/screenshot file name + // associated with the bugreport). + private static final String INTENT_BUGREPORT_FINISHED = + "com.android.internal.intent.action.BUGREPORT_FINISHED"; + private static final String EXTRA_BUGREPORT = "android.intent.extra.BUGREPORT"; + private static final String EXTRA_SCREENSHOT = "android.intent.extra.SCREENSHOT"; + private Handler mHandler; private Executor mExecutor; private BugreportManager mBrm; @@ -212,6 +226,48 @@ public class BugreportManagerTest { } @Test + public void cancelBugreport_noReportStarted() throws Exception { + // Without the native DumpstateService running, we don't get a SecurityException. + mBrm.cancelBugreport(); + } + + @LargeTest + @Test + public void cancelBugreport_fromDifferentUid() throws Exception { + assertThat(Process.myUid()).isNotEqualTo(Process.SHELL_UID); + + // Start a bugreport through ActivityManager's shell command - this starts a BR from the + // shell UID rather than our own. + BugreportBroadcastReceiver br = new BugreportBroadcastReceiver(); + InstrumentationRegistry.getContext() + .registerReceiver(br, new IntentFilter(INTENT_BUGREPORT_FINISHED)); + UiDevice.getInstance(InstrumentationRegistry.getInstrumentation()) + .executeShellCommand("am bug-report"); + + // The command triggers the report through a broadcast, so wait until dumpstate actually + // starts up, which may take a bit. + waitTillDumpstateRunningOrTimeout(); + + try { + mBrm.cancelBugreport(); + fail("Expected cancelBugreport to throw SecurityException when report started by " + + "different UID"); + } catch (SecurityException expected) { + } finally { + // Do this in the finally block so that even if this test case fails, we don't break + // other test cases unexpectedly due to the still-running shell report. + try { + // The shell's BR is still running and should complete successfully. + br.waitForBugreportFinished(); + } finally { + // The latch may fail for a number of reasons but we still need to unregister the + // BroadcastReceiver. + InstrumentationRegistry.getContext().unregisterReceiver(br); + } + } + } + + @Test public void insufficientPermissions_throwsException() throws Exception { dropPermissions(); @@ -346,6 +402,28 @@ public class BugreportManagerTest { .adoptShellPermissionIdentity(Manifest.permission.DUMP); } + private static boolean isDumpstateRunning() { + String[] output; + try { + output = + UiDevice.getInstance(InstrumentationRegistry.getInstrumentation()) + .executeShellCommand("ps -A -o NAME | grep dumpstate") + .trim() + .split("\n"); + } catch (IOException e) { + Log.w(TAG, "Failed to check if dumpstate is running", e); + return false; + } + for (String line : output) { + // Check for an exact match since there may be other things that contain "dumpstate" as + // a substring (e.g. the dumpstate HAL). + if (TextUtils.equals("dumpstate", line)) { + return true; + } + } + return false; + } + private static void assertFdIsClosed(ParcelFileDescriptor pfd) { try { int fd = pfd.getFd(); @@ -364,18 +442,25 @@ public class BugreportManagerTest { return System.currentTimeMillis(); } - private static boolean shouldTimeout(long startTimeMs) { - return now() - startTimeMs >= BUGREPORT_TIMEOUT_MS; + private static void waitTillDumpstateRunningOrTimeout() throws Exception { + long startTimeMs = now(); + while (!isDumpstateRunning()) { + Thread.sleep(500 /* .5s */); + if (now() - startTimeMs >= DUMPSTATE_STARTUP_TIMEOUT_MS) { + break; + } + Log.d(TAG, "Waited " + (now() - startTimeMs) + "ms for dumpstate to start"); + } } private static void waitTillDoneOrTimeout(BugreportCallbackImpl callback) throws Exception { long startTimeMs = now(); while (!callback.isDone()) { Thread.sleep(1000 /* 1s */); - if (shouldTimeout(startTimeMs)) { + if (now() - startTimeMs >= BUGREPORT_TIMEOUT_MS) { break; } - Log.d(TAG, "Waited " + (now() - startTimeMs) + "ms"); + Log.d(TAG, "Waited " + (now() - startTimeMs) + "ms for bugreport to finish"); } } @@ -450,6 +535,36 @@ public class BugreportManagerTest { assertTrue(device.wait(Until.gone(consentTitleObj), UIAUTOMATOR_TIMEOUT_MS)); } + private class BugreportBroadcastReceiver extends BroadcastReceiver { + Intent mBugreportFinishedIntent = null; + final CountDownLatch mLatch; + + BugreportBroadcastReceiver() { + mLatch = new CountDownLatch(1); + } + + @Override + public void onReceive(Context context, Intent intent) { + setBugreportFinishedIntent(intent); + mLatch.countDown(); + } + + private void setBugreportFinishedIntent(Intent intent) { + mBugreportFinishedIntent = intent; + } + + public Intent getBugreportFinishedIntent() { + return mBugreportFinishedIntent; + } + + public void waitForBugreportFinished() throws Exception { + if (!mLatch.await(BUGREPORT_TIMEOUT_MS, TimeUnit.MILLISECONDS)) { + throw new Exception("Failed to receive BUGREPORT_FINISHED in " + + BUGREPORT_TIMEOUT_MS + " ms."); + } + } + } + /** * A rule to change strict mode vm policy temporarily till test method finished. * diff --git a/core/tests/coretests/src/android/content/OWNERS b/core/tests/coretests/src/android/content/OWNERS index 696aa11618ff..912db1e835dc 100644 --- a/core/tests/coretests/src/android/content/OWNERS +++ b/core/tests/coretests/src/android/content/OWNERS @@ -1,4 +1,3 @@ per-file ContextTest.java = file:/services/core/java/com/android/server/wm/OWNERS per-file *Shortcut* = file:/core/java/android/content/pm/SHORTCUT_OWNERS -per-file AppSearchPersonTest.java = file:/core/java/android/content/pm/SHORTCUT_OWNERS per-file *Launcher* = file:/core/java/android/content/pm/LAUNCHER_OWNERS diff --git a/core/tests/coretests/src/android/content/pm/OWNERS b/core/tests/coretests/src/android/content/pm/OWNERS new file mode 100644 index 000000000000..711f5f012b8b --- /dev/null +++ b/core/tests/coretests/src/android/content/pm/OWNERS @@ -0,0 +1,2 @@ +per-file AppSearchPersonTest.java = file:/core/java/android/content/pm/SHORTCUT_OWNERS + diff --git a/core/tests/coretests/src/android/view/autofill/OWNERS b/core/tests/coretests/src/android/view/autofill/OWNERS new file mode 100644 index 000000000000..9a30e826a24f --- /dev/null +++ b/core/tests/coretests/src/android/view/autofill/OWNERS @@ -0,0 +1,3 @@ +# Bug component: 351486 + +include /core/java/android/view/autofill/OWNERS diff --git a/core/tests/coretests/src/android/view/contentcapture/OWNERS b/core/tests/coretests/src/android/view/contentcapture/OWNERS new file mode 100644 index 000000000000..24561c59bba6 --- /dev/null +++ b/core/tests/coretests/src/android/view/contentcapture/OWNERS @@ -0,0 +1,3 @@ +# Bug component: 544200 + +include /core/java/android/view/contentcapture/OWNERS diff --git a/core/tests/coretests/src/android/view/textclassifier/OWNERS b/core/tests/coretests/src/android/view/textclassifier/OWNERS new file mode 100644 index 000000000000..46b3cb8824a0 --- /dev/null +++ b/core/tests/coretests/src/android/view/textclassifier/OWNERS @@ -0,0 +1 @@ +include /core/java/android/service/textclassifier/OWNERS diff --git a/core/tests/utiltests/src/com/android/internal/util/LocationPermissionCheckerTest.java b/core/tests/utiltests/src/com/android/internal/util/LocationPermissionCheckerTest.java index 4c3eaeb1730b..7175f562d7ef 100644 --- a/core/tests/utiltests/src/com/android/internal/util/LocationPermissionCheckerTest.java +++ b/core/tests/utiltests/src/com/android/internal/util/LocationPermissionCheckerTest.java @@ -15,6 +15,8 @@ */ package com.android.internal.util; +import static android.Manifest.permission.NETWORK_SETTINGS; + import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; import static org.mockito.ArgumentMatchers.any; @@ -82,6 +84,7 @@ public class LocationPermissionCheckerTest { private int mAllowCoarseLocationApps; private int mFineLocationPermission; private int mAllowFineLocationApps; + private int mNetworkSettingsPermission; private int mCurrentUser; private boolean mIsLocationEnabled; private boolean mThrowSecurityException; @@ -138,6 +141,7 @@ public class LocationPermissionCheckerTest { mFineLocationPermission = PackageManager.PERMISSION_DENIED; mAllowCoarseLocationApps = AppOpsManager.MODE_ERRORED; mAllowFineLocationApps = AppOpsManager.MODE_ERRORED; + mNetworkSettingsPermission = PackageManager.PERMISSION_DENIED; } private void setupMockInterface() { @@ -151,6 +155,8 @@ public class LocationPermissionCheckerTest { .thenReturn(mCoarseLocationPermission); when(mMockContext.checkPermission(mManifestStringFine, -1, mUid)) .thenReturn(mFineLocationPermission); + when(mMockContext.checkPermission(NETWORK_SETTINGS, -1, mUid)) + .thenReturn(mNetworkSettingsPermission); when(mLocationManager.isLocationEnabledForUser(any())).thenReturn(mIsLocationEnabled); } @@ -264,6 +270,21 @@ public class LocationPermissionCheckerTest { assertEquals(LocationPermissionChecker.ERROR_LOCATION_MODE_OFF, result); } + @Test + public void testenforceCanAccessScanResults_LocationModeDisabledHasNetworkSettings() + throws Exception { + mThrowSecurityException = false; + mIsLocationEnabled = false; + mNetworkSettingsPermission = PackageManager.PERMISSION_GRANTED; + setupTestCase(); + + final int result = + mChecker.checkLocationPermissionWithDetailInfo( + TEST_PKG_NAME, TEST_FEATURE_ID, mUid, null); + assertEquals(LocationPermissionChecker.SUCCEEDED, result); + } + + private static void assertThrows(Class<? extends Exception> exceptionClass, Runnable r) { try { r.run(); |