Merge "Merge history of cts/hostsidetests/statsd" into stage-aosp-master
diff --git a/tests/framework/base/windowmanager/src/android/server/wm/AppConfigurationTests.java b/tests/framework/base/windowmanager/src/android/server/wm/AppConfigurationTests.java
index 5adb97f..191a70b 100644
--- a/tests/framework/base/windowmanager/src/android/server/wm/AppConfigurationTests.java
+++ b/tests/framework/base/windowmanager/src/android/server/wm/AppConfigurationTests.java
@@ -888,7 +888,10 @@
* that are smaller than the dockedSizes.
*/
private static void assertSizesAreSane(SizeInfo fullscreenSizes, SizeInfo dockedSizes) {
- if (isDisplayPortrait()) {
+ final boolean isHorizontalDivision =
+ fullscreenSizes.displayHeight - dockedSizes.displayHeight >
+ fullscreenSizes.displayWidth - dockedSizes.displayWidth;
+ if (isHorizontalDivision) {
assertThat(dockedSizes.displayHeight, lessThan(fullscreenSizes.displayHeight));
assertThat(dockedSizes.heightDp, lessThan(fullscreenSizes.heightDp));
assertThat(dockedSizes.metricsHeight, lessThan(fullscreenSizes.metricsHeight));
diff --git a/tests/framework/base/windowmanager/src/android/server/wm/PinnedStackTests.java b/tests/framework/base/windowmanager/src/android/server/wm/PinnedStackTests.java
index 89b310d..2a82511 100644
--- a/tests/framework/base/windowmanager/src/android/server/wm/PinnedStackTests.java
+++ b/tests/framework/base/windowmanager/src/android/server/wm/PinnedStackTests.java
@@ -862,7 +862,7 @@
public void testConfigurationChangeOrderDuringTransition() throws Exception {
// Launch a PiP activity and ensure configuration change only happened once, and that the
// configuration change happened after the picture-in-picture and multi-window callbacks
- launchActivity(PIP_ACTIVITY);
+ launchActivity(PIP_ACTIVITY, WINDOWING_MODE_FULLSCREEN);
separateTestJournal();
int windowingMode = mWmState.getTaskByActivity(PIP_ACTIVITY).getWindowingMode();
mBroadcastActionTrigger.doAction(ACTION_ENTER_PIP);
diff --git a/tests/media/OWNERS b/tests/media/OWNERS
index 4f734c8..ad8bb0a 100644
--- a/tests/media/OWNERS
+++ b/tests/media/OWNERS
@@ -9,3 +9,7 @@
marcone@google.com
pawin@google.com
wonsik@google.com
+
+# LON
+olly@google.com
+andrewlewis@google.com
diff --git a/tests/tests/media/OWNERS b/tests/tests/media/OWNERS
index e3d8ccc..4f5a2ef 100644
--- a/tests/tests/media/OWNERS
+++ b/tests/tests/media/OWNERS
@@ -12,3 +12,7 @@
jmtrivi@google.com
jsharkey@android.com
sungsoo@google.com
+
+# LON
+olly@google.com
+andrewlewis@google.com
diff --git a/tests/tests/permission2/res/raw/android_manifest.xml b/tests/tests/permission2/res/raw/android_manifest.xml
index cbcaf24..e04ace9 100644
--- a/tests/tests/permission2/res/raw/android_manifest.xml
+++ b/tests/tests/permission2/res/raw/android_manifest.xml
@@ -2302,6 +2302,15 @@
<permission android:name="android.permission.READ_CARRIER_APP_INFO"
android:protectionLevel="signature" />
+ <!-- Must be required by an GbaService to ensure that only the
+ system can bind to it.
+ <p>Protection level: signature
+ @SystemApi
+ @hide
+ -->
+ <permission android:name="android.permission.BIND_GBA_SERVICE"
+ android:protectionLevel="signature" />
+
<!-- ================================== -->
<!-- Permissions for sdcard interaction -->
<!-- ================================== -->
diff --git a/tests/tests/selinux/common/src/android/security/SELinuxTargetSdkTestBase.java b/tests/tests/selinux/common/src/android/security/SELinuxTargetSdkTestBase.java
index 6ec352c..496270f 100644
--- a/tests/tests/selinux/common/src/android/security/SELinuxTargetSdkTestBase.java
+++ b/tests/tests/selinux/common/src/android/security/SELinuxTargetSdkTestBase.java
@@ -12,6 +12,7 @@
import java.util.Collections;
import java.util.regex.Pattern;
import java.util.regex.Matcher;
+import org.junit.Assert;
abstract class SELinuxTargetSdkTestBase extends AndroidTestCase
{
@@ -19,6 +20,8 @@
System.loadLibrary("ctsselinux_jni");
}
+ static final byte[] ANONYMIZED_HARDWARE_ADDRESS = { 0x02, 0x00, 0x00, 0x00, 0x00, 0x00 };
+
protected static String getFile(String filename) throws IOException {
BufferedReader in = null;
try {
@@ -76,19 +79,11 @@
}
}
- protected static void checkNetlinkRouteBind(boolean expectAllowed) throws IOException {
- if (!expectAllowed) {
- assertEquals(
- "Bind() is not allowed on a netlink route sockets",
- 13,
- checkNetlinkRouteBind());
- } else {
- assertEquals(
- "Bind() should succeed for netlink route sockets for apps with "
- + "targetSdkVersion <= Q",
- -1,
- checkNetlinkRouteBind());
- }
+ protected static void noNetlinkRouteBind() throws IOException {
+ assertEquals(
+ "bind() is not allowed on netlink route sockets",
+ 13,
+ checkNetlinkRouteBind());
}
/**
@@ -169,16 +164,17 @@
}
/**
- * Verify that apps having targetSdkVersion <= 29 are able to see MAC
- * addresses of ethernet devices.
+ * Verify that apps having targetSdkVersion <= 29 get an anonymized MAC
+ * address (02:00:00:00:00:00) instead of a null MAC for ethernet interfaces.
* The counterpart of this test (testing for targetSdkVersion > 29) is
* {@link libcore.java.net.NetworkInterfaceTest#testGetHardwareAddress_returnsNull()}.
*/
- protected static void checkNetworkInterface_returnsHardwareAddresses() throws Exception {
+ protected static void checkNetworkInterface_returnsAnonymizedHardwareAddresses()
+ throws Exception {
assertNotNull(NetworkInterface.getNetworkInterfaces());
for (NetworkInterface nif : Collections.list(NetworkInterface.getNetworkInterfaces())) {
if (isEthernet(nif.getName())) {
- assertEquals(6, nif.getHardwareAddress().length);
+ Assert.assertArrayEquals(ANONYMIZED_HARDWARE_ADDRESS, nif.getHardwareAddress());
}
}
}
diff --git a/tests/tests/selinux/selinuxEphemeral/src/android/security/SELinuxTargetSdkTest.java b/tests/tests/selinux/selinuxEphemeral/src/android/security/SELinuxTargetSdkTest.java
index 1ed366e..1098a6f 100644
--- a/tests/tests/selinux/selinuxEphemeral/src/android/security/SELinuxTargetSdkTest.java
+++ b/tests/tests/selinux/selinuxEphemeral/src/android/security/SELinuxTargetSdkTest.java
@@ -83,6 +83,6 @@
}
public void testNoNetlinkRouteBind() throws IOException {
- checkNetlinkRouteBind(false);
+ noNetlinkRouteBind();
}
}
diff --git a/tests/tests/selinux/selinuxTargetSdk27/src/android/security/SELinuxTargetSdkTest.java b/tests/tests/selinux/selinuxTargetSdk27/src/android/security/SELinuxTargetSdkTest.java
index a784464..5e2f75d 100644
--- a/tests/tests/selinux/selinuxTargetSdk27/src/android/security/SELinuxTargetSdkTest.java
+++ b/tests/tests/selinux/selinuxTargetSdk27/src/android/security/SELinuxTargetSdkTest.java
@@ -66,6 +66,6 @@
}
public void testNetworkInterface() throws Exception {
- checkNetworkInterface_returnsHardwareAddresses();
+ checkNetworkInterface_returnsAnonymizedHardwareAddresses();
}
}
diff --git a/tests/tests/selinux/selinuxTargetSdk28/src/android/security/SELinuxTargetSdkTest.java b/tests/tests/selinux/selinuxTargetSdk28/src/android/security/SELinuxTargetSdkTest.java
index 880ae1a..29b68db 100644
--- a/tests/tests/selinux/selinuxTargetSdk28/src/android/security/SELinuxTargetSdkTest.java
+++ b/tests/tests/selinux/selinuxTargetSdk28/src/android/security/SELinuxTargetSdkTest.java
@@ -66,6 +66,6 @@
}
public void testNetworkInterface() throws Exception {
- checkNetworkInterface_returnsHardwareAddresses();
+ checkNetworkInterface_returnsAnonymizedHardwareAddresses();
}
}
diff --git a/tests/tests/selinux/selinuxTargetSdk29/src/android/security/SELinuxTargetSdkTest.java b/tests/tests/selinux/selinuxTargetSdk29/src/android/security/SELinuxTargetSdkTest.java
index 1f1eaaa..c1d93dc 100644
--- a/tests/tests/selinux/selinuxTargetSdk29/src/android/security/SELinuxTargetSdkTest.java
+++ b/tests/tests/selinux/selinuxTargetSdk29/src/android/security/SELinuxTargetSdkTest.java
@@ -47,8 +47,8 @@
checkNetlinkRouteGetlink(true);
}
- public void testNetlinkRouteBindSucceeds() throws IOException {
- checkNetlinkRouteBind(true);
+ public void testNoNetlinkRouteBind() throws IOException {
+ noNetlinkRouteBind();
}
public void testCanNotExecuteFromHomeDir() throws Exception {
@@ -86,6 +86,6 @@
}
public void testNetworkInterface() throws Exception {
- checkNetworkInterface_returnsHardwareAddresses();
+ checkNetworkInterface_returnsAnonymizedHardwareAddresses();
}
}
diff --git a/tests/tests/selinux/selinuxTargetSdkCurrent/src/android/security/SELinuxTargetSdkTest.java b/tests/tests/selinux/selinuxTargetSdkCurrent/src/android/security/SELinuxTargetSdkTest.java
index 05fad31..4de03b0 100644
--- a/tests/tests/selinux/selinuxTargetSdkCurrent/src/android/security/SELinuxTargetSdkTest.java
+++ b/tests/tests/selinux/selinuxTargetSdkCurrent/src/android/security/SELinuxTargetSdkTest.java
@@ -38,7 +38,7 @@
}
public void testNoNetlinkRouteBind() throws IOException {
- checkNetlinkRouteBind(false);
+ noNetlinkRouteBind();
}
public void testCanNotExecuteFromHomeDir() throws Exception {
diff --git a/tests/tests/telephony/current/AndroidManifest.xml b/tests/tests/telephony/current/AndroidManifest.xml
index f6b655e..2a26b18 100644
--- a/tests/tests/telephony/current/AndroidManifest.xml
+++ b/tests/tests/telephony/current/AndroidManifest.xml
@@ -150,6 +150,16 @@
</intent-filter>
</service>
+ <service
+ android:name="android.telephony.gba.cts.TestGbaService"
+ android:directBootAware="true"
+ android:permission="android.permission.BIND_GBA_SERVICE"
+ android:exported="true">
+ <intent-filter>
+ <action android:name="android.telephony.gba.GbaService"/>
+ </intent-filter>
+ </service>
+
<activity android:name="android.telephony.cts.StubDialerActvity">
<intent-filter>
<action android:name="android.intent.action.DIAL" />
diff --git a/tests/tests/telephony/current/src/android/telephony/gba/cts/GbaServiceTest.java b/tests/tests/telephony/current/src/android/telephony/gba/cts/GbaServiceTest.java
new file mode 100644
index 0000000..64a1538
--- /dev/null
+++ b/tests/tests/telephony/current/src/android/telephony/gba/cts/GbaServiceTest.java
@@ -0,0 +1,337 @@
+/*
+ * 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.telephony.gba.cts;
+
+import static org.junit.Assert.assertArrayEquals;
+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 android.app.Instrumentation;
+import android.content.pm.PackageManager;
+import android.net.Uri;
+import android.os.AsyncTask;
+import android.telephony.SubscriptionManager;
+import android.telephony.TelephonyManager;
+import android.telephony.cts.TelephonyUtils;
+import android.telephony.gba.UaSecurityProtocolIdentifier;
+import android.util.Log;
+
+import androidx.test.InstrumentationRegistry;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
+
+import com.android.compatibility.common.util.ShellIdentityUtils;
+
+import org.junit.AfterClass;
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.util.Random;
+import java.util.concurrent.atomic.AtomicBoolean;
+
+@RunWith(AndroidJUnit4.class)
+public final class GbaServiceTest {
+
+ private static final String TAG = "GbaServiceTest";
+
+ private static final String COMMAND_UPDATE_PACKAGE = "cmd phone gba set-service ";
+ private static final String COMMAND_UPDATE_RELEASE = "cmd phone gba set-release ";
+ private static final String COMMAND_GET_PACKAGE = "cmd phone gba get-service";
+ private static final String COMMAND_GET_RELEASE = "cmd phone gba get-release";
+ private static final String SERVICE_PACKAGE = "android.telephony.cts";
+ private static final String NAF = "3GPP-bootstrapping@naf1.operator.com";
+ private static final String BTID = "(B-TID)";
+ private static final int REQ_TIMEOUT = 5000;
+ private static final int RELEASE_DEFAULT = 0;
+ private static final int RELEASE_TEST_MS = 15 * 1000;
+ private static final int RELEASE_NEVER = -1;
+
+ private static int sSubId;
+ private static Instrumentation sInstrumentation;
+ private static TelephonyManager sTm;
+ private static TestGbaConfig sConfig;
+ private static String sServiceConfig;
+ private static int sReleaseTimeConfig;
+
+ @BeforeClass
+ public static void init() throws Exception {
+ if (!isFeatureSupported()) {
+ return;
+ }
+
+ sConfig = TestGbaConfig.getInstance();
+ sInstrumentation = InstrumentationRegistry.getInstrumentation();
+ sTm = sInstrumentation.getContext().getSystemService(TelephonyManager.class);
+ sServiceConfig = TelephonyUtils.executeShellCommand(
+ sInstrumentation, COMMAND_GET_PACKAGE);
+ sReleaseTimeConfig = Integer.parseInt(TelephonyUtils.executeShellCommand(
+ sInstrumentation, COMMAND_GET_RELEASE));
+ }
+
+ @AfterClass
+ public static void release() throws Exception {
+ if (!isFeatureSupported()) {
+ return;
+ }
+
+ setService(sServiceConfig);
+ setReleaseTime(sReleaseTimeConfig);
+ }
+
+ @Before
+ public void setUp() throws Exception {
+ if (!isFeatureSupported()) {
+ return;
+ }
+
+ setService(SERVICE_PACKAGE);
+ setReleaseTime(RELEASE_DEFAULT);
+ }
+
+ @Test (expected = SecurityException.class)
+ public void testPermissions() {
+ if (!isFeatureSupported()) {
+ throw new SecurityException("Feaure is not supported");
+ }
+
+ runGbaFailCase(TelephonyManager.GBA_FAILURE_REASON_FEATURE_NOT_SUPPORTED,
+ android.Manifest.permission.READ_PHONE_STATE);
+ }
+
+ @Test
+ public void testAuthSuccess() {
+ if (!isFeatureSupported()) {
+ return;
+ }
+
+ Random rand = new Random();
+
+ for (int i = 0; i < 20; i++) {
+ Log.d(TAG, "testAuthSuccess[" + i + "]");
+ byte[] key = new byte[16];
+ rand.nextBytes(key);
+ sConfig.setConfig(true, key, BTID, TelephonyManager.GBA_FAILURE_REASON_UNKNOWN);
+ final AtomicBoolean isSuccess = new AtomicBoolean(false);
+ final AtomicBoolean isFail = new AtomicBoolean(false);
+ TelephonyManager.BootstrapAuthenticationCallback cb = new
+ TelephonyManager.BootstrapAuthenticationCallback() {
+ @Override
+ public void onKeysAvailable(byte[] gbaKey, String btId) {
+ assertNotNull(gbaKey);
+ assertNotNull(btId);
+ assertArrayEquals(key, gbaKey);
+ assertEquals(BTID, btId);
+ synchronized (isSuccess) {
+ isSuccess.set(true);
+ isSuccess.notify();
+ }
+ }
+
+ @Override
+ public void onAuthenticationFailure(int reason) {
+ synchronized (isSuccess) {
+ isFail.set(true);
+ isSuccess.notify();
+ }
+ }
+ };
+ UaSecurityProtocolIdentifier.Builder builder =
+ new UaSecurityProtocolIdentifier.Builder();
+ builder.setOrg(UaSecurityProtocolIdentifier.ORG_3GPP).setProtocol(
+ UaSecurityProtocolIdentifier.UA_SECURITY_PROTOCOL_3GPP_HTTP_BASED_MBMS);
+
+ ShellIdentityUtils.invokeMethodWithShellPermissionsNoReturn(sTm,
+ (tm) -> tm.bootstrapAuthenticationRequest(TelephonyManager.APPTYPE_USIM,
+ Uri.parse(NAF), builder.build(), true, AsyncTask.SERIAL_EXECUTOR, cb),
+ android.Manifest.permission.MODIFY_PHONE_STATE);
+ waitForMs(isSuccess, REQ_TIMEOUT);
+
+ assertTrue(isSuccess.get());
+ assertFalse(isFail.get());
+ }
+ }
+
+ @Test
+ public void testGbaNotSupported() throws Exception {
+ if (!isFeatureSupported()) {
+ return;
+ }
+
+ setService("");
+ sConfig.setConfig(true, new byte[16], BTID, TelephonyManager.GBA_FAILURE_REASON_UNKNOWN);
+
+ runGbaFailCase(TelephonyManager.GBA_FAILURE_REASON_FEATURE_NOT_SUPPORTED,
+ android.Manifest.permission.MODIFY_PHONE_STATE);
+
+ assertTrue(setService(SERVICE_PACKAGE));
+ }
+
+ @Test
+ public void testAuthFail() {
+ if (!isFeatureSupported()) {
+ return;
+ }
+
+ for (int r = TelephonyManager.GBA_FAILURE_REASON_UNKNOWN;
+ r <= TelephonyManager.GBA_FAILURE_REASON_SECURITY_PROTOCOL_NOT_SUPPORTED; r++) {
+ sConfig.setConfig(false, new byte[16], BTID, r);
+ runGbaFailCase(r, android.Manifest.permission.MODIFY_PHONE_STATE);
+ }
+ }
+
+ private void runGbaFailCase(int r, String permission) {
+ final AtomicBoolean isSuccess = new AtomicBoolean(false);
+ final AtomicBoolean isFail = new AtomicBoolean(false);
+ TelephonyManager.BootstrapAuthenticationCallback cb = new
+ TelephonyManager.BootstrapAuthenticationCallback() {
+ @Override
+ public void onKeysAvailable(byte[] gbaKey, String btId) {
+ synchronized (isFail) {
+ isSuccess.set(true);
+ isFail.notify();
+ }
+ }
+
+ @Override
+ public void onAuthenticationFailure(int reason) {
+ assertEquals(reason, r);
+ synchronized (isFail) {
+ isFail.set(true);
+ isFail.notify();
+ }
+ }
+ };
+ UaSecurityProtocolIdentifier.Builder builder = new UaSecurityProtocolIdentifier.Builder();
+ builder.setOrg(UaSecurityProtocolIdentifier.ORG_3GPP).setProtocol(
+ UaSecurityProtocolIdentifier.UA_SECURITY_PROTOCOL_3GPP_HTTP_BASED_MBMS);
+
+ ShellIdentityUtils.invokeMethodWithShellPermissionsNoReturn(sTm,
+ (tm) -> tm.bootstrapAuthenticationRequest(TelephonyManager.APPTYPE_USIM,
+ Uri.parse(NAF), builder.build(), true, AsyncTask.SERIAL_EXECUTOR, cb), permission);
+ waitForMs(isFail, REQ_TIMEOUT);
+
+ assertTrue(isFail.get());
+ assertFalse(isSuccess.get());
+ }
+
+ @Test
+ public void testServiceReleaseDefault() throws Exception {
+ if (!isFeatureSupported()) {
+ return;
+ }
+
+ int ss = sConfig.getServiceState();
+ boolean isExpected = (ss == TestGbaConfig.STATE_UNKNOWN
+ || ss == TestGbaConfig.STATE_REMOVED
+ || ss == TestGbaConfig.STATE_UNBOUND);
+ assertTrue(isExpected);
+ sConfig.setConfig(false, new byte[16], BTID,
+ TelephonyManager.GBA_FAILURE_REASON_UNKNOWN);
+
+ runGbaFailCase(TelephonyManager.GBA_FAILURE_REASON_UNKNOWN,
+ android.Manifest.permission.MODIFY_PHONE_STATE);
+ waitForMs(sConfig, 500);
+
+ assertFalse(TestGbaConfig.STATE_BOUND == sConfig.getServiceState());
+ }
+
+ @Test
+ public void testServiceReleaseDuration() throws Exception {
+ if (!isFeatureSupported()) {
+ return;
+ }
+
+ int ss = sConfig.getServiceState();
+ boolean isExpected = (ss == TestGbaConfig.STATE_UNKNOWN
+ || ss == TestGbaConfig.STATE_REMOVED
+ || ss == TestGbaConfig.STATE_UNBOUND);
+ assertTrue(isExpected);
+ sConfig.setConfig(false, new byte[16], BTID,
+ TelephonyManager.GBA_FAILURE_REASON_UNKNOWN);
+ assertTrue(setReleaseTime(RELEASE_TEST_MS));
+
+ runGbaFailCase(TelephonyManager.GBA_FAILURE_REASON_UNKNOWN,
+ android.Manifest.permission.MODIFY_PHONE_STATE);
+
+ waitForMs(sConfig, 500);
+ assertEquals(TestGbaConfig.STATE_BOUND, sConfig.getServiceState());
+
+ waitForMs(sConfig, RELEASE_TEST_MS);
+ assertFalse(TestGbaConfig.STATE_BOUND == sConfig.getServiceState());
+ }
+
+ @Test
+ public void testServiceNoRelease() throws Exception {
+ if (!isFeatureSupported()) {
+ return;
+ }
+
+ int ss = sConfig.getServiceState();
+ boolean isExpected = (ss == TestGbaConfig.STATE_UNKNOWN
+ || ss == TestGbaConfig.STATE_REMOVED
+ || ss == TestGbaConfig.STATE_UNBOUND);
+ assertTrue(isExpected);
+ sConfig.setConfig(false, new byte[16], BTID,
+ TelephonyManager.GBA_FAILURE_REASON_UNKNOWN);
+ assertTrue(setReleaseTime(RELEASE_NEVER));
+
+ runGbaFailCase(TelephonyManager.GBA_FAILURE_REASON_UNKNOWN,
+ android.Manifest.permission.MODIFY_PHONE_STATE);
+ waitForMs(sConfig, 2 * RELEASE_TEST_MS);
+
+ assertEquals(TestGbaConfig.STATE_BOUND, sConfig.getServiceState());
+ }
+
+ public static void waitForMs(Object obj, long ms) {
+ synchronized (obj) {
+ try {
+ obj.wait(ms);
+ } catch (InterruptedException e) {
+ Log.d(TAG, "InterruptedException while waiting: " + e);
+ }
+ }
+ }
+
+ private static boolean setService(String packageName) throws Exception {
+ String result = TelephonyUtils.executeShellCommand(sInstrumentation,
+ COMMAND_UPDATE_PACKAGE + packageName);
+ return "true".equals(result);
+ }
+
+ private static boolean setReleaseTime(int interval) throws Exception {
+ String result = TelephonyUtils.executeShellCommand(sInstrumentation,
+ COMMAND_UPDATE_RELEASE + interval);
+ return "true".equals(result);
+ }
+
+ private static boolean isFeatureSupported() {
+ if (!InstrumentationRegistry.getContext().getPackageManager().hasSystemFeature(
+ PackageManager.FEATURE_TELEPHONY)) {
+ return false;
+ }
+ int[] activeSubs = InstrumentationRegistry.getContext().getSystemService(
+ SubscriptionManager.class).getActiveSubscriptionIdList();
+ if (activeSubs.length == 0) {
+ return false;
+ }
+ sSubId = activeSubs[0];
+ return true;
+ }
+}
diff --git a/tests/tests/telephony/current/src/android/telephony/gba/cts/TestGbaConfig.java b/tests/tests/telephony/current/src/android/telephony/gba/cts/TestGbaConfig.java
new file mode 100644
index 0000000..33d1a83
--- /dev/null
+++ b/tests/tests/telephony/current/src/android/telephony/gba/cts/TestGbaConfig.java
@@ -0,0 +1,90 @@
+/*
+ * 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.telephony.gba.cts;
+
+final class TestGbaConfig {
+
+ static final int STATE_UNKNOWN = 0;
+ static final int STATE_CREATED = 1;
+ static final int STATE_BOUND = 2;
+ static final int STATE_UNBOUND = 3;
+ static final int STATE_REMOVED = 4;
+
+ private boolean mIsAuthSuccess;
+ private byte[] mGbaKey;
+ private String mBTid;
+ private int mFailReason;
+ private int mServiceState;
+
+ private static TestGbaConfig sInstance;
+
+ private TestGbaConfig() {
+ }
+
+ static TestGbaConfig getInstance() {
+ if (sInstance == null) {
+ sInstance = new TestGbaConfig();
+ }
+ return sInstance;
+ }
+
+ void setConfig(boolean success, byte[] key, String id, int reason) {
+ synchronized (this) {
+ mIsAuthSuccess = success;
+ mGbaKey = key;
+ mBTid = id;
+ mFailReason = reason;
+ }
+ }
+
+ boolean isAuthSuccess() {
+ synchronized (this) {
+ return mIsAuthSuccess;
+ }
+ }
+
+ byte[] getGbaKey() {
+ synchronized (this) {
+ return mGbaKey;
+ }
+ }
+
+ String getBTid() {
+ synchronized (this) {
+ return mBTid;
+ }
+ }
+
+ int getFailReason() {
+ synchronized (this) {
+ return mFailReason;
+ }
+ }
+
+ void setServiceState(int state) {
+ synchronized (this) {
+ mServiceState = state;
+ this.notify();
+ }
+ }
+
+ int getServiceState() {
+ synchronized (this) {
+ return mServiceState;
+ }
+ }
+}
diff --git a/tests/tests/telephony/current/src/android/telephony/gba/cts/TestGbaService.java b/tests/tests/telephony/current/src/android/telephony/gba/cts/TestGbaService.java
new file mode 100644
index 0000000..702f757
--- /dev/null
+++ b/tests/tests/telephony/current/src/android/telephony/gba/cts/TestGbaService.java
@@ -0,0 +1,74 @@
+/*
+ * 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.telephony.gba.cts;
+
+import android.annotation.NonNull;
+import android.content.Intent;
+import android.net.Uri;
+import android.os.IBinder;
+import android.telephony.gba.GbaService;
+import android.util.Log;
+
+public class TestGbaService extends GbaService {
+
+ private static final String TAG = "TestGbaService";
+
+ private TestGbaConfig mConfig;
+
+ @Override
+ public void onCreate() {
+ Log.i(TAG, "Service created");
+ mConfig = TestGbaConfig.getInstance();
+ mConfig.setServiceState(TestGbaConfig.STATE_CREATED);
+ }
+
+ @Override
+ public void onAuthenticationRequest(int subId, int token, int appType,
+ @NonNull Uri nafUrl, @NonNull byte[] securityProtocol, boolean forceBootStrapping) {
+ boolean isSuccess = mConfig.isAuthSuccess();
+ int reason = mConfig.getFailReason();
+ byte[] key = mConfig.getGbaKey();
+ String btid = mConfig.getBTid();
+
+ if (isSuccess) {
+ reportKeysAvailable(token, key, btid);
+ } else {
+ reportAuthenticationFailure(token, reason);
+ }
+ }
+
+ @Override
+ public IBinder onBind(Intent intent) {
+ Log.d(TAG, "onBind intent:" + intent);
+ mConfig.setServiceState(TestGbaConfig.STATE_BOUND);
+ return super.onBind(intent);
+ }
+
+ @Override
+ public boolean onUnbind(Intent intent) {
+ Log.d(TAG, "onUnbind intent:" + intent);
+ mConfig.setServiceState(TestGbaConfig.STATE_UNBOUND);
+ return super.onUnbind(intent);
+ }
+
+ @Override
+ public void onDestroy() {
+ Log.d(TAG, "onDestroy!");
+ mConfig.setServiceState(TestGbaConfig.STATE_REMOVED);
+ super.onDestroy();
+ }
+}
diff --git a/tests/tests/telephony/current/src/android/telephony/gba/cts/UaSecurityProtocolIdentifierTest.java b/tests/tests/telephony/current/src/android/telephony/gba/cts/UaSecurityProtocolIdentifierTest.java
new file mode 100644
index 0000000..ae1b0fd
--- /dev/null
+++ b/tests/tests/telephony/current/src/android/telephony/gba/cts/UaSecurityProtocolIdentifierTest.java
@@ -0,0 +1,209 @@
+/*
+ * 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.telephony.gba.cts;
+
+import static org.junit.Assert.assertArrayEquals;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+
+import android.os.Parcel;
+import android.telephony.gba.TlsParams;
+import android.telephony.gba.UaSecurityProtocolIdentifier;
+
+import androidx.test.ext.junit.runners.AndroidJUnit4;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.nio.ByteBuffer;
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.Random;
+
+@RunWith(AndroidJUnit4.class)
+public final class UaSecurityProtocolIdentifierTest {
+ private static final String TAG = "UaSecurityProtocolIdentifierTest";
+ private static final int PROTO_SIZE = 5;
+ private static final byte[] PROTO_DEFAULT = {0x00, 0x00, 0x00, 0x00, 0x00};
+ private static final int[] PROTO_3GPP_PLAIN_ID = {
+ UaSecurityProtocolIdentifier.UA_SECURITY_PROTOCOL_3GPP_SUBSCRIBER_CERTIFICATE,
+ UaSecurityProtocolIdentifier.UA_SECURITY_PROTOCOL_3GPP_MBMS,
+ UaSecurityProtocolIdentifier.UA_SECURITY_PROTOCOL_3GPP_HTTP_DIGEST_AUTHENTICATION,
+ UaSecurityProtocolIdentifier.UA_SECURITY_PROTOCOL_3GPP_HTTP_BASED_MBMS,
+ UaSecurityProtocolIdentifier.UA_SECURITY_PROTOCOL_3GPP_SIP_BASED_MBMS,
+ UaSecurityProtocolIdentifier.UA_SECURITY_PROTOCOL_3GPP_GENERIC_PUSH_LAYER,
+ UaSecurityProtocolIdentifier.UA_SECURITY_PROTOCOL_3GPP_IMS_MEDIA_PLANE,
+ UaSecurityProtocolIdentifier.UA_SECURITY_PROTOCOL_3GPP_GENERATION_TMPI};
+ private static final byte[][] PROTO_3GPP_PLAIN = {
+ {0x01, 0x00, 0x00, 0x00, 0x00},
+ {0x01, 0x00, 0x00, 0x00, 0x01},
+ {0x01, 0x00, 0x00, 0x00, 0x02},
+ {0x01, 0x00, 0x00, 0x00, 0x03},
+ {0x01, 0x00, 0x00, 0x00, 0x04},
+ {0x01, 0x00, 0x00, 0x00, 0x05},
+ {0x01, 0x00, 0x00, 0x00, 0x06},
+ {0x01, 0x00, 0x00, 0x01, 0x00}};
+ private static final int[] PROTO_3GPP_TLS_ID = {
+ UaSecurityProtocolIdentifier.UA_SECURITY_PROTOCOL_3GPP_TLS_DEFAULT,
+ UaSecurityProtocolIdentifier.UA_SECURITY_PROTOCOL_3GPP_TLS_BROWSER};
+ private static final byte[][] PROTO_3GPP_TLS = {
+ {0x01, 0x00, 0x01, 0x00, 0x00},
+ {0x01, 0x00, 0x02, 0x00, 0x00}};
+
+ private static final int[] TLS_CS_ID_SUPPORTED = {
+ 0x0000, 0x0001, 0x0002, 0x0004, 0x0005, 0x000A, 0x000D, 0x0010, 0x0013, 0x0016, 0x0018,
+ 0x001B, 0x002F, 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, 0x0038,
+ 0x0039, 0x003A, 0x003B, 0x003C, 0x003D, 0x003E, 0x003F, 0x0040, 0x0067, 0x0068, 0x0069,
+ 0x006A, 0x006B, 0x006C, 0x006D, 0x009E, 0x009F, 0x00AA, 0x00AB, 0x1301, 0x1302, 0x1303,
+ 0x1304, 0xC02B, 0xC02C, 0xC02F, 0xC030, 0xC09E, 0xC09F, 0xC0A6, 0xC0A7, 0xCCA8, 0xCCA9,
+ 0xCCAA, 0xCCAC, 0xCCAD, 0xD001, 0xD002, 0xD005};
+
+ @Test
+ public void testDefaultId() {
+ UaSecurityProtocolIdentifier.Builder builder = new UaSecurityProtocolIdentifier.Builder();
+ UaSecurityProtocolIdentifier sp = builder.build();
+ assertNotNull(sp);
+ assertEquals(UaSecurityProtocolIdentifier.ORG_NONE, sp.getOrg());
+ assertArrayEquals(sp.toByteArray(), PROTO_DEFAULT);
+ }
+
+ @Test
+ public void testValid3gppId() {
+ for (int i = 0; i < PROTO_3GPP_PLAIN_ID.length; i++) {
+ UaSecurityProtocolIdentifier sp = testCreate3GppSpId(
+ PROTO_3GPP_PLAIN_ID[i], null, false);
+ assertNotNull(sp);
+ assertEquals(UaSecurityProtocolIdentifier.ORG_3GPP, sp.getOrg());
+ assertEquals(PROTO_3GPP_PLAIN_ID[i], sp.getProtocol());
+ assertEquals(0, sp.getTlsCipherSuite());
+ assertArrayEquals(sp.toByteArray(), PROTO_3GPP_PLAIN[i]);
+ }
+ }
+
+ @Test
+ public void testValid3gppIdWithTls() {
+ for (int i = 0; i < PROTO_3GPP_TLS_ID.length; i++) {
+ for (int j = 0; j < TLS_CS_ID_SUPPORTED.length; j++) {
+ UaSecurityProtocolIdentifier sp = testCreate3GppSpId(
+ PROTO_3GPP_TLS_ID[i], TLS_CS_ID_SUPPORTED[j], false);
+ assertNotNull(sp);
+ assertEquals(UaSecurityProtocolIdentifier.ORG_3GPP, sp.getOrg());
+ assertEquals(PROTO_3GPP_TLS_ID[i], sp.getProtocol());
+ assertEquals(TLS_CS_ID_SUPPORTED[j], sp.getTlsCipherSuite());
+ byte[] targetData = new byte[PROTO_SIZE];
+ ByteBuffer buf = ByteBuffer.wrap(targetData);
+ buf.put(PROTO_3GPP_TLS[i]);
+ buf.putShort(PROTO_SIZE - 2, (short) TLS_CS_ID_SUPPORTED[j]);
+ assertArrayEquals(targetData, sp.toByteArray());
+ }
+ }
+ }
+
+ @Test
+ public void testInvalidId() {
+ Random rand = new Random();
+ HashSet<Integer> validIds = new HashSet<>();
+ for (int id : PROTO_3GPP_PLAIN_ID) {
+ validIds.add(id);
+ }
+ for (int id : PROTO_3GPP_TLS_ID) {
+ validIds.add(id);
+ }
+ for (int i = 0; i < 200; i++) {
+ int r = rand.nextInt();
+ UaSecurityProtocolIdentifier sp = testCreate3GppSpId(
+ r, TlsParams.TLS_NULL_WITH_NULL_NULL, !validIds.contains(r));
+ }
+ }
+
+ @Test
+ public void testInvalid3gppIdWithTls() {
+ Random rand = new Random();
+ for (int i = 0; i < PROTO_3GPP_TLS_ID.length; i++) {
+ for (int j = 0; j < 200; j++) {
+ int r = rand.nextInt(Integer.MAX_VALUE);
+ int index = Arrays.binarySearch(TLS_CS_ID_SUPPORTED, r);
+ boolean isFailExpected = index < 0;
+ UaSecurityProtocolIdentifier sp = testCreate3GppSpId(
+ PROTO_3GPP_TLS_ID[i], r, isFailExpected);
+ }
+ }
+ }
+
+ @Test
+ public void testParcelUnparcel() {
+ UaSecurityProtocolIdentifier sp = testCreate3GppSpId(
+ PROTO_3GPP_TLS_ID[0], TLS_CS_ID_SUPPORTED[0], false);
+ Parcel parcel = Parcel.obtain();
+ sp.writeToParcel(parcel, 0);
+ parcel.setDataPosition(0);
+ UaSecurityProtocolIdentifier sp2 =
+ UaSecurityProtocolIdentifier.CREATOR.createFromParcel(parcel);
+ parcel.recycle();
+ assertTrue(sp.equals(sp2));
+ }
+
+ @Test
+ public void testIsTlsCipherSuiteSupported() {
+ Random rand = new Random();
+
+ for (int i = 0; i < TLS_CS_ID_SUPPORTED.length; i++) {
+ assertTrue(TlsParams.isTlsCipherSuiteSupported(TLS_CS_ID_SUPPORTED[i]));
+ }
+
+ for (int i = 0; i < 100; i++) {
+ int val = rand.nextInt();
+ if (Arrays.binarySearch(TLS_CS_ID_SUPPORTED, val) < 0) {
+ assertFalse(TlsParams.isTlsCipherSuiteSupported(val));
+ }
+ }
+ }
+
+ private UaSecurityProtocolIdentifier testCreate3GppSpId(
+ Integer id, Integer cs, boolean nullExpected) {
+ boolean isFail = false;
+ UaSecurityProtocolIdentifier sp = null;
+ UaSecurityProtocolIdentifier.Builder builder = new UaSecurityProtocolIdentifier.Builder();
+ builder.setOrg(UaSecurityProtocolIdentifier.ORG_3GPP);
+ try {
+ if (id != null) {
+ builder.setProtocol(id);
+ }
+ if (cs != null) {
+ builder.setTlsCipherSuite(cs);
+ }
+ sp = builder.build();
+ } catch (IllegalArgumentException e) {
+ }
+ if (nullExpected) {
+ assertNull(sp);
+ } else {
+ assertNotNull(sp);
+ }
+ return sp;
+ }
+
+ private String getRandomString(Random rand) {
+ int size = rand.nextInt(64);
+ byte[] arr = new byte[size];
+ rand.nextBytes(arr);
+ return new String(arr);
+ }
+}
diff --git a/tests/tests/telephony/current/src/android/telephony/ims/cts/ImsUtils.java b/tests/tests/telephony/current/src/android/telephony/ims/cts/ImsUtils.java
index e691e51..bf45867 100644
--- a/tests/tests/telephony/current/src/android/telephony/ims/cts/ImsUtils.java
+++ b/tests/tests/telephony/current/src/android/telephony/ims/cts/ImsUtils.java
@@ -46,6 +46,7 @@
public static final int ITEM_COMPRESSED = 2001;
// TODO Replace with a real sip message once that logic is in.
public static final String TEST_TRANSACTION_ID = "z9hG4bK.TeSt";
+ public static final String TEST_CALL_ID = "testcall";
public static final SipMessage TEST_SIP_MESSAGE = new SipMessage("A", "B", new byte[0]);
public static boolean shouldTestTelephony() {
diff --git a/tests/tests/telephony/current/src/android/telephony/ims/cts/SipDelegateManagerTest.java b/tests/tests/telephony/current/src/android/telephony/ims/cts/SipDelegateManagerTest.java
index 3f786fa..c0f2e6b 100644
--- a/tests/tests/telephony/current/src/android/telephony/ims/cts/SipDelegateManagerTest.java
+++ b/tests/tests/telephony/current/src/android/telephony/ims/cts/SipDelegateManagerTest.java
@@ -832,6 +832,8 @@
// Send a message and ensure it gets received on the other end as well as acked
delegateConn.sendMessageAndVerifyCompletedSuccessfully(ImsUtils.TEST_SIP_MESSAGE);
delegate.verifyMessageSend(ImsUtils.TEST_SIP_MESSAGE);
+ delegateConn.sendCloseDialog(ImsUtils.TEST_CALL_ID);
+ delegate.verifyCloseDialog(ImsUtils.TEST_CALL_ID);
// send a message and notify connection that it failed
delegate.setSendMessageDenyReason(
SipDelegateManager.MESSAGE_FAILURE_REASON_NETWORK_NOT_AVAILABLE);
diff --git a/tests/tests/telephony/current/src/android/telephony/ims/cts/TestSipDelegate.java b/tests/tests/telephony/current/src/android/telephony/ims/cts/TestSipDelegate.java
index 3d06dce..729efb9 100644
--- a/tests/tests/telephony/current/src/android/telephony/ims/cts/TestSipDelegate.java
+++ b/tests/tests/telephony/current/src/android/telephony/ims/cts/TestSipDelegate.java
@@ -48,6 +48,7 @@
// Pair is <transactionId, error reason>
private final LinkedBlockingQueue<Pair<String, Integer>> mReceivedMessageAcks =
new LinkedBlockingQueue<>();
+ private final LinkedBlockingQueue<String> mCloseDialogRequests = new LinkedBlockingQueue<>();
private int mSendMessageDenyReason = -1;
public TestSipDelegate(int sub, DelegateRequest request, DelegateStateCallback cb,
@@ -73,7 +74,7 @@
@Override
public void closeDialog(@NonNull String callId) {
if (ImsUtils.VDBG) Log.d(LOG_TAG, "closeDialog");
- // TODO: Test once dialogs are tracked in AOSP.
+ mCloseDialogRequests.offer(callId);
}
@Override
@@ -93,6 +94,12 @@
assertEquals(messageToVerify, m);
}
+ public void verifyCloseDialog(String callIdToVerify) throws Exception {
+ String requestedCallId = mCloseDialogRequests.poll(ImsUtils.TEST_TIMEOUT_MS,
+ TimeUnit.MILLISECONDS);
+ assertEquals(callIdToVerify, requestedCallId);
+ }
+
public void setSendMessageDenyReason(int reason) {
mSendMessageDenyReason = reason;
}
diff --git a/tests/tests/telephony/current/src/android/telephony/ims/cts/TestSipDelegateConnection.java b/tests/tests/telephony/current/src/android/telephony/ims/cts/TestSipDelegateConnection.java
index 6b3b134..adf4956 100644
--- a/tests/tests/telephony/current/src/android/telephony/ims/cts/TestSipDelegateConnection.java
+++ b/tests/tests/telephony/current/src/android/telephony/ims/cts/TestSipDelegateConnection.java
@@ -145,6 +145,11 @@
mLatch.countDown();
}
+ public void sendCloseDialog(String callId) {
+ assertNotNull("SipDelegate was null when closing dialog", connection);
+ connection.closeDialog(callId);
+ }
+
public void sendMessageAndVerifyCompletedSuccessfully(SipMessage messageToSend)
throws Exception {
assertNotNull("SipDelegate was null when sending message", connection);