Merge "Adding more incidentd privacy filtering tests." into pi-dev
diff --git a/hostsidetests/appsecurity/res/pkgsigverify/v3-rsa-pkcs1-sha256-2048-2-with-por_1_2-full-and-roll-caps.apk b/hostsidetests/appsecurity/res/pkgsigverify/v3-rsa-pkcs1-sha256-2048-2-with-por_1_2-full-and-roll-caps.apk
new file mode 100644
index 0000000..8c8f140
--- /dev/null
+++ b/hostsidetests/appsecurity/res/pkgsigverify/v3-rsa-pkcs1-sha256-2048-2-with-por_1_2-full-and-roll-caps.apk
Binary files differ
diff --git a/hostsidetests/appsecurity/src/android/appsecurity/cts/PkgInstallSignatureVerificationTest.java b/hostsidetests/appsecurity/src/android/appsecurity/cts/PkgInstallSignatureVerificationTest.java
index 05521b9..bb0735a 100644
--- a/hostsidetests/appsecurity/src/android/appsecurity/cts/PkgInstallSignatureVerificationTest.java
+++ b/hostsidetests/appsecurity/src/android/appsecurity/cts/PkgInstallSignatureVerificationTest.java
@@ -525,6 +525,19 @@
assertInstallSucceeds("v3-rsa-pkcs1-sha256-2048-2-with-por_1_2-full-caps.apk");
}
+ public void testInstallV3KeyRotationToAncestor() throws Exception {
+ // tests that a v3 signed APK with RSA key cannot be upgraded by one of its past certs
+ assertInstallSucceeds("v3-rsa-pkcs1-sha256-2048-2-with-por_1_2-full-caps.apk");
+ assertInstallFails("v3-rsa-pkcs1-sha256-2048-1.apk");
+ }
+
+ public void testInstallV3KeyRotationToAncestorWithRollback() throws Exception {
+ // tests that a v3 signed APK with RSA key can be upgraded by one of its past certs if it
+ // has granted that cert the rollback capability
+ assertInstallSucceeds("v3-rsa-pkcs1-sha256-2048-2-with-por_1_2-full-and-roll-caps.apk");
+ assertInstallSucceeds("v3-rsa-pkcs1-sha256-2048-1.apk");
+ }
+
public void testInstallV3KeyRotationMultipleHops() throws Exception {
// tests that a v3 signed APK with RSA key can rotate to a new key which is the result of
// multiple rotations from the original: APK signed with key 1 can be updated by key 3, when
diff --git a/libs/wrappedgtest/Android.mk b/libs/wrappedgtest/Android.mk
deleted file mode 100644
index f89ba9d..0000000
--- a/libs/wrappedgtest/Android.mk
+++ /dev/null
@@ -1,25 +0,0 @@
-# Copyright 2012 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.
-
-LOCAL_PATH:= $(call my-dir)
-
-include $(CLEAR_VARS)
-
-LOCAL_SRC_FILES := $(call all-java-files-under, src)
-
-LOCAL_MODULE_TAGS := optional
-
-LOCAL_MODULE := ctswrappedgtest
-
-include $(BUILD_STATIC_JAVA_LIBRARY)
diff --git a/libs/wrappedgtest/src/WrappedGTestActivity.java b/libs/wrappedgtest/src/WrappedGTestActivity.java
deleted file mode 100644
index 0633a5b..0000000
--- a/libs/wrappedgtest/src/WrappedGTestActivity.java
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- * Copyright 2012 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.test.wrappedgtest;
-
-import android.app.Activity;
-import android.app.Instrumentation;
-import android.os.Bundle;
-
-public class WrappedGTestActivity extends Activity {
-
- private WrappedGTestInstrumentation mInstrumentation;
-
- public void setInstrumentation(WrappedGTestInstrumentation instrumentation) {
- mInstrumentation = instrumentation;
- }
-
- public int runGTests() {
- return runTests(this);
- }
-
- public void sendStatus(String output) {
- Bundle outputBundle = new Bundle();
- outputBundle.putString("gtest", output);
- mInstrumentation.sendStatus(1, outputBundle);
- }
-
- protected static native int runTests(WrappedGTestActivity activity);
-}
diff --git a/libs/wrappedgtest/src/WrappedGTestInstrumentation.java b/libs/wrappedgtest/src/WrappedGTestInstrumentation.java
deleted file mode 100644
index b29aaab..0000000
--- a/libs/wrappedgtest/src/WrappedGTestInstrumentation.java
+++ /dev/null
@@ -1,68 +0,0 @@
-/*
- * Copyright 2012 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.test.wrappedgtest;
-
-import android.app.Activity;
-import android.app.Instrumentation;
-import android.app.KeyguardManager;
-import android.content.Context;
-import android.content.pm.PackageManager;
-import android.content.Intent;
-import android.os.Bundle;
-import android.util.Log;
-
-
-public class WrappedGTestInstrumentation extends Instrumentation {
-
- private static final String TAG = "WrappedGTestInstrumentation";
- private WrappedGTestActivity mActivity;
- protected Class mActivityClass;
-
- public WrappedGTestInstrumentation() {
- }
-
- @Override
- public void onCreate(Bundle arguments) {
- // attempt to disable keyguard, if current test has permission to do so
- if (getContext().checkCallingOrSelfPermission(android.Manifest.permission.DISABLE_KEYGUARD)
- == PackageManager.PERMISSION_GRANTED) {
- Log.i(TAG, "Disabling keyguard");
- KeyguardManager keyguardManager =
- (KeyguardManager) getContext().getSystemService(Context.KEYGUARD_SERVICE);
- keyguardManager.newKeyguardLock("cts").disableKeyguard();
- } else {
- Log.i(TAG, "Test lacks permission to disable keyguard. " +
- "UI based tests may fail if keyguard is up");
- }
- super.onCreate(arguments);
- start();
- }
-
- @Override
- public void onStart() {
- super.onStart();
-
- Intent intent = new Intent(getTargetContext(), mActivityClass);
- intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
-
- mActivity = (WrappedGTestActivity)startActivitySync(intent);
- mActivity.setInstrumentation(this);
- mActivity.runGTests();
-
- finish(Activity.RESULT_OK, new Bundle());
- }
-}
diff --git a/tests/app/src/android/app/cts/Instrumentation_ActivityMonitorTest.java b/tests/app/src/android/app/cts/Instrumentation_ActivityMonitorTest.java
index a8d16b7..9e070ff9 100644
--- a/tests/app/src/android/app/cts/Instrumentation_ActivityMonitorTest.java
+++ b/tests/app/src/android/app/cts/Instrumentation_ActivityMonitorTest.java
@@ -135,7 +135,8 @@
final Context context = instrumentation.getTargetContext();
// Start ActivityMonitorTestActivity
- final Intent intent = new Intent(context, ActivityMonitorTestActivity.class);
+ final Intent intent = new Intent(context, ActivityMonitorTestActivity.class)
+ .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
ActivityMonitorTestActivity amTestActivity =
(ActivityMonitorTestActivity) instrumentation.startActivitySync(intent);
@@ -183,7 +184,8 @@
final Context context = instrumentation.getTargetContext();
// Start ActivityMonitorTestActivity
- final Intent intent = new Intent(context, ActivityMonitorTestActivity.class);
+ final Intent intent = new Intent(context, ActivityMonitorTestActivity.class)
+ .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
ActivityMonitorTestActivity amTestActivity =
(ActivityMonitorTestActivity) instrumentation.startActivitySync(intent);
@@ -234,7 +236,8 @@
final Context context = instrumentation.getTargetContext();
// Start ActivityMonitorTestActivity
- final Intent intent = new Intent(context, ActivityMonitorTestActivity.class);
+ final Intent intent = new Intent(context, ActivityMonitorTestActivity.class)
+ .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
ActivityMonitorTestActivity amTestActivity =
(ActivityMonitorTestActivity) instrumentation.startActivitySync(intent);
diff --git a/tests/camera/src/android/hardware/camera2/cts/RecordingTest.java b/tests/camera/src/android/hardware/camera2/cts/RecordingTest.java
index 3fd9fa3..d2353a1 100644
--- a/tests/camera/src/android/hardware/camera2/cts/RecordingTest.java
+++ b/tests/camera/src/android/hardware/camera2/cts/RecordingTest.java
@@ -15,6 +15,7 @@
import static com.android.ex.camera2.blocking.BlockingSessionCallback.*;
import android.graphics.ImageFormat;
+import android.graphics.SurfaceTexture;
import android.hardware.camera2.CameraCharacteristics;
import android.hardware.camera2.CameraCaptureSession;
import android.hardware.camera2.CameraConstrainedHighSpeedCaptureSession;
@@ -307,6 +308,116 @@
constrainedHighSpeedRecording(/*enableSessionParams*/ true);
}
+ public void testAbandonedHighSpeedRequest() throws Exception {
+ for (String id : mCameraIds) {
+ try {
+ Log.i(TAG, "Testing bad suface for createHighSpeedRequestList for camera " + id);
+ // Re-use the MediaRecorder object for the same camera device.
+ mMediaRecorder = new MediaRecorder();
+ openDevice(id);
+ if (!mStaticInfo.isColorOutputSupported()) {
+ Log.i(TAG, "Camera " + id +
+ " does not support color outputs, skipping");
+ continue;
+ }
+ if (!mStaticInfo.isConstrainedHighSpeedVideoSupported()) {
+ Log.i(TAG, "Camera " + id +
+ " does not support constrained high speed video, skipping");
+ continue;
+ }
+
+ StreamConfigurationMap config =
+ mStaticInfo.getValueFromKeyNonNull(
+ CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP);
+ Size[] highSpeedVideoSizes = config.getHighSpeedVideoSizes();
+ Size size = highSpeedVideoSizes[0];
+ Range<Integer> fpsRange = getHighestHighSpeedFixedFpsRangeForSize(config, size);
+ mCollector.expectNotNull("Unable to find the fixed frame rate fps range for " +
+ "size " + size, fpsRange);
+ if (fpsRange == null) {
+ continue;
+ }
+
+ int captureRate = fpsRange.getLower();
+ int videoFramerate = captureRate / SLOWMO_SLOW_FACTOR;
+ // Skip the test if the highest recording FPS supported by CamcorderProfile
+ if (fpsRange.getUpper() > getFpsFromHighSpeedProfileForSize(size)) {
+ Log.w(TAG, "high speed recording " + size + "@" + captureRate + "fps"
+ + " is not supported by CamcorderProfile");
+ continue;
+ }
+
+ mOutMediaFileName = VIDEO_FILE_PATH + "/test_video.mp4";
+ prepareRecording(size, videoFramerate, captureRate);
+ updatePreviewSurfaceWithVideo(size, captureRate);
+
+ List<Surface> outputSurfaces = new ArrayList<Surface>(2);
+ assertTrue("Both preview and recording surfaces should be valid",
+ mPreviewSurface.isValid() && mRecordingSurface.isValid());
+
+ outputSurfaces.add(mPreviewSurface);
+ outputSurfaces.add(mRecordingSurface);
+
+ mSessionListener = new BlockingSessionCallback();
+ mSession = configureCameraSession(mCamera, outputSurfaces, /*highSpeed*/true,
+ mSessionListener, mHandler);
+
+ CaptureRequest.Builder requestBuilder =
+ mCamera.createCaptureRequest(CameraDevice.TEMPLATE_RECORD);
+ requestBuilder.set(CaptureRequest.CONTROL_AE_TARGET_FPS_RANGE, fpsRange);
+ requestBuilder.addTarget(mPreviewSurface);
+ requestBuilder.addTarget(mRecordingSurface);
+
+ // 1. Test abandoned MediaRecorder
+ releaseRecorder();
+ try {
+ List<CaptureRequest> slowMoRequests =
+ ((CameraConstrainedHighSpeedCaptureSession) mSession).
+ createHighSpeedRequestList(requestBuilder.build());
+ fail("Create high speed request on abandoned surface must fail!");
+ } catch (IllegalArgumentException e) {
+ Log.i(TAG, "Release recording surface test passed");
+ // expected
+ }
+
+ // 2. Test abandoned preview surface
+ mMediaRecorder = new MediaRecorder();
+ SurfaceTexture preview = new SurfaceTexture(/*random int*/ 1);
+ Surface previewSurface = new Surface(preview);
+ preview.setDefaultBufferSize(size.getWidth(), size.getHeight());
+
+ outputSurfaces = new ArrayList<Surface>();
+ outputSurfaces.add(previewSurface);
+
+ prepareRecording(size, videoFramerate, captureRate);
+ updatePreviewSurfaceWithVideo(size, captureRate);
+
+ mSession = configureCameraSession(mCamera, outputSurfaces, /*highSpeed*/true,
+ mSessionListener, mHandler);
+
+ requestBuilder = mCamera.createCaptureRequest(CameraDevice.TEMPLATE_RECORD);
+ requestBuilder.set(CaptureRequest.CONTROL_AE_TARGET_FPS_RANGE, fpsRange);
+ requestBuilder.addTarget(previewSurface);
+
+ // Abandon preview surface.
+ previewSurface.release();
+
+ try {
+ List<CaptureRequest> slowMoRequests =
+ ((CameraConstrainedHighSpeedCaptureSession) mSession).
+ createHighSpeedRequestList(requestBuilder.build());
+ fail("Create high speed request on abandoned preview surface must fail!");
+ } catch (IllegalArgumentException e) {
+ Log.i(TAG, "Release preview surface test passed");
+ // expected
+ }
+ } finally {
+ closeDevice();
+ releaseRecorder();
+ }
+ }
+ }
+
/**
* <p>
* Test recording framerate accuracy when switching from low FPS to high FPS.
diff --git a/tests/camera/src/android/hardware/camera2/cts/RobustnessTest.java b/tests/camera/src/android/hardware/camera2/cts/RobustnessTest.java
index b047bd0..fa0742f 100644
--- a/tests/camera/src/android/hardware/camera2/cts/RobustnessTest.java
+++ b/tests/camera/src/android/hardware/camera2/cts/RobustnessTest.java
@@ -967,6 +967,63 @@
}
}
+ public void testConfigureAbandonedSurface() throws Exception {
+ for (String id : mCameraIds) {
+ Log.i(TAG, String.format(
+ "Testing Camera %s for configuring abandoned surface", id));
+
+ openDevice(id);
+ try {
+ SurfaceTexture preview = new SurfaceTexture(/*random int*/ 1);
+ Surface previewSurface = new Surface(preview);
+
+ // Abandon preview SurfaceTexture.
+ preview.release();
+
+ try {
+ CaptureRequest.Builder previewRequest = preparePreviewTestSession(preview);
+ fail("Configuring abandoned surfaces must fail!");
+ } catch (IllegalArgumentException e) {
+ // expected
+ Log.i(TAG, "normal session check passed");
+ }
+
+ // Try constrained high speed session/requests
+ if (!mStaticInfo.isConstrainedHighSpeedVideoSupported()) {
+ continue;
+ }
+
+ List<Surface> surfaces = new ArrayList<>();
+ surfaces.add(previewSurface);
+ CameraCaptureSession.StateCallback sessionListener =
+ mock(CameraCaptureSession.StateCallback.class);
+
+ try {
+ mCamera.createConstrainedHighSpeedCaptureSession(surfaces,
+ sessionListener, mHandler);
+ fail("Configuring abandoned surfaces in high speed session must fail!");
+ } catch (IllegalArgumentException e) {
+ // expected
+ Log.i(TAG, "high speed session check 1 passed");
+ }
+
+ // Also try abandone the Surface directly
+ previewSurface.release();
+
+ try {
+ mCamera.createConstrainedHighSpeedCaptureSession(surfaces,
+ sessionListener, mHandler);
+ fail("Configuring abandoned surfaces in high speed session must fail!");
+ } catch (IllegalArgumentException e) {
+ // expected
+ Log.i(TAG, "high speed session check 2 passed");
+ }
+ } finally {
+ closeDevice(id);
+ }
+ }
+ }
+
public void testAfSceneChange() throws Exception {
final int NUM_FRAMES_VERIFIED = 3;
diff --git a/tests/tests/app.usage/src/android/app/usage/cts/NetworkUsageStatsTest.java b/tests/tests/app.usage/src/android/app/usage/cts/NetworkUsageStatsTest.java
index 636a6b8..e8b0463 100644
--- a/tests/tests/app.usage/src/android/app/usage/cts/NetworkUsageStatsTest.java
+++ b/tests/tests/app.usage/src/android/app/usage/cts/NetworkUsageStatsTest.java
@@ -414,7 +414,7 @@
result = mNsm.querySummary(
mNetworkInterfacesToTest[i].getNetworkType(), getSubscriberId(i),
mStartTime, mEndTime);
- assertTrue(result != null);
+ assertNotNull(result);
NetworkStats.Bucket bucket = new NetworkStats.Bucket();
long totalTxPackets = 0;
long totalRxPackets = 0;
@@ -448,8 +448,6 @@
assertTrue("No Rx packets usage for uid " + Process.myUid(), totalRxPackets > 0);
assertTrue("No Tx bytes usage for uid " + Process.myUid(), totalTxBytes > 0);
assertTrue("No Tx packets usage for uid " + Process.myUid(), totalTxPackets > 0);
- } catch (RemoteException | SecurityException e) {
- fail("testAppSummary fails with exception: " + e.toString());
} finally {
if (result != null) {
result.close();
@@ -481,31 +479,16 @@
result = mNsm.queryDetails(
mNetworkInterfacesToTest[i].getNetworkType(), getSubscriberId(i),
mStartTime, mEndTime);
- assertTrue(result != null);
- NetworkStats.Bucket bucket = new NetworkStats.Bucket();
- long totalTxPackets = 0;
- long totalRxPackets = 0;
- long totalTxBytes = 0;
- long totalRxBytes = 0;
- while (result.hasNextBucket()) {
- assertTrue(result.getNextBucket(bucket));
- assertTimestamps(bucket);
- assertEquals(bucket.getState(), NetworkStats.Bucket.STATE_ALL);
- assertEquals(bucket.getMetered(), NetworkStats.Bucket.METERED_ALL);
- assertEquals(bucket.getDefaultNetwork(),
- NetworkStats.Bucket.DEFAULT_NETWORK_ALL);
- if (bucket.getUid() == Process.myUid()) {
- totalTxPackets += bucket.getTxPackets();
- totalRxPackets += bucket.getRxPackets();
- totalTxBytes += bucket.getTxBytes();
- totalRxBytes += bucket.getRxBytes();
- }
- }
- assertFalse(result.getNextBucket(bucket));
- assertTrue("No Rx bytes usage for uid " + Process.myUid(), totalRxBytes > 0);
- assertTrue("No Rx packets usage for uid " + Process.myUid(), totalRxPackets > 0);
- assertTrue("No Tx bytes usage for uid " + Process.myUid(), totalTxBytes > 0);
- assertTrue("No Tx packets usage for uid " + Process.myUid(), totalTxPackets > 0);
+ long totalBytesWithSubscriberId = getTotalAndAssertNotEmpty(result);
+
+ // Test without filtering by subscriberId
+ result = mNsm.queryDetails(
+ mNetworkInterfacesToTest[i].getNetworkType(), null,
+ mStartTime, mEndTime);
+
+ assertTrue("More bytes with subscriberId filter than without.",
+ getTotalAndAssertNotEmpty(result) >= totalBytesWithSubscriberId);
+
} catch (RemoteException | SecurityException e) {
fail("testAppDetails fails with exception: " + e.toString());
} finally {
@@ -539,7 +522,7 @@
result = mNsm.queryDetailsForUid(
mNetworkInterfacesToTest[i].getNetworkType(), getSubscriberId(i),
mStartTime, mEndTime, Process.myUid());
- assertTrue(result != null);
+ assertNotNull(result);
NetworkStats.Bucket bucket = new NetworkStats.Bucket();
long totalTxPackets = 0;
long totalRxPackets = 0;
@@ -563,8 +546,6 @@
assertTrue("No Rx packets usage for uid " + Process.myUid(), totalRxPackets > 0);
assertTrue("No Tx bytes usage for uid " + Process.myUid(), totalTxBytes > 0);
assertTrue("No Tx packets usage for uid " + Process.myUid(), totalTxPackets > 0);
- } catch (RemoteException | SecurityException e) {
- fail("testUidDetails fails with exception: " + e.toString());
} finally {
if (result != null) {
result.close();
@@ -576,8 +557,6 @@
mNetworkInterfacesToTest[i].getNetworkType(), getSubscriberId(i),
mStartTime, mEndTime, Process.myUid());
fail("negative testUidDetails fails: no exception thrown.");
- } catch (RemoteException e) {
- fail("testUidDetails fails with exception: " + e.toString());
} catch (SecurityException e) {
// expected outcome
}
@@ -596,7 +575,7 @@
result = mNsm.queryDetailsForUidTag(
mNetworkInterfacesToTest[i].getNetworkType(), getSubscriberId(i),
mStartTime, mEndTime, Process.myUid(), NETWORK_TAG);
- assertTrue(result != null);
+ assertNotNull(result);
NetworkStats.Bucket bucket = new NetworkStats.Bucket();
long totalTxPackets = 0;
long totalRxPackets = 0;
@@ -619,14 +598,72 @@
}
assertTrue("No Rx bytes tagged with 0x" + Integer.toHexString(NETWORK_TAG)
+ " for uid " + Process.myUid(), totalRxBytes > 0);
- assertTrue("No Rx packets tagged with " + Integer.toHexString(NETWORK_TAG)
+ assertTrue("No Rx packets tagged with 0x" + Integer.toHexString(NETWORK_TAG)
+ " for uid " + Process.myUid(), totalRxPackets > 0);
assertTrue("No Tx bytes tagged with 0x" + Integer.toHexString(NETWORK_TAG)
+ " for uid " + Process.myUid(), totalTxBytes > 0);
assertTrue("No Tx packets tagged with 0x" + Integer.toHexString(NETWORK_TAG)
+ " for uid " + Process.myUid(), totalTxPackets > 0);
+ } finally {
+ if (result != null) {
+ result.close();
+ }
+ }
+ setAppOpsMode(AppOpsManager.OPSTR_GET_USAGE_STATS, "deny");
+ try {
+ result = mNsm.queryDetailsForUidTag(
+ mNetworkInterfacesToTest[i].getNetworkType(), getSubscriberId(i),
+ mStartTime, mEndTime, Process.myUid(), NETWORK_TAG);
+ fail("negative testUidDetails fails: no exception thrown.");
} catch (SecurityException e) {
- fail("testUidDetails fails with exception: " + e.toString());
+ // expected outcome
+ }
+ }
+ }
+
+ public void testUidTagStateDetails() throws Exception {
+ for (int i = 0; i < mNetworkInterfacesToTest.length; ++i) {
+ // Relatively large tolerance to accommodate for history bucket size.
+ if (!shouldTestThisNetworkType(i, MINUTE * 120)) {
+ continue;
+ }
+ setAppOpsMode(AppOpsManager.OPSTR_GET_USAGE_STATS, "allow");
+ NetworkStats result = null;
+ try {
+ // Assume test is running in the background and thus is in STATE_DEFAULT.
+ result = mNsm.queryDetailsForUidTagState(
+ mNetworkInterfacesToTest[i].getNetworkType(), getSubscriberId(i),
+ mStartTime, mEndTime, Process.myUid(), NETWORK_TAG,
+ NetworkStats.Bucket.STATE_DEFAULT);
+ assertNotNull(result);
+ NetworkStats.Bucket bucket = new NetworkStats.Bucket();
+ long totalTxPackets = 0;
+ long totalRxPackets = 0;
+ long totalTxBytes = 0;
+ long totalRxBytes = 0;
+ while (result.hasNextBucket()) {
+ assertTrue(result.getNextBucket(bucket));
+ assertTimestamps(bucket);
+ assertEquals(bucket.getState(), NetworkStats.Bucket.STATE_DEFAULT);
+ assertEquals(bucket.getMetered(), NetworkStats.Bucket.METERED_ALL);
+ assertEquals(bucket.getDefaultNetwork(),
+ NetworkStats.Bucket.DEFAULT_NETWORK_ALL);
+ assertEquals(bucket.getUid(), Process.myUid());
+ if (bucket.getTag() == NETWORK_TAG) {
+ totalTxPackets += bucket.getTxPackets();
+ totalRxPackets += bucket.getRxPackets();
+ totalTxBytes += bucket.getTxBytes();
+ totalRxBytes += bucket.getRxBytes();
+ }
+ }
+ assertTrue("No Rx bytes tagged with 0x" + Integer.toHexString(NETWORK_TAG)
+ + " for uid " + Process.myUid(), totalRxBytes > 0);
+ assertTrue("No Rx packets tagged with 0x" + Integer.toHexString(NETWORK_TAG)
+ + " for uid " + Process.myUid(), totalRxPackets > 0);
+ assertTrue("No Tx bytes tagged with 0x" + Integer.toHexString(NETWORK_TAG)
+ + " for uid " + Process.myUid(), totalTxBytes > 0);
+ assertTrue("No Tx packets tagged with 0x" + Integer.toHexString(NETWORK_TAG)
+ + " for uid " + Process.myUid(), totalTxPackets > 0);
} finally {
if (result != null) {
result.close();
@@ -668,6 +705,36 @@
}
}
+ private long getTotalAndAssertNotEmpty(NetworkStats result) {
+ assertTrue(result != null);
+ NetworkStats.Bucket bucket = new NetworkStats.Bucket();
+ long totalTxPackets = 0;
+ long totalRxPackets = 0;
+ long totalTxBytes = 0;
+ long totalRxBytes = 0;
+ while (result.hasNextBucket()) {
+ assertTrue(result.getNextBucket(bucket));
+ assertTimestamps(bucket);
+ assertEquals(bucket.getState(), NetworkStats.Bucket.STATE_ALL);
+ assertEquals(bucket.getMetered(), NetworkStats.Bucket.METERED_ALL);
+ assertEquals(bucket.getDefaultNetwork(),
+ NetworkStats.Bucket.DEFAULT_NETWORK_ALL);
+ if (bucket.getUid() == Process.myUid()) {
+ totalTxPackets += bucket.getTxPackets();
+ totalRxPackets += bucket.getRxPackets();
+ totalTxBytes += bucket.getTxBytes();
+ totalRxBytes += bucket.getRxBytes();
+ }
+ }
+ assertFalse(result.getNextBucket(bucket));
+ assertTrue("No Rx bytes usage for uid " + Process.myUid(), totalRxBytes > 0);
+ assertTrue("No Rx packets usage for uid " + Process.myUid(), totalRxPackets > 0);
+ assertTrue("No Tx bytes usage for uid " + Process.myUid(), totalTxBytes > 0);
+ assertTrue("No Tx packets usage for uid " + Process.myUid(), totalTxPackets > 0);
+
+ return totalRxBytes + totalTxBytes;
+ }
+
private void assertTimestamps(final NetworkStats.Bucket bucket) {
assertTrue("Start timestamp " + bucket.getStartTimeStamp() + " is less than " +
mStartTime, bucket.getStartTimeStamp() >= mStartTime);
diff --git a/tests/tests/content/src/android/content/res/cts/TypedArrayTest.java b/tests/tests/content/src/android/content/res/cts/TypedArrayTest.java
index 4e1469b..f27f06c 100644
--- a/tests/tests/content/src/android/content/res/cts/TypedArrayTest.java
+++ b/tests/tests/content/src/android/content/res/cts/TypedArrayTest.java
@@ -55,8 +55,7 @@
private static final String EXPECTED_NON_RESOURCE_STRING = "testNonResourcesString";
private static final String XML_BEGIN = "resources";
private static final int EXPECTED_INT_ATT = 86400;
- private static final int EXPECTED_CHANGING_CONFIG =
- ActivityInfo.CONFIG_ORIENTATION | ActivityInfo.CONFIG_LOCALE;
+ private static final int EXPECTED_CHANGING_CONFIG = ActivityInfo.CONFIG_ORIENTATION;
private TypedArray mTypedArray;
diff --git a/tests/tests/permission2/res/raw/android_manifest.xml b/tests/tests/permission2/res/raw/android_manifest.xml
index 07f1ff7..f4715fc 100644
--- a/tests/tests/permission2/res/raw/android_manifest.xml
+++ b/tests/tests/permission2/res/raw/android_manifest.xml
@@ -89,6 +89,8 @@
<protected-broadcast android:name="android.intent.action.OVERLAY_REMOVED" />
<protected-broadcast android:name="android.intent.action.OVERLAY_PRIORITY_CHANGED" />
<protected-broadcast android:name="android.intent.action.USER_ACTIVITY_NOTIFICATION" />
+ <protected-broadcast android:name="android.intent.action.MY_PACKAGE_SUSPENDED" />
+ <protected-broadcast android:name="android.intent.action.MY_PACKAGE_UNSUSPENDED" />
<protected-broadcast android:name="android.os.action.POWER_SAVE_MODE_CHANGED" />
<protected-broadcast android:name="android.os.action.POWER_SAVE_MODE_CHANGING" />
@@ -180,6 +182,8 @@
<protected-broadcast
android:name="android.bluetooth.hearingaid.profile.action.PLAYING_STATE_CHANGED" />
<protected-broadcast
+ android:name="android.bluetooth.hearingaid.profile.action.ACTIVE_DEVICE_CHANGED" />
+ <protected-broadcast
android:name="android.bluetooth.a2dp.profile.action.CONNECTION_STATE_CHANGED" />
<protected-broadcast
android:name="android.bluetooth.a2dp.profile.action.ACTIVE_DEVICE_CHANGED" />
@@ -1100,6 +1104,8 @@
<!-- Allows an app to use fingerprint hardware.
<p>Protection level: normal
+ @deprecated Applications should request {@link
+ android.Manifest.permission#USE_BIOMETRIC} instead
-->
<permission android:name="android.permission.USE_FINGERPRINT"
android:permissionGroup="android.permission-group.SENSORS"
@@ -1107,6 +1113,15 @@
android:description="@string/permdesc_useFingerprint"
android:protectionLevel="normal" />
+ <!-- Allows an app to use device supported biometric modalities.
+ <p>Protection level: normal
+ -->
+ <permission android:name="android.permission.USE_BIOMETRIC"
+ android:permissionGroup="android.permission-group.SENSORS"
+ android:label="@string/permlab_useBiometric"
+ android:description="@string/permdesc_useBiometric"
+ android:protectionLevel="normal" />
+
<!-- ====================================================================== -->
<!-- REMOVED PERMISSIONS -->
<!-- ====================================================================== -->
@@ -1341,6 +1356,13 @@
android:label="@string/permlab_changeWifiState"
android:protectionLevel="normal" />
+ <!-- @SystemApi @hide Allows apps to create and manage IPsec tunnels.
+ <p>Only granted to applications that are currently bound by the
+ system for creating and managing IPsec-based interfaces.
+ -->
+ <permission android:name="android.permission.MANAGE_IPSEC_TUNNELS"
+ android:protectionLevel="signature|appop" />
+
<!-- @SystemApi @hide Allows applications to read Wi-Fi credential.
<p>Not for use by third-party applications. -->
<permission android:name="android.permission.READ_WIFI_CREDENTIAL"
@@ -1441,6 +1463,13 @@
android:label="@string/permlab_bluetooth"
android:protectionLevel="normal" />
+ <!-- @SystemApi Allows an application to suspend other apps, which will prevent the user
+ from using them until they are unsuspended.
+ @hide
+ -->
+ <permission android:name="android.permission.SUSPEND_APPS"
+ android:protectionLevel="signature|privileged" />
+
<!-- Allows applications to discover and pair bluetooth devices.
<p>Protection level: normal
-->
@@ -1987,11 +2016,11 @@
<permission android:name="android.permission.REMOVE_TASKS"
android:protectionLevel="signature" />
- <!-- @SystemApi @hide Allows an application to create/manage/remove stacks -->
+ <!-- @SystemApi @TestApi @hide Allows an application to create/manage/remove stacks -->
<permission android:name="android.permission.MANAGE_ACTIVITY_STACKS"
android:protectionLevel="signature|privileged|development" />
- <!-- @SystemApi @hide Allows an application to embed other activities -->
+ <!-- @SystemApi @TestApi @hide Allows an application to embed other activities -->
<permission android:name="android.permission.ACTIVITY_EMBEDDING"
android:protectionLevel="signature|privileged|development" />
@@ -3092,6 +3121,12 @@
<permission android:name="android.permission.CONFIGURE_DISPLAY_COLOR_MODE"
android:protectionLevel="signature" />
+ <!-- Allows an application to control the color saturation of the display.
+ @hide
+ @SystemApi -->
+ <permission android:name="android.permission.CONTROL_DISPLAY_SATURATION"
+ android:protectionLevel="signature|privileged" />
+
<!-- Allows an application to collect usage infomation about brightness slider changes.
<p>Not for use by third-party applications.</p>
@hide
@@ -3274,6 +3309,11 @@
android:protectionLevel="signature|privileged|development|appop" />
<uses-permission android:name="android.permission.PACKAGE_USAGE_STATS" />
+ <!-- @hide @SystemApi Allows an application to observe usage time of apps. The app can register
+ for callbacks when apps reach a certain usage time limit, etc. -->
+ <permission android:name="android.permission.OBSERVE_APP_USAGE"
+ android:protectionLevel="signature|privileged" />
+
<!-- @hide @SystemApi Allows an application to change the app idle state of an app.
<p>Not for use by third-party applications. -->
<permission android:name="android.permission.CHANGE_APP_IDLE_STATE"
@@ -3310,8 +3350,9 @@
<permission android:name="android.permission.BACKUP"
android:protectionLevel="signature|privileged" />
- <!-- @SystemApi Allows application to manage RecoverableKeyStoreLoader.
- <p>Not for use by third-party applications.
+ <!-- @SystemApi Allows application to manage
+ {@link android.security.keystore.recovery.RecoveryController}.
+ <p>Not for use by third-party applications.
@hide -->
<permission android:name="android.permission.RECOVER_KEYSTORE"
android:protectionLevel="signature|privileged" />
@@ -4207,6 +4248,16 @@
android:exported="false">
</receiver>
+ <receiver android:name="com.android.server.am.BatteryStatsService$UsbConnectionReceiver"
+ android:exported="false">
+ <intent-filter>
+ <action android:name="android.intent.action.BOOT_COMPLETED" />
+ </intent-filter>
+ <intent-filter>
+ <action android:name="android.hardware.usb.action.USB_STATE" />
+ </intent-filter>
+ </receiver>
+
<service android:name="android.hardware.location.GeofenceHardwareService"
android:permission="android.permission.LOCATION_HARDWARE"
android:exported="false" />
diff --git a/tests/tests/permission2/src/android/permission2/cts/ProtectedBroadcastsTest.java b/tests/tests/permission2/src/android/permission2/cts/ProtectedBroadcastsTest.java
index 37b9461..be999f5 100644
--- a/tests/tests/permission2/src/android/permission2/cts/ProtectedBroadcastsTest.java
+++ b/tests/tests/permission2/src/android/permission2/cts/ProtectedBroadcastsTest.java
@@ -82,6 +82,7 @@
"android.net.conn.TETHER_STATE_CHANGED",
"android.net.conn.INET_CONDITION_ACTION",
"android.net.conn.CAPTIVE_PORTAL_TEST_COMPLETED",
+ "android.telephony.action.SUBSCRIPTION_CARRIER_IDENTITY_CHANGED",
"com.android.server.InputMethodManagerService.SHOW_INPUT_METHOD_PICKER"
};
diff --git a/tests/tests/telephony/src/android/telephony/cts/SubscriptionManagerTest.java b/tests/tests/telephony/src/android/telephony/cts/SubscriptionManagerTest.java
index f7ec3b7..7ed8049 100644
--- a/tests/tests/telephony/src/android/telephony/cts/SubscriptionManagerTest.java
+++ b/tests/tests/telephony/src/android/telephony/cts/SubscriptionManagerTest.java
@@ -16,63 +16,241 @@
package android.telephony.cts;
-import android.content.Context;
+import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_METERED;
+import static android.net.NetworkCapabilities.TRANSPORT_CELLULAR;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+import android.annotation.Nullable;
+import android.content.pm.PackageManager;
import android.net.ConnectivityManager;
-import android.os.Looper;
+import android.net.ConnectivityManager.NetworkCallback;
+import android.net.Network;
+import android.net.NetworkCapabilities;
+import android.net.NetworkRequest;
+import android.support.test.InstrumentationRegistry;
+import android.support.test.runner.AndroidJUnit4;
import android.telephony.SubscriptionInfo;
import android.telephony.SubscriptionManager;
-import android.test.AndroidTestCase;
-import android.util.Log;
+import android.telephony.SubscriptionPlan;
-import com.android.compatibility.common.util.TestThread;
+import com.android.compatibility.common.util.SystemUtil;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.time.ZonedDateTime;
+import java.util.Arrays;
import java.util.List;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
+import java.util.function.Predicate;
-public class SubscriptionManagerTest extends AndroidTestCase {
- private SubscriptionManager mSubscriptionManager;
- private static ConnectivityManager mCm;
- private SubscriptionManager.OnSubscriptionsChangedListener mListener;
- private final Object mLock = new Object();
- private boolean mOnSubscriptionsChangedCalled = false;
- private static final int TOLERANCE = 1000;
- private static final String TAG = "android.telephony.cts.SubscriptionManagerTest";
+@RunWith(AndroidJUnit4.class)
+public class SubscriptionManagerTest {
+ private SubscriptionManager mSm;
- @Override
- protected void setUp() throws Exception {
- super.setUp();
- mSubscriptionManager = new SubscriptionManager(getContext());
- mCm = (ConnectivityManager)getContext().getSystemService(Context.CONNECTIVITY_SERVICE);
+ private int mSubId;
+ private String mPackageName;
+
+ @Before
+ public void setUp() throws Exception {
+ mSm = InstrumentationRegistry.getContext().getSystemService(SubscriptionManager.class);
+ mSubId = SubscriptionManager.getDefaultDataSubscriptionId();
+ mPackageName = InstrumentationRegistry.getContext().getPackageName();
}
- @Override
- protected void tearDown() throws Exception {
- if (mListener != null) {
- // unregister the listener
- mSubscriptionManager.removeOnSubscriptionsChangedListener(mListener);
+ /**
+ * Sanity check that both {@link PackageManager#FEATURE_TELEPHONY} and
+ * {@link NetworkCapabilities#TRANSPORT_CELLULAR} network must both be
+ * either defined or undefined; you can't cross the streams.
+ */
+ @Test
+ public void testSanity() throws Exception {
+ final boolean hasCellular = findCellularNetwork() != null;
+ if (isSupported() && !hasCellular) {
+ fail("Device claims to support " + PackageManager.FEATURE_TELEPHONY
+ + " but has no active cellular network, which is required for validation");
+ } else if (!isSupported() && hasCellular) {
+ fail("Device has active cellular network, but claims to not support "
+ + PackageManager.FEATURE_TELEPHONY);
}
- super.tearDown();
+
+ if (isSupported()) {
+ if (mSubId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
+ fail("Device must have a valid default data subId for validation");
+ }
+ }
}
- public void testGetActiveSubscriptionInfoCount() {
- if (mCm.getNetworkInfo(ConnectivityManager.TYPE_MOBILE) == null) {
- Log.d(TAG, "Skipping test that requires ConnectivityManager.TYPE_MOBILE");
- return;
- }
- assertTrue(mSubscriptionManager.getActiveSubscriptionInfoCount() <=
- mSubscriptionManager.getActiveSubscriptionInfoCountMax());
+ @Test
+ public void testGetActiveSubscriptionInfoCount() throws Exception {
+ if (!isSupported()) return;
+
+ assertTrue(mSm.getActiveSubscriptionInfoCount() <=
+ mSm.getActiveSubscriptionInfoCountMax());
}
- public void testActiveSubscriptions() {
- if (mCm.getNetworkInfo(ConnectivityManager.TYPE_MOBILE) == null) {
- Log.d(TAG, "Skipping test that requires ConnectivityManager.TYPE_MOBILE");
- return;
- }
- List<SubscriptionInfo> subList = mSubscriptionManager.getActiveSubscriptionInfoList();
+ @Test
+ public void testActiveSubscriptions() throws Exception {
+ if (!isSupported()) return;
+
+ List<SubscriptionInfo> subList = mSm.getActiveSubscriptionInfoList();
// Assert when there is no sim card present or detected
- assertTrue(subList != null && subList.size() > 0);
+ assertNotNull("Active subscriber required", subList);
+ assertFalse("Active subscriber required", subList.isEmpty());
for (int i = 0; i < subList.size(); i++) {
assertTrue(subList.get(i).getSubscriptionId() >= 0);
assertTrue(subList.get(i).getSimSlotIndex() >= 0);
}
}
+
+ @Test
+ public void testSubscriptionPlans() throws Exception {
+ if (!isSupported()) return;
+
+ // Make ourselves the owner
+ setSubPlanOwner(mSubId, mPackageName);
+
+ // Push empty list and we get empty back
+ mSm.setSubscriptionPlans(mSubId, Arrays.asList());
+ assertEquals(Arrays.asList(), mSm.getSubscriptionPlans(mSubId));
+
+ // Push simple plan and get it back
+ final SubscriptionPlan plan = buildSubscriptionPlan();
+ mSm.setSubscriptionPlans(mSubId, Arrays.asList(plan));
+ assertEquals(Arrays.asList(plan), mSm.getSubscriptionPlans(mSubId));
+
+ // Now revoke our access
+ setSubPlanOwner(mSubId, null);
+ try {
+ mSm.setSubscriptionPlans(mSubId, Arrays.asList());
+ fail();
+ } catch (SecurityException expected) {
+ }
+ try {
+ mSm.getSubscriptionPlans(mSubId);
+ fail();
+ } catch (SecurityException expected) {
+ }
+ }
+
+ @Test
+ public void testSubscriptionPlansOverrideCongested() throws Exception {
+ if (!isSupported()) return;
+
+ // Make ourselves the owner
+ setSubPlanOwner(mSubId, mPackageName);
+
+ // Missing plans means no overrides
+ mSm.setSubscriptionPlans(mSubId, Arrays.asList());
+ try {
+ mSm.setSubscriptionOverrideCongested(mSubId, true, 0);
+ fail();
+ } catch (SecurityException | IllegalStateException expected) {
+ }
+
+ // Defining plans means we get to override
+ final SubscriptionPlan plan = buildSubscriptionPlan();
+ mSm.setSubscriptionPlans(mSubId, Arrays.asList(plan));
+ mSm.setSubscriptionOverrideCongested(mSubId, true, 0);
+ mSm.setSubscriptionOverrideCongested(mSubId, false, 0);
+
+ // Now revoke our access
+ setSubPlanOwner(mSubId, null);
+ try {
+ mSm.setSubscriptionOverrideCongested(mSubId, true, 0);
+ fail();
+ } catch (SecurityException | IllegalStateException expected) {
+ }
+ }
+
+ @Test
+ public void testSubscriptionPlansOverrideUnmetered() throws Exception {
+ if (!isSupported()) return;
+
+ final ConnectivityManager cm = InstrumentationRegistry.getContext()
+ .getSystemService(ConnectivityManager.class);
+ final Network net = findCellularNetwork();
+ assertNotNull("Active cellular network required", net);
+
+ // Make ourselves the owner and define some plans
+ setSubPlanOwner(mSubId, mPackageName);
+ mSm.setSubscriptionPlans(mSubId, Arrays.asList(buildSubscriptionPlan()));
+
+ // Cellular is metered by default
+ assertFalse(cm.getNetworkCapabilities(net).hasCapability(NET_CAPABILITY_NOT_METERED));
+
+ // Override should make it go unmetered
+ {
+ final CountDownLatch latch = waitForNetworkCapabilities(net, caps -> {
+ return caps.hasCapability(NET_CAPABILITY_NOT_METERED);
+ });
+ mSm.setSubscriptionOverrideUnmetered(mSubId, true, 0);
+ latch.await(10, TimeUnit.SECONDS);
+ }
+
+ // Clearing override should make it go metered
+ {
+ final CountDownLatch latch = waitForNetworkCapabilities(net, caps -> {
+ return !caps.hasCapability(NET_CAPABILITY_NOT_METERED);
+ });
+ mSm.setSubscriptionOverrideUnmetered(mSubId, false, 0);
+ latch.await(10, TimeUnit.SECONDS);
+ }
+ }
+
+ public static CountDownLatch waitForNetworkCapabilities(Network network,
+ Predicate<NetworkCapabilities> predicate) {
+ final CountDownLatch latch = new CountDownLatch(1);
+ final ConnectivityManager cm = InstrumentationRegistry.getContext()
+ .getSystemService(ConnectivityManager.class);
+ cm.registerNetworkCallback(new NetworkRequest.Builder().build(),
+ new NetworkCallback() {
+ @Override
+ public void onCapabilitiesChanged(Network net, NetworkCapabilities caps) {
+ if (net.equals(network) && predicate.test(caps)) {
+ latch.countDown();
+ cm.unregisterNetworkCallback(this);
+ }
+ }
+ });
+ return latch;
+ }
+
+ private static SubscriptionPlan buildSubscriptionPlan() {
+ return SubscriptionPlan.Builder
+ .createRecurringMonthly(ZonedDateTime.parse("2007-03-14T00:00:00.000Z"))
+ .setTitle("CTS")
+ .setDataLimit(1_000_000_000, SubscriptionPlan.LIMIT_BEHAVIOR_DISABLED)
+ .setDataUsage(500_000_000, System.currentTimeMillis())
+ .build();
+ }
+
+ private static @Nullable Network findCellularNetwork() {
+ final ConnectivityManager cm = InstrumentationRegistry.getContext()
+ .getSystemService(ConnectivityManager.class);
+ for (Network net : cm.getAllNetworks()) {
+ final NetworkCapabilities caps = cm.getNetworkCapabilities(net);
+ if (caps != null && caps.hasTransport(TRANSPORT_CELLULAR)) {
+ return net;
+ }
+ }
+ return null;
+ }
+
+ private static boolean isSupported() {
+ return InstrumentationRegistry.getContext().getPackageManager()
+ .hasSystemFeature(PackageManager.FEATURE_TELEPHONY);
+ }
+
+ private static void setSubPlanOwner(int subId, String packageName) throws Exception {
+ SystemUtil.runShellCommand(InstrumentationRegistry.getInstrumentation(),
+ "cmd netpolicy set sub-plan-owner " + subId + " " + packageName);
+ }
}