diff options
author | Android Build Coastguard Worker <android-build-coastguard-worker@google.com> | 2022-05-12 18:53:10 +0000 |
---|---|---|
committer | Gerrit Code Review <noreply-gerritcodereview@google.com> | 2022-05-12 18:53:10 +0000 |
commit | b6dc9fab0f7d4aca206bc81bf5e6d144345d2fba (patch) | |
tree | 80fcf05cee350dc3641e9ba3d0796900470c5a74 | |
parent | 47da14e9f38c232c10ce4c5c7042182ca410d527 (diff) | |
parent | 27784407a1b98e0628485004797b32073f6d020e (diff) | |
download | cts-main-cg-testing-release.tar.gz |
Merge "Snap for 8580505 from cc61dc91e9875dddbab3ff123ab571e7d50bfbc5 to main-cg-testing-release" into main-cg-testing-releasemain-cg-testing-release
57 files changed, 2764 insertions, 411 deletions
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/bluetooth/BleAdvertisingSetTestActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/bluetooth/BleAdvertisingSetTestActivity.java index e02b1221ad6..7411575b72e 100644 --- a/apps/CtsVerifier/src/com/android/cts/verifier/bluetooth/BleAdvertisingSetTestActivity.java +++ b/apps/CtsVerifier/src/com/android/cts/verifier/bluetooth/BleAdvertisingSetTestActivity.java @@ -117,16 +117,15 @@ public class BleAdvertisingSetTestActivity extends PassFailButtons.Activity { @Override public void run() { if (!mBluetoothAdapter.isEnabled()) { - assertTrue(BtAdapterUtils.enableAdapter(mBluetoothAdapter, - BleAdvertisingSetTestActivity.this)); // If BluetoothAdapter was previously not enabled, we need to get the // BluetoothLeAdvertiser instance again. + mBluetoothAdapter.enable(); mAdvertiser = mBluetoothAdapter.getBluetoothLeAdvertiser(); } try { startAdvertisingSet(); - testEnableAndDisableAdvertising(); + testDisableAndEnableAdvertising(); testSetAdvertisingData(); testSetAdvertisingParameters(); testPeriodicAdvertising(); @@ -139,8 +138,7 @@ public class BleAdvertisingSetTestActivity extends PassFailButtons.Activity { } // Disable bluetooth adapter - assertTrue(BtAdapterUtils.disableAdapter(mBluetoothAdapter, - BleAdvertisingSetTestActivity.this)); + mBluetoothAdapter.disable(); BleAdvertisingSetTestActivity.this.runOnUiThread(new Runnable() { @Override @@ -182,19 +180,19 @@ public class BleAdvertisingSetTestActivity extends PassFailButtons.Activity { mTestAdapter.setTestPass(TEST_ADAPTER_INDEX_START); } - private void testEnableAndDisableAdvertising() throws InterruptedException { + private void testDisableAndEnableAdvertising() throws InterruptedException { mCallback.reset(); - mCallback.mAdvertisingSet.get().enableAdvertising(/* enable= */ true, /* duration= */ 1, - /* maxExtendedAdvertisingEvents= */ 1); - assertTrue(mCallback.mAdvertisingEnabledLatch.await(TIMEOUT_MS, TimeUnit.MILLISECONDS)); - assertEquals(ADVERTISE_SUCCESS, mCallback.mAdvertisingEnabledStatus.get()); - mCallback.mAdvertisingSet.get().enableAdvertising(/* enable= */ false, /* duration= */ 1, /* maxExtendedAdvertisingEvents= */ 1); assertTrue(mCallback.mAdvertisingDisabledLatch.await(TIMEOUT_MS, TimeUnit.MILLISECONDS)); assertEquals(ADVERTISE_SUCCESS, mCallback.mAdvertisingDisabledStatus.get()); + mCallback.mAdvertisingSet.get().enableAdvertising(/* enable= */ true, /* duration= */ 1, + /* maxExtendedAdvertisingEvents= */ 1); + assertTrue(mCallback.mAdvertisingEnabledLatch.await(TIMEOUT_MS, TimeUnit.MILLISECONDS)); + assertEquals(ADVERTISE_SUCCESS, mCallback.mAdvertisingEnabledStatus.get()); + mAllTestsPassed |= PASS_FLAG_ENABLE_DISABLE; mTestAdapter.setTestPass(TEST_ADAPTER_INDEX_ENABLE_DISABLE); } @@ -225,7 +223,7 @@ public class BleAdvertisingSetTestActivity extends PassFailButtons.Activity { mCallback.reset(); mCallback.mAdvertisingSet.get().enableAdvertising(false, /* duration= */ 1, - /* maxExtendedAdvertisingEvents= */1); + /* maxExtendedAdvertisingEvents= */ 1); assertTrue(mCallback.mAdvertisingDisabledLatch.await(TIMEOUT_MS, TimeUnit.MILLISECONDS)); assertEquals(ADVERTISE_SUCCESS, mCallback.mAdvertisingDisabledStatus.get()); @@ -253,6 +251,11 @@ public class BleAdvertisingSetTestActivity extends PassFailButtons.Activity { TimeUnit.MILLISECONDS)); assertEquals(ADVERTISE_SUCCESS, mCallback.mAdvertisingParametersUpdatedStatus.get()); + // Let's make sure we disable periodic advertising + mCallback.mAdvertisingSet.get().setPeriodicAdvertisingEnabled(false); + assertTrue(mCallback.mPeriodicAdvertisingDisabledLatch.await(TIMEOUT_MS, + TimeUnit.MILLISECONDS)); + assertEquals(ADVERTISE_SUCCESS, mCallback.mPeriodicAdvertisingDisabledStatus.get()); mCallback.mAdvertisingSet.get().setPeriodicAdvertisingParameters( new PeriodicAdvertisingParameters.Builder().build()); assertTrue(mCallback.mPeriodicAdvertisingParamsUpdatedLatch.await(TIMEOUT_MS, @@ -282,6 +285,7 @@ public class BleAdvertisingSetTestActivity extends PassFailButtons.Activity { assertEquals(ADVERTISE_SUCCESS, mCallback.mPeriodicAdvertisingDisabledStatus.get()); mAllTestsPassed |= PASS_FLAG_SET_PERIODIC_ADVERTISING_ENABLED_DISABLED; + mTestAdapter.setTestPass(TEST_ADAPTER_INDEX_SET_PERIODIC_ADVERTISING_ENABLED_DISABLED); } 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 795028ef497..e57d620b821 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 @@ -16,31 +16,15 @@ package com.android.cts.verifier.nfc.offhost; -import android.annotation.TargetApi; -import android.app.Activity; -import android.app.AlertDialog; -import android.app.ProgressDialog; -import android.content.BroadcastReceiver; -import android.content.ComponentName; import android.content.Context; -import android.content.DialogInterface; import android.content.Intent; -import android.content.IntentFilter; 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; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; - import com.android.cts.verifier.PassFailButtons; import com.android.cts.verifier.R; - import com.android.cts.verifier.nfc.hce.HceUtils; public class UiccTransactionEvent1EmulatorActivity extends PassFailButtons.Activity { @@ -106,9 +90,9 @@ public class UiccTransactionEvent1EmulatorActivity extends PassFailButtons.Activ private void initProcess() { Bundle bundle = getIntent().getExtras(); - if(bundle != null){ + if (bundle != null && getIntent().getAction() != null) { byte[] transactionData = bundle.getByteArray(NfcAdapter.EXTRA_DATA); - if(transactionData != null){ + if (transactionData != null) { runOnUiThread(new Runnable() { @Override public void run() { 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 34a418bcc13..3f914c1f121 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 @@ -16,31 +16,15 @@ package com.android.cts.verifier.nfc.offhost; -import android.annotation.TargetApi; -import android.app.Activity; -import android.app.AlertDialog; -import android.app.ProgressDialog; -import android.content.BroadcastReceiver; -import android.content.ComponentName; import android.content.Context; -import android.content.DialogInterface; import android.content.Intent; -import android.content.IntentFilter; 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; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; - import com.android.cts.verifier.PassFailButtons; import com.android.cts.verifier.R; - import com.android.cts.verifier.nfc.hce.HceUtils; public class UiccTransactionEvent2EmulatorActivity extends PassFailButtons.Activity { @@ -106,9 +90,9 @@ public class UiccTransactionEvent2EmulatorActivity extends PassFailButtons.Activ private void initProcess() { Bundle bundle = getIntent().getExtras(); - if(bundle != null){ + if (bundle != null && getIntent().getAction() != null) { byte[] transactionData = bundle.getByteArray(NfcAdapter.EXTRA_DATA); - if(transactionData != null){ + if (transactionData != null) { runOnUiThread(new Runnable() { @Override public void run() { 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 6055ac4ef32..09c13b8cbdb 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 @@ -16,31 +16,15 @@ package com.android.cts.verifier.nfc.offhost; -import android.annotation.TargetApi; -import android.app.Activity; -import android.app.AlertDialog; -import android.app.ProgressDialog; -import android.content.BroadcastReceiver; -import android.content.ComponentName; import android.content.Context; -import android.content.DialogInterface; import android.content.Intent; -import android.content.IntentFilter; 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; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; - import com.android.cts.verifier.PassFailButtons; import com.android.cts.verifier.R; - import com.android.cts.verifier.nfc.hce.HceUtils; public class UiccTransactionEvent3EmulatorActivity extends PassFailButtons.Activity { @@ -105,9 +89,9 @@ public class UiccTransactionEvent3EmulatorActivity extends PassFailButtons.Activ private void initProcess() { Bundle bundle = getIntent().getExtras(); - if(bundle != null){ + if (bundle != null && getIntent().getAction() != null) { byte[] transactionData = bundle.getByteArray(NfcAdapter.EXTRA_DATA); - if(transactionData != null){ + if (transactionData != null) { runOnUiThread(new Runnable() { @Override public void run() { diff --git a/hostsidetests/neuralnetworks/app/src/com/android/nn/stats/app/NnapiDeviceActivity.java b/hostsidetests/neuralnetworks/app/src/com/android/nn/stats/app/NnapiDeviceActivity.java index e372fb92c5f..7dc401598ee 100644 --- a/hostsidetests/neuralnetworks/app/src/com/android/nn/stats/app/NnapiDeviceActivity.java +++ b/hostsidetests/neuralnetworks/app/src/com/android/nn/stats/app/NnapiDeviceActivity.java @@ -21,7 +21,7 @@ import android.os.Bundle; import android.util.Log; /** - * A simple activity which triggers libneuralnetworks.so to push WestWorld atoms. + * A simple activity which triggers libneuralnetworks.so to push statsd atoms. */ public class NnapiDeviceActivity extends Activity { private static final String TAG = NnapiDeviceActivity.class.getSimpleName(); @@ -33,7 +33,7 @@ public class NnapiDeviceActivity extends Activity { @Override public void onCreate(Bundle icicle) { super.onCreate(icicle); - Log.i(TAG, "Triggering libneuralnetworks.so to push WestWorld atoms."); + Log.i(TAG, "Triggering libneuralnetworks.so to push statsd atoms."); trigger_libneuralnetworks_atoms(); } diff --git a/hostsidetests/packagemanager/dynamicmime/src/android/dynamicmime/cts/RebootTestCases.java b/hostsidetests/packagemanager/dynamicmime/src/android/dynamicmime/cts/RebootTestCases.java index a26de84bdf1..d6fb65e3d1c 100644 --- a/hostsidetests/packagemanager/dynamicmime/src/android/dynamicmime/cts/RebootTestCases.java +++ b/hostsidetests/packagemanager/dynamicmime/src/android/dynamicmime/cts/RebootTestCases.java @@ -40,6 +40,8 @@ public class RebootTestCases extends BaseHostJUnit4Test { private static final String PACKAGE_TEST_APP = "android.dynamicmime.testapp"; private static final String PACKAGE_REBOOT_TESTS = PACKAGE_TEST_APP + ".reboot"; + private static final int SETTINGS_WRITE_TIMEOUT_MS = 10_000; + @Test public void testGroupWithExactType() throws DeviceNotAvailableException { runTestWithReboot("SingleAppTest", "testGroupWithExactType"); @@ -213,6 +215,7 @@ public class RebootTestCases extends BaseHostJUnit4Test { private void runTestWithReboot(String testClassName, String testMethodName) throws DeviceNotAvailableException { runPreReboot(testClassName, testMethodName); + waitForSettingsWrite(); getDevice().reboot(); runPostReboot(testClassName, testMethodName); } @@ -223,6 +226,13 @@ public class RebootTestCases extends BaseHostJUnit4Test { testMethodName); } + private void waitForSettingsWrite() { + try { + Thread.sleep(SETTINGS_WRITE_TIMEOUT_MS); + } catch (InterruptedException ignored) { + } + } + private void runPreReboot(String testClassName, String testMethodName) throws DeviceNotAvailableException { runDeviceTests(PACKAGE_TEST_APP, PACKAGE_REBOOT_TESTS + ".PreReboot" + testClassName, diff --git a/hostsidetests/packagemanager/dynamicmime/test/Android.bp b/hostsidetests/packagemanager/dynamicmime/test/Android.bp index fb63a62b732..19bf6066a72 100644 --- a/hostsidetests/packagemanager/dynamicmime/test/Android.bp +++ b/hostsidetests/packagemanager/dynamicmime/test/Android.bp @@ -33,5 +33,4 @@ android_test_helper_app { "general-tests", ], sdk_version: "test_current", - platform_apis: true, } diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2021-0921/Android.bp b/hostsidetests/securitybulletin/test-apps/CVE-2021-0921/Android.bp index f0ab82b41ad..e7cd5548d0d 100644 --- a/hostsidetests/securitybulletin/test-apps/CVE-2021-0921/Android.bp +++ b/hostsidetests/securitybulletin/test-apps/CVE-2021-0921/Android.bp @@ -20,7 +20,6 @@ android_test_helper_app { name: "CVE-2021-0921", defaults: ["cts_support_defaults"], srcs: ["src/**/*.java"], - platform_apis: true, test_suites: [ "cts", "vts10", diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2021-0928/Android.bp b/hostsidetests/securitybulletin/test-apps/CVE-2021-0928/Android.bp index 67b3b0215c0..3ba129b85eb 100644 --- a/hostsidetests/securitybulletin/test-apps/CVE-2021-0928/Android.bp +++ b/hostsidetests/securitybulletin/test-apps/CVE-2021-0928/Android.bp @@ -20,7 +20,6 @@ android_test_helper_app { name: "CVE-2021-0928", defaults: ["cts_support_defaults"], srcs: ["src/**/*.java"], - platform_apis: true, test_suites: [ "cts", "vts10", diff --git a/hostsidetests/statsdatom/Android.bp b/hostsidetests/statsdatom/Android.bp index 6f2da5f503f..62842def2f9 100644 --- a/hostsidetests/statsdatom/Android.bp +++ b/hostsidetests/statsdatom/Android.bp @@ -72,7 +72,11 @@ java_test_host { data: [ ":CtsStatsdAtomApp", ":CtsStatsdApp", //TODO(b/163546661): Remove once migration to new lib is complete. - ] + ":CtsAppExitTestCases", + ":CtsExternalServiceService", + ":CtsSimpleApp", + ], + per_testcase_directory: true, } java_library_host { diff --git a/tests/app/NotificationListener/Android.bp b/tests/app/NotificationListener/Android.bp index 4c43e373ac1..adfa03df8fc 100644 --- a/tests/app/NotificationListener/Android.bp +++ b/tests/app/NotificationListener/Android.bp @@ -39,6 +39,5 @@ android_test_helper_app { "androidx.test.rules", "platform-test-annotations", ], - platform_apis: true, sdk_version: "test_current", } diff --git a/tests/app/NotificationProvider/Android.bp b/tests/app/NotificationProvider/Android.bp index 4a9d084472c..a0c6396f17e 100644 --- a/tests/app/NotificationProvider/Android.bp +++ b/tests/app/NotificationProvider/Android.bp @@ -19,7 +19,10 @@ package { android_test_helper_app { name: "NotificationProvider", defaults: ["cts_support_defaults"], - srcs: ["**/*.java", "**/*.kt"], + srcs: [ + "**/*.java", + "**/*.kt", + ], // Tag this module as a cts test artifact test_suites: [ "cts", @@ -27,6 +30,5 @@ android_test_helper_app { "general-tests", "sts", ], - platform_apis: true, sdk_version: "current", } 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 8360e97cf1a..5a7cbdd6061 100644 --- a/tests/framework/base/windowmanager/src/android/server/wm/AppConfigurationTests.java +++ b/tests/framework/base/windowmanager/src/android/server/wm/AppConfigurationTests.java @@ -58,7 +58,6 @@ import static org.junit.Assume.assumeTrue; import android.app.Activity; import android.content.ComponentName; import android.content.Context; -import android.content.res.Resources; import android.graphics.Point; import android.graphics.Rect; import android.hardware.display.DisplayManager; @@ -69,7 +68,6 @@ import android.server.wm.CommandSession.ActivitySessionClient; import android.server.wm.CommandSession.ConfigInfo; import android.server.wm.CommandSession.SizeInfo; import android.server.wm.TestJournalProvider.TestJournalContainer; -import android.util.DisplayMetrics; import android.view.Display; import android.window.WindowContainerTransaction; @@ -475,6 +473,7 @@ public class AppConfigurationTests extends MultiDisplayTestBase { // Start a portrait activity first to ensure that the orientation will change. launchActivity(PORTRAIT_ORIENTATION_ACTIVITY); mWmState.waitForLastOrientation(SCREEN_ORIENTATION_PORTRAIT); + final int prevRotation = mWmState.getRotation(); getLaunchActivityBuilder() .setUseInstrumentation() @@ -499,34 +498,35 @@ public class AppConfigurationTests extends MultiDisplayTestBase { assertEquals("The last reported size should be the same as the one from onCreate", reportedSizes, onCreateConfigInfo.sizeInfo); - final Display display = mDm.getDisplay(Display.DEFAULT_DISPLAY); - final Point expectedRealDisplaySize = new Point(); - display.getRealSize(expectedRealDisplaySize); + final WindowManagerState.DisplayContent dc = mWmState.getDisplay(Display.DEFAULT_DISPLAY); + final Point realDisplaySize = + new Point(dc.getDisplayRect().width(), dc.getDisplayRect().height()); + final int currentRotation = mWmState.getRotation(); + // Some devices may launch the activity in a letterboxed area so the display won't rotate. + final boolean displayRotationChanged = prevRotation != currentRotation; - final int expectedRotation = display.getRotation(); assertEquals("The activity should get the final display rotation in onCreate", - expectedRotation, onCreateConfigInfo.rotation); + currentRotation, onCreateConfigInfo.rotation); assertEquals("The application should get the final display rotation in onCreate", - expectedRotation, appConfigInfo.rotation); + currentRotation, appConfigInfo.rotation); assertEquals("The orientation of application must be landscape", ORIENTATION_LANDSCAPE, appConfigInfo.sizeInfo.orientation); assertEquals("The orientation of system resources must be landscape", ORIENTATION_LANDSCAPE, globalSizeInfo.orientation); - assertEquals("The activity should get the final display size in onCreate", - expectedRealDisplaySize, onCreateRealDisplaySize); - final boolean isLandscape = expectedRealDisplaySize.x > expectedRealDisplaySize.y; - assertEquals("The app size of activity should have the same orientation", isLandscape, - onCreateSize.displayWidth > onCreateSize.displayHeight); + final boolean isLandscape = onCreateSize.displayWidth > onCreateSize.displayHeight; + if (displayRotationChanged) { + assertEquals("The activity should get the final display size in onCreate", + realDisplaySize, onCreateRealDisplaySize); + assertEquals("The app size of activity should have the same orientation", isLandscape, + realDisplaySize.x > realDisplaySize.y); + assertEquals("The display metrics of system resources must be landscape", isLandscape, + globalSizeInfo.metricsWidth > globalSizeInfo.metricsHeight); + } assertEquals("The application should get the same orientation", isLandscape, appConfigInfo.sizeInfo.displayWidth > appConfigInfo.sizeInfo.displayHeight); assertEquals("The app display metrics must be landscape", isLandscape, appConfigInfo.sizeInfo.metricsWidth > appConfigInfo.sizeInfo.metricsHeight); - - final DisplayMetrics globalMetrics = Resources.getSystem().getDisplayMetrics(); - assertEquals("The display metrics of system resources must be landscape", - new Point(globalMetrics.widthPixels, globalMetrics.heightPixels), - new Point(globalSizeInfo.metricsWidth, globalSizeInfo.metricsHeight)); } @Test diff --git a/tests/framework/base/windowmanager/src/android/server/wm/AspectRatioTestsBase.java b/tests/framework/base/windowmanager/src/android/server/wm/AspectRatioTestsBase.java index 96cf5c219fc..e032a10031f 100644 --- a/tests/framework/base/windowmanager/src/android/server/wm/AspectRatioTestsBase.java +++ b/tests/framework/base/windowmanager/src/android/server/wm/AspectRatioTestsBase.java @@ -25,6 +25,7 @@ import android.app.Activity; import android.content.ComponentName; import android.graphics.Point; import android.graphics.Rect; +import android.server.wm.WindowManagerState.DisplayArea; import android.view.Display; import android.view.WindowManager; @@ -97,10 +98,8 @@ class AspectRatioTestsBase extends ActivityManagerTestBase { } float getDisplayAspectRatio(ComponentName componentName) { - final int displayId = mWmState.getDisplayByActivity(componentName); - final WindowManagerState.DisplayContent display = mWmState.getDisplay(displayId); - - final Rect appRect = display.getAppRect(); + final DisplayArea tda = mWmState.getTaskDisplayArea(componentName); + final Rect appRect = tda.getAppBounds(); final int shortSide = Math.min(appRect.width(), appRect.height()); final int longSide = Math.max(appRect.width(), appRect.height()); return (float) longSide / (float) shortSide; diff --git a/tests/framework/base/windowmanager/src/android/server/wm/BlurTests.java b/tests/framework/base/windowmanager/src/android/server/wm/BlurTests.java index 23e47c2a87d..42efd623ef0 100644 --- a/tests/framework/base/windowmanager/src/android/server/wm/BlurTests.java +++ b/tests/framework/base/windowmanager/src/android/server/wm/BlurTests.java @@ -73,6 +73,7 @@ public class BlurTests extends WindowManagerTestBase { private static final int DISABLE_BLUR_BROADCAST_WAIT_TIME = 100; private float mSavedAnimatorDurationScale; private boolean mSavedWindowBlurDisabledSetting; + private Rect mSavedActivityBounds; @Before public void setUp() { @@ -87,7 +88,13 @@ public class BlurTests extends WindowManagerTestBase { Settings.Global.getFloat(resolver, ANIMATOR_DURATION_SCALE, 1f); Settings.Global.putFloat(resolver, ANIMATOR_DURATION_SCALE, 0); }); - startTestActivity(BACKGROUND_IMAGE_ACTIVITY); + + // Use the background activity's bounds when taking the device screenshot. + // This is needed for multi-screen devices (foldables) where + // the launched activity covers just one screen + WindowManagerState.Activity act = startAndReturnTestActivity(BACKGROUND_IMAGE_ACTIVITY); + mSavedActivityBounds = act.getBounds(); + verifyOnlyBackgroundImageVisible(); assertTrue(mContext.getSystemService(WindowManager.class).isCrossWindowBlurEnabled()); } @@ -109,7 +116,7 @@ public class BlurTests extends WindowManagerTestBase { extraInt(EXTRA_BACKGROUND_BLUR_RADIUS_PX, BACKGROUND_BLUR_PX)); final Rect windowFrame = getWindowFrame(BLUR_ACTIVITY); - assertBackgroundBlur(takeScreenshot(), windowFrame); + assertBackgroundBlur(takeScreenshotForBounds(mSavedActivityBounds), windowFrame); } @Test @@ -118,7 +125,7 @@ public class BlurTests extends WindowManagerTestBase { extraInt(EXTRA_BLUR_BEHIND_RADIUS_PX, BLUR_BEHIND_PX), extraInt(EXTRA_NO_BLUR_BACKGROUND_COLOR, NO_BLUR_BACKGROUND_COLOR)); - final Bitmap screenshot = takeScreenshot(); + final Bitmap screenshot = takeScreenshotForBounds(mSavedActivityBounds); final Rect windowFrame = getWindowFrame(BLUR_ACTIVITY); assertBlurBehind(screenshot, windowFrame); assertNoBackgroundBlur(screenshot, windowFrame); @@ -165,22 +172,22 @@ public class BlurTests extends WindowManagerTestBase { extraInt(EXTRA_NO_BLUR_BACKGROUND_COLOR, NO_BLUR_BACKGROUND_COLOR)); final Rect windowFrame = getWindowFrame(BLUR_ACTIVITY); - Bitmap screenshot = takeScreenshot(); - assertBackgroundBlur(takeScreenshot(), windowFrame); + Bitmap screenshot = takeScreenshotForBounds(mSavedActivityBounds); + assertBackgroundBlur(takeScreenshotForBounds(mSavedActivityBounds), windowFrame); assertNoBlurBehind(screenshot, windowFrame); setForceBlurDisabled(true); Thread.sleep(BACKGROUND_BLUR_DYNAMIC_UPDATE_WAIT_TIME); - screenshot = takeScreenshot(); + screenshot = takeScreenshotForBounds(mSavedActivityBounds); assertNoBackgroundBlur(screenshot, windowFrame); assertNoBlurBehind(screenshot, windowFrame); setForceBlurDisabled(false); Thread.sleep(BACKGROUND_BLUR_DYNAMIC_UPDATE_WAIT_TIME); - screenshot = takeScreenshot(); - assertBackgroundBlur(takeScreenshot(), windowFrame); + screenshot = takeScreenshotForBounds(mSavedActivityBounds); + assertBackgroundBlur(takeScreenshotForBounds(mSavedActivityBounds), windowFrame); assertNoBlurBehind(screenshot, windowFrame); } @@ -191,21 +198,21 @@ public class BlurTests extends WindowManagerTestBase { extraInt(EXTRA_NO_BLUR_BACKGROUND_COLOR, NO_BLUR_BACKGROUND_COLOR)); final Rect windowFrame = getWindowFrame(BLUR_ACTIVITY); - Bitmap screenshot = takeScreenshot(); + Bitmap screenshot = takeScreenshotForBounds(mSavedActivityBounds); assertBlurBehind(screenshot, windowFrame); assertNoBackgroundBlur(screenshot, windowFrame); setForceBlurDisabled(true); Thread.sleep(BLUR_BEHIND_DYNAMIC_UPDATE_WAIT_TIME); - screenshot = takeScreenshot(); + screenshot = takeScreenshotForBounds(mSavedActivityBounds); assertNoBackgroundBlur(screenshot, windowFrame); assertNoBlurBehind(screenshot, windowFrame); setForceBlurDisabled(false); Thread.sleep(BLUR_BEHIND_DYNAMIC_UPDATE_WAIT_TIME); - screenshot = takeScreenshot(); + screenshot = takeScreenshotForBounds(mSavedActivityBounds); assertBlurBehind(screenshot, windowFrame); assertNoBackgroundBlur(screenshot, windowFrame); } @@ -218,21 +225,21 @@ public class BlurTests extends WindowManagerTestBase { extraInt(EXTRA_BACKGROUND_BLUR_RADIUS_PX, BACKGROUND_BLUR_PX)); final Rect windowFrame = getWindowFrame(BLUR_ACTIVITY); - Bitmap screenshot = takeScreenshot(); + Bitmap screenshot = takeScreenshotForBounds(mSavedActivityBounds); assertBlurBehind(screenshot, windowFrame); assertBackgroundBlurOverBlurBehind(screenshot, windowFrame); setForceBlurDisabled(true); Thread.sleep(BLUR_BEHIND_DYNAMIC_UPDATE_WAIT_TIME); - screenshot = takeScreenshot(); + screenshot = takeScreenshotForBounds(mSavedActivityBounds); assertNoBackgroundBlur(screenshot, windowFrame); assertNoBlurBehind(screenshot, windowFrame); setForceBlurDisabled(false); Thread.sleep(BLUR_BEHIND_DYNAMIC_UPDATE_WAIT_TIME); - screenshot = takeScreenshot(); + screenshot = takeScreenshotForBounds(mSavedActivityBounds); assertBlurBehind(screenshot, windowFrame); assertBackgroundBlurOverBlurBehind(screenshot, windowFrame); } @@ -241,7 +248,7 @@ public class BlurTests extends WindowManagerTestBase { public void testBlurBehindAndBackgroundBlurSetWithAttributes() { startTestActivity(BLUR_ATTRIBUTES_ACTIVITY); final Rect windowFrame = getWindowFrame(BLUR_ATTRIBUTES_ACTIVITY); - final Bitmap screenshot = takeScreenshot(); + final Bitmap screenshot = takeScreenshotForBounds(mSavedActivityBounds); assertBlurBehind(screenshot, windowFrame); assertBackgroundBlurOverBlurBehind(screenshot, windowFrame); @@ -254,7 +261,7 @@ public class BlurTests extends WindowManagerTestBase { extraInt(EXTRA_NO_BLUR_BACKGROUND_COLOR, NO_BLUR_BACKGROUND_COLOR), extraInt(EXTRA_BACKGROUND_BLUR_RADIUS_PX, BACKGROUND_BLUR_PX)); final Rect windowFrame = getWindowFrame(BLUR_ACTIVITY); - Bitmap screenshot = takeScreenshot(); + Bitmap screenshot = takeScreenshotForBounds(mSavedActivityBounds); assertBlurBehind(screenshot, windowFrame); assertBackgroundBlurOverBlurBehind(screenshot, windowFrame); @@ -326,6 +333,15 @@ public class BlurTests extends WindowManagerTestBase { mWmState.waitForAppTransitionIdleOnDisplay(DEFAULT_DISPLAY); } + private WindowManagerState.Activity startAndReturnTestActivity(ComponentName activityName, + final CliIntentExtra... extras) { + launchActivity(activityName, extras); + assertNotEquals(mWmState.getRootTaskIdByActivity(activityName), INVALID_STACK_ID); + waitAndAssertResumedActivity(activityName, activityName + " must be resumed"); + mWmState.waitForAppTransitionIdleOnDisplay(DEFAULT_DISPLAY); + return mWmState.getActivity(activityName); + } + private Rect getWindowFrame(ComponentName activityName) { String windowName = getWindowName(activityName); @@ -334,7 +350,7 @@ public class BlurTests extends WindowManagerTestBase { } private void verifyOnlyBackgroundImageVisible() { - final Bitmap screenshot = takeScreenshot(); + final Bitmap screenshot = takeScreenshotForBounds(mSavedActivityBounds); final int height = screenshot.getHeight(); final int width = screenshot.getWidth(); diff --git a/tests/framework/base/windowmanager/src/android/server/wm/WindowInsetsAnimationSynchronicityTests.java b/tests/framework/base/windowmanager/src/android/server/wm/WindowInsetsAnimationSynchronicityTests.java index 8e289032133..bc02d768fe9 100644 --- a/tests/framework/base/windowmanager/src/android/server/wm/WindowInsetsAnimationSynchronicityTests.java +++ b/tests/framework/base/windowmanager/src/android/server/wm/WindowInsetsAnimationSynchronicityTests.java @@ -63,6 +63,7 @@ import androidx.test.rule.ActivityTestRule; import com.android.compatibility.common.util.PollingCheck; import com.android.compatibility.common.util.SystemUtil; +import org.junit.Ignore; import org.junit.Rule; import org.junit.Test; @@ -82,11 +83,13 @@ public class WindowInsetsAnimationSynchronicityTests { private final Context mContext = InstrumentationRegistry.getInstrumentation().getContext(); + @Ignore("b/168446060") @Test public void testShowAndHide_renderSynchronouslyBetweenImeWindowAndAppContent() throws Throwable { runTest(false /* useControlApi */); } + @Ignore("b/168446060") @Test public void testControl_rendersSynchronouslyBetweenImeWindowAndAppContent() throws Throwable { runTest(true /* useControlApi */); 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 331db92c72a..c7bbce11099 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 @@ -760,6 +760,12 @@ public abstract class ActivityManagerTestBase { return mInstrumentation.getUiAutomation().takeScreenshot(); } + protected Bitmap takeScreenshotForBounds(Rect rect) { + Bitmap fullBitmap = takeScreenshot(); + return Bitmap.createBitmap(fullBitmap, rect.left, rect.top, + rect.width(), rect.height()); + } + protected void launchActivity(final ComponentName activityName, final CliIntentExtra... extras) { launchActivityNoWait(activityName, extras); diff --git a/tests/framework/base/windowmanager/util/src/android/server/wm/WindowManagerState.java b/tests/framework/base/windowmanager/util/src/android/server/wm/WindowManagerState.java index 55b2b624f57..0cb025cbe22 100644 --- a/tests/framework/base/windowmanager/util/src/android/server/wm/WindowManagerState.java +++ b/tests/framework/base/windowmanager/util/src/android/server/wm/WindowManagerState.java @@ -1805,6 +1805,10 @@ public class WindowManagerState { return mIsOrganized; } + public Rect getAppBounds() { + return mFullConfiguration.windowConfiguration.getAppBounds(); + } + @Override public Rect getBounds() { if (mBounds == null) { diff --git a/tests/media/src/android/mediav2/cts/DecodeGlAccuracyTest.java b/tests/media/src/android/mediav2/cts/DecodeGlAccuracyTest.java index c6e0ae6e72a..1618ddc4e65 100644 --- a/tests/media/src/android/mediav2/cts/DecodeGlAccuracyTest.java +++ b/tests/media/src/android/mediav2/cts/DecodeGlAccuracyTest.java @@ -45,14 +45,15 @@ import javax.microedition.khronos.opengles.GL10; * data in compressed YUV format. The output of the decoders is shared with OpenGL * as external textures. And OpenGL outputs RGB pixels. The class validates whether * the conversion of input YUV to output RGB is in accordance with the chosen color - * aspects. + * aspects. Video files used in the test do not have any color aspects info coded in + * the bitstreams */ @RunWith(Parameterized.class) public class DecodeGlAccuracyTest extends CodecDecoderTestBase { - private final String LOG_TAG = DecodeGlAccuracyTest.class.getSimpleName(); + private static final String LOG_TAG = DecodeGlAccuracyTest.class.getSimpleName(); // Allowed color tolerance to account for differences in the conversion process - private final int ALLOWED_COLOR_DELTA = 8; + private static final int ALLOWED_COLOR_DELTA = 8; // The test video assets were generated with a set of color bars. // Depending on the color aspects, the values from OpenGL pbuffer @@ -95,7 +96,7 @@ public class DecodeGlAccuracyTest extends CodecDecoderTestBase { // LVL_OFFSET_FR = Transpose({0, 128, 128}) // Reference RGB values for 601 Limited Range - private final int[][] mColorBars601LR = new int[][]{ + private static final int[][] COLOR_BARS_601LR = new int[][]{ {255, 17, 252}, {219, 40, 44}, {255, 196, 0}, @@ -109,7 +110,7 @@ public class DecodeGlAccuracyTest extends CodecDecoderTestBase { {127, 219, 82}, }; // Reference RGB values for 601 Full Range - private final int[][] mColorBars601FR = new int[][]{ + private static final int[][] COLOR_BARS_601FR = new int[][]{ {255, 31, 237}, {204, 51, 55}, {236, 188, 0}, @@ -123,7 +124,7 @@ public class DecodeGlAccuracyTest extends CodecDecoderTestBase { {125, 208, 88}, }; // Reference RGB values for 709 Limited Range - private final int[][] mColorBars709LR = new int[][]{ + private static final int[][] COLOR_BARS_709LR = new int[][]{ {255, 57, 255}, {234, 57, 42}, {255, 188, 0}, @@ -137,6 +138,11 @@ public class DecodeGlAccuracyTest extends CodecDecoderTestBase { {120, 202, 78}, }; + // The test videos were generated with the above color bars. Each bar is of width 16. + private static final int COLOR_BAR_WIDTH = 16; + private static final int COLOR_BAR_OFFSET_X = 8; + private static final int COLOR_BAR_OFFSET_Y = 64; + private int[][] mColorBars; private final String mCompName; @@ -148,12 +154,6 @@ public class DecodeGlAccuracyTest extends CodecDecoderTestBase { private final int mTransferCurve; private OutputSurface mEGLWindowOutSurface; - - // The test videos were generated with the above color bars. Each bar is of - // width 16. - private final int mColorBarWidth = 16; - private final int xOffset = 8; - private final int yOffset = 64; private int mBadFrames = 0; public DecodeGlAccuracyTest(String decoder, String mediaType, String fileName, int range, @@ -165,16 +165,16 @@ public class DecodeGlAccuracyTest extends CodecDecoderTestBase { mStandard = standard; mTransferCurve = transfer; - mColorBars = mColorBars601LR; + mColorBars = COLOR_BARS_601LR; if ((mStandard == MediaFormat.COLOR_STANDARD_BT601_NTSC) && (mRange == MediaFormat.COLOR_RANGE_LIMITED)) { - mColorBars = mColorBars601LR; + mColorBars = COLOR_BARS_601LR; } else if ((mStandard == MediaFormat.COLOR_STANDARD_BT601_NTSC) && (mRange == MediaFormat.COLOR_RANGE_FULL)) { - mColorBars = mColorBars601FR; + mColorBars = COLOR_BARS_601FR; } else if ((mStandard == MediaFormat.COLOR_STANDARD_BT709) && (mRange == MediaFormat.COLOR_RANGE_LIMITED)) { - mColorBars = mColorBars709LR; + mColorBars = COLOR_BARS_709LR; } else { Log.e(LOG_TAG, "Unsupported Color Aspects."); } @@ -185,6 +185,7 @@ public class DecodeGlAccuracyTest extends CodecDecoderTestBase { final boolean isEncoder = false; final boolean needAudio = false; final boolean needVideo = true; + final List<Object[]> argsList = Arrays.asList(new Object[][]{ // mediaType, asset, range, standard, transfer // 601LR @@ -268,8 +269,8 @@ public class DecodeGlAccuracyTest extends CodecDecoderTestBase { ByteBuffer pixelBuf = ByteBuffer.allocateDirect(4); boolean frameFailed = false; for (int i = 0; i < mColorBars.length; i++) { - int x = mColorBarWidth * i + xOffset; - int y = yOffset; + int x = COLOR_BAR_WIDTH * i + COLOR_BAR_OFFSET_X; + int y = COLOR_BAR_OFFSET_Y; GLES20.glReadPixels(x, y, 1, 1, GL10.GL_RGBA, GL10.GL_UNSIGNED_BYTE, pixelBuf); int r = pixelBuf.get(0) & 0xff; int g = pixelBuf.get(1) & 0xff; diff --git a/tests/mediapc/common/src/android/mediapc/cts/common/PerformanceClassEvaluator.java b/tests/mediapc/common/src/android/mediapc/cts/common/PerformanceClassEvaluator.java index ac1905c5570..70340afa8f7 100644 --- a/tests/mediapc/common/src/android/mediapc/cts/common/PerformanceClassEvaluator.java +++ b/tests/mediapc/common/src/android/mediapc/cts/common/PerformanceClassEvaluator.java @@ -195,6 +195,96 @@ public class PerformanceClassEvaluator { } } + // used for requirements [2.2.7.1/5.1/H-1-7], [2.2.7.1/5.1/H-1-8], [2.2.7.1/5.1/H-1-?] + public static class CodecInitLatencyRequirement extends Requirement { + + private static final String TAG = CodecInitLatencyRequirement.class.getSimpleName(); + + private CodecInitLatencyRequirement(String id, RequiredMeasurement<?>... reqs) { + super(id, reqs); + } + + public void setCodecInitLatencyMs(long codecInitLatencyMs) { + this.setMeasuredValue(RequirementConstants.CODEC_INIT_LATENCY, codecInitLatencyMs); + } + + /** + * [2.2.7.1/5.1/H-1-7] MUST have a codec initialization latency of 65(R) / 50(S) / 40(T) + * ms or less for a 1080p or smaller video encoding session for all hardware video + * encoders when under load. Load here is defined as a concurrent 1080p to 720p + * video-only transcoding session using hardware video codecs together with the 1080p + * audio-video recording initialization. + */ + public static CodecInitLatencyRequirement createR5_1__H_1_7() { + RequiredMeasurement<Long> codec_init_latency = + RequiredMeasurement.<Long>builder().setId(RequirementConstants.CODEC_INIT_LATENCY) + .setPredicate(RequirementConstants.LONG_LTE) + .addRequiredValue(Build.VERSION_CODES.R, 65L) + .addRequiredValue(Build.VERSION_CODES.S, 50L) + .addRequiredValue(Build.VERSION_CODES.TIRAMISU, 40L) + .build(); + + return new CodecInitLatencyRequirement(RequirementConstants.R5_1__H_1_7, + codec_init_latency); + } + + /** + * [2.2.7.1/5.1/H-1-8] MUST have a codec initialization latency of 50(R) / 40(S) / 30(T) + * ms or less for a 128 kbps or lower bitrate audio encoding session for all audio + * encoders when under load. Load here is defined as a concurrent 1080p to 720p + * video-only transcoding session using hardware video codecs together with the 1080p + * audio-video recording initialization. + */ + public static CodecInitLatencyRequirement createR5_1__H_1_8() { + RequiredMeasurement<Long> codec_init_latency = + RequiredMeasurement.<Long>builder().setId(RequirementConstants.CODEC_INIT_LATENCY) + .setPredicate(RequirementConstants.LONG_LTE) + .addRequiredValue(Build.VERSION_CODES.R, 50L) + .addRequiredValue(Build.VERSION_CODES.S, 40L) + .addRequiredValue(Build.VERSION_CODES.TIRAMISU, 30L) + .build(); + + return new CodecInitLatencyRequirement(RequirementConstants.R5_1__H_1_8, + codec_init_latency); + } + + // TODO(b/218771970): Update CDD section + /** + * [2.2.7.1/5.1/H-1-?] Codec initialization latency of 40ms or less for a 1080p or + * smaller video decoding session for all hardware video encoders when under load. Load + * here is defined as a concurrent 1080p to 720p video-only transcoding session using + * hardware video codecs together with the 1080p audio-video recording initialization. + */ + public static CodecInitLatencyRequirement createR5_1__H_1_TBD1() { + RequiredMeasurement<Long> codec_init_latency = + RequiredMeasurement.<Long>builder().setId(RequirementConstants.CODEC_INIT_LATENCY) + .setPredicate(RequirementConstants.LONG_LTE) + .addRequiredValue(Build.VERSION_CODES.TIRAMISU, 40L) + .build(); + + return new CodecInitLatencyRequirement(RequirementConstants.R5_1__H_1_TBD, + codec_init_latency); + } + + // TODO(b/218771970): Update CDD section + /** + * [2.2.7.1/5.1/H-1-?] Codec initialization latency of 30ms or less for a 128kbps or + * lower bitrate audio decoding session for all audio encoders when under load. Load here + * is defined as a concurrent 1080p to 720p video-only transcoding session using hardware + * video codecs together with the 1080p audio-video recording initialization. + */ + public static CodecInitLatencyRequirement createR5_1__H_1_TBD2() { + RequiredMeasurement<Long> codec_init_latency = + RequiredMeasurement.<Long>builder().setId(RequirementConstants.CODEC_INIT_LATENCY) + .setPredicate(RequirementConstants.LONG_LTE) + .addRequiredValue(Build.VERSION_CODES.TIRAMISU, 30L) + .build(); + + return new CodecInitLatencyRequirement(RequirementConstants.R5_1__H_1_TBD, + codec_init_latency); + } + } + private <R extends Requirement> R addRequirement(R req) { if (!this.mRequirements.add(req)) { throw new IllegalStateException("Requirement " + req.id() + " already added"); @@ -228,6 +318,22 @@ public class PerformanceClassEvaluator { return this.<MemoryRequirement>addRequirement(MemoryRequirement.createR7_6_1__H_2_1()); } + public CodecInitLatencyRequirement addR5_1__H_1_7() { + return this.addRequirement(CodecInitLatencyRequirement.createR5_1__H_1_7()); + } + + public CodecInitLatencyRequirement addR5_1__H_1_8() { + return this.addRequirement(CodecInitLatencyRequirement.createR5_1__H_1_8()); + } + + public CodecInitLatencyRequirement addR5_1__H_1_TBD1() { + return this.addRequirement(CodecInitLatencyRequirement.createR5_1__H_1_TBD1()); + } + + public CodecInitLatencyRequirement addR5_1__H_1_TBD2() { + return this.addRequirement(CodecInitLatencyRequirement.createR5_1__H_1_TBD2()); + } + public void submitAndCheck() { boolean perfClassMet = true; for (Requirement req: this.mRequirements) { diff --git a/tests/mediapc/common/src/android/mediapc/cts/common/RequirementConstants.java b/tests/mediapc/common/src/android/mediapc/cts/common/RequirementConstants.java index e67656fbb98..13621891c59 100644 --- a/tests/mediapc/common/src/android/mediapc/cts/common/RequirementConstants.java +++ b/tests/mediapc/common/src/android/mediapc/cts/common/RequirementConstants.java @@ -35,6 +35,7 @@ public class RequirementConstants { public static final String R5_1__H_1_6 = "r5_1__h_1_6"; // 5.1/H-1-6 public static final String R5_1__H_1_7 = "r5_1__h_1_7"; // 5.1/H-1-7 public static final String R5_1__H_1_8 = "r5_1__h_1_8"; // 5.1/H-1-8 + public static final String R5_1__H_1_TBD = "r5_1__h_1_?"; // 5.1/H-1-? public static final String R5_3__H_1_1 = "r5_3__h_1_1"; // 5.3/H-1-1 public static final String R5_3__H_1_2 = "r5_3__h_1_2"; // 5.3/H-1-2 public static final String R5_6__H_1_1 = "r5_6__h_1_1"; // 5.6/H-1-1 @@ -70,12 +71,14 @@ public class RequirementConstants { public static final String SHORT_RESOLUTION = "short_resolution_pixels"; public static final String DISPLAY_DENSITY = "display_density_dpi"; public static final String PHYSICAL_MEMORY = "physical_memory_mb"; + public static final String CODEC_INIT_LATENCY = "codec_initialization_latency_ms"; public enum Result { NA, MET, UNMET } public static final BiPredicate<Long, Long> LONG_GTE = RequirementConstants.gte(); + public static final BiPredicate<Long, Long> LONG_LTE = RequirementConstants.lte(); public static final BiPredicate<Integer, Integer> INTEGER_GTE = RequirementConstants.gte(); public static final BiPredicate<Integer, Integer> INTEGER_LTE = RequirementConstants.lte(); diff --git a/tests/mediapc/src/android/mediapc/cts/CodecInitializationLatencyTest.java b/tests/mediapc/src/android/mediapc/cts/CodecInitializationLatencyTest.java index e1260e772f3..03790901307 100644 --- a/tests/mediapc/src/android/mediapc/cts/CodecInitializationLatencyTest.java +++ b/tests/mediapc/src/android/mediapc/cts/CodecInitializationLatencyTest.java @@ -35,8 +35,8 @@ import android.media.MediaCodec; import android.media.MediaCodecInfo; import android.media.MediaFormat; import android.media.MediaRecorder; +import android.mediapc.cts.common.PerformanceClassEvaluator; import android.mediapc.cts.common.Utils; -import android.os.Build; import android.util.Log; import android.util.Pair; import android.view.Surface; @@ -46,14 +46,11 @@ import androidx.test.platform.app.InstrumentationRegistry; import androidx.test.rule.ActivityTestRule; import com.android.compatibility.common.util.CddTest; -import com.android.compatibility.common.util.DeviceReportLog; -import com.android.compatibility.common.util.ResultType; -import com.android.compatibility.common.util.ResultUnit; - import org.junit.After; import org.junit.Before; import org.junit.Rule; import org.junit.Test; +import org.junit.rules.TestName; import org.junit.runner.RunWith; import org.junit.runners.Parameterized; @@ -76,19 +73,7 @@ import java.util.Set; public class CodecInitializationLatencyTest { private static final String LOG_TAG = CodecInitializationLatencyTest.class.getSimpleName(); private static final boolean[] boolStates = {false, true}; - private static final int MAX_AUDIOENC_INITIALIZATION_LATENCY_PC_R_MS = 50; - private static final int MAX_VIDEOENC_INITIALIZATION_LATENCY_PC_R_MS = 65; - private static final int MAX_AUDIOENC_INITIALIZATION_LATENCY_PC_S_MS = 40; - private static final int MAX_VIDEOENC_INITIALIZATION_LATENCY_PC_S_MS = 50; - private static final int MAX_AUDIOENC_INITIALIZATION_LATENCY_PC_T_MS = 30; - private static final int MAX_VIDEOENC_INITIALIZATION_LATENCY_PC_T_MS = 40; - private static final int MAX_AUDIODEC_INITIALIZATION_LATENCY_PC_T_MS = 30; - private static final int MAX_VIDEODEC_INITIALIZATION_LATENCY_PC_T_MS = 40; - - private static final int MAX_AUDIOENC_INITIALIZATION_LATENCY_MS; - private static final int MAX_VIDEOENC_INITIALIZATION_LATENCY_MS; - private static final int MAX_AUDIODEC_INITIALIZATION_LATENCY_MS; - private static final int MAX_VIDEODEC_INITIALIZATION_LATENCY_MS; + private static final String AVC = MediaFormat.MIMETYPE_VIDEO_AVC; private static final String HEVC = MediaFormat.MIMETYPE_VIDEO_HEVC; private static final String AVC_TRANSCODE_FILE = "bbb_1280x720_3mbps_30fps_avc.mp4"; @@ -96,26 +81,10 @@ public class CodecInitializationLatencyTest { private static String AVC_ENCODER_NAME; private static final Map<String, String> mTestFiles = new HashMap<>(); + @Rule + public final TestName mTestName = new TestName(); + static { - if (Utils.isRPerfClass()) { - MAX_AUDIOENC_INITIALIZATION_LATENCY_MS = MAX_AUDIOENC_INITIALIZATION_LATENCY_PC_R_MS; - MAX_VIDEOENC_INITIALIZATION_LATENCY_MS = MAX_VIDEOENC_INITIALIZATION_LATENCY_PC_R_MS; - } else if (Utils.isSPerfClass()) { - MAX_AUDIOENC_INITIALIZATION_LATENCY_MS = MAX_AUDIOENC_INITIALIZATION_LATENCY_PC_S_MS; - MAX_VIDEOENC_INITIALIZATION_LATENCY_MS = MAX_VIDEOENC_INITIALIZATION_LATENCY_PC_S_MS; - } else { - // Performance class Build.VERSION_CODES.TIRAMISU and beyond - MAX_AUDIOENC_INITIALIZATION_LATENCY_MS = MAX_AUDIOENC_INITIALIZATION_LATENCY_PC_T_MS; - MAX_VIDEOENC_INITIALIZATION_LATENCY_MS = MAX_VIDEOENC_INITIALIZATION_LATENCY_PC_T_MS; - } - if (Utils.isTPerfClass()) { - MAX_AUDIODEC_INITIALIZATION_LATENCY_MS = MAX_AUDIODEC_INITIALIZATION_LATENCY_PC_T_MS; - MAX_VIDEODEC_INITIALIZATION_LATENCY_MS = MAX_VIDEODEC_INITIALIZATION_LATENCY_PC_T_MS; - } else { - // no requirement below performance class Build.VERSION_CODES.TIRAMISU - MAX_AUDIODEC_INITIALIZATION_LATENCY_MS = Integer.MAX_VALUE; - MAX_VIDEODEC_INITIALIZATION_LATENCY_MS = Integer.MAX_VALUE; - } // TODO(b/222006626): Add tests vectors for remaining media types // Audio media types mTestFiles.put(MediaFormat.MIMETYPE_AUDIO_AAC, "bbb_stereo_48kHz_128kbps_aac.mp4"); @@ -300,6 +269,7 @@ public class CodecInitializationLatencyTest { } } + // TODO(b/218771970): Add cdd annotation /** * This test validates the initialization latency (time for codec create + configure) for * audio and hw video codecs. @@ -324,11 +294,6 @@ public class CodecInitializationLatencyTest { // need to meet the pass criteria. For eg. if NUM_MEASUREMENTS = 5, audio, sync and Async // modes which is a total of 10 iterations, this translates to index 7. final int percentile = 70; - long expectedMaxCodecInitializationLatencyMs = isAudio ? - isEncoder ? MAX_AUDIOENC_INITIALIZATION_LATENCY_MS : - MAX_AUDIODEC_INITIALIZATION_LATENCY_MS : - isEncoder ? MAX_VIDEOENC_INITIALIZATION_LATENCY_MS : - MAX_VIDEODEC_INITIALIZATION_LATENCY_MS; long sumOfCodecInitializationLatencyMs = 0; int count = 0; int numOfActualMeasurements = @@ -378,38 +343,15 @@ public class CodecInitializationLatencyTest { Log.i(LOG_TAG, "Max " + statsLog + codecInitializationLatencyMs[count - 1]); Log.i(LOG_TAG, "Avg " + statsLog + (sumOfCodecInitializationLatencyMs / count)); long initializationLatency = codecInitializationLatencyMs[percentile * count / 100]; - if (Utils.isPerfClass()) { - String errorLog = String.format( - "CodecInitialization latency for mime: %s, Codec: %s is not as expected." - + "act/exp in Ms :: %d/%d", mMime, mCodecName, initializationLatency, - expectedMaxCodecInitializationLatencyMs); - assertTrue(errorLog, initializationLatency <= expectedMaxCodecInitializationLatencyMs); - } else { - int pc; - if (mMime.startsWith("audio/")) { - pc = initializationLatency < MAX_AUDIOENC_INITIALIZATION_LATENCY_PC_T_MS ? - Build.VERSION_CODES.TIRAMISU : - initializationLatency < MAX_AUDIOENC_INITIALIZATION_LATENCY_PC_S_MS ? - Build.VERSION_CODES.S : initializationLatency < - MAX_AUDIOENC_INITIALIZATION_LATENCY_PC_R_MS ? - Build.VERSION_CODES.R : 0; - } else { - pc = initializationLatency < MAX_VIDEOENC_INITIALIZATION_LATENCY_PC_T_MS ? - Build.VERSION_CODES.TIRAMISU : - initializationLatency < MAX_VIDEOENC_INITIALIZATION_LATENCY_PC_S_MS ? - Build.VERSION_CODES.S : initializationLatency < - MAX_VIDEOENC_INITIALIZATION_LATENCY_PC_R_MS ? - Build.VERSION_CODES.R : 0; - } - DeviceReportLog log = new DeviceReportLog("MediaPerformanceClassLogs", - "InitializationLatency_" + mCodecName); - log.addValue("codec", mCodecName, ResultType.NEUTRAL, ResultUnit.NONE); - log.addValue("initialization_latency", initializationLatency, ResultType.LOWER_BETTER, - ResultUnit.NONE); - log.setSummary("CDD 2.2.7.1/5.1/H-1-7,H-1-8 performance_class", pc, ResultType.NEUTRAL, - ResultUnit.NONE); - log.submit(InstrumentationRegistry.getInstrumentation()); - } + + PerformanceClassEvaluator pce = new PerformanceClassEvaluator(this.mTestName); + PerformanceClassEvaluator.CodecInitLatencyRequirement r5_1__H_1_Latency = + isEncoder ? isAudio ? pce.addR5_1__H_1_8() : pce.addR5_1__H_1_7() + : isAudio ? pce.addR5_1__H_1_TBD2() : pce.addR5_1__H_1_TBD1(); + + r5_1__H_1_Latency.setCodecInitLatencyMs(initializationLatency); + + pce.submitAndCheck(); } /** diff --git a/tests/tests/app.usage/TestApp2/Android.bp b/tests/tests/app.usage/TestApp2/Android.bp index 1ac6331ff0e..088769f36ce 100644 --- a/tests/tests/app.usage/TestApp2/Android.bp +++ b/tests/tests/app.usage/TestApp2/Android.bp @@ -19,7 +19,6 @@ package { android_test_helper_app { name: "CtsUsageStatsTestApp2", defaults: ["cts_defaults"], - platform_apis: true, static_libs: [ "androidx.test.rules", "compatibility-device-util-axt", @@ -32,12 +31,15 @@ android_test_helper_app { "android.test.base", "android.test.runner", ], - srcs: ["src/**/*.java", "aidl/**/*.aidl"], + srcs: [ + "src/**/*.java", + "aidl/**/*.aidl", + ], // Tag this module as a cts test artifact test_suites: [ "cts", "general-tests", - "mts" + "mts", ], - sdk_version: "test_current" + sdk_version: "test_current", } diff --git a/tests/tests/bluetooth/src/android/bluetooth/cts/BluetoothA2dpTest.java b/tests/tests/bluetooth/src/android/bluetooth/cts/BluetoothA2dpTest.java index e21c62907e1..c4289e01e79 100644 --- a/tests/tests/bluetooth/src/android/bluetooth/cts/BluetoothA2dpTest.java +++ b/tests/tests/bluetooth/src/android/bluetooth/cts/BluetoothA2dpTest.java @@ -41,7 +41,7 @@ public class BluetoothA2dpTest extends AndroidTestCase { private boolean mHasBluetooth; private BluetoothAdapter mAdapter; - private UiAutomation mUiAutomation;; + private UiAutomation mUiAutomation; private BluetoothA2dp mBluetoothA2dp; private boolean mIsA2dpSupported; diff --git a/tests/tests/bluetooth/src/android/bluetooth/cts/BluetoothConfigTest.java b/tests/tests/bluetooth/src/android/bluetooth/cts/BluetoothConfigTest.java new file mode 100644 index 00000000000..4eccda133ca --- /dev/null +++ b/tests/tests/bluetooth/src/android/bluetooth/cts/BluetoothConfigTest.java @@ -0,0 +1,143 @@ +/* + * Copyright 2022 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.bluetooth.cts; + +import static android.Manifest.permission.BLUETOOTH_CONNECT; +import static android.Manifest.permission.BLUETOOTH_PRIVILEGED; + +import android.app.UiAutomation; +import android.bluetooth.BluetoothAdapter; +import android.bluetooth.BluetoothManager; +import android.bluetooth.BluetoothProfile; +import android.bluetooth.BluetoothStatusCodes; +import android.test.AndroidTestCase; +import android.util.Log; + +import androidx.test.InstrumentationRegistry; + +import java.lang.invoke.MethodHandles; +import java.util.List; + +public class BluetoothConfigTest extends AndroidTestCase { + private static final String TAG = MethodHandles.lookup().lookupClass().getSimpleName(); + + private boolean mHasBluetooth; + private BluetoothAdapter mAdapter; + private UiAutomation mUiAutomation; + + @Override + public void setUp() throws Exception { + super.setUp(); + + mHasBluetooth = TestUtils.hasBluetooth(); + if (!mHasBluetooth) return; + + mUiAutomation = InstrumentationRegistry.getInstrumentation().getUiAutomation(); + mUiAutomation.adoptShellPermissionIdentity(BLUETOOTH_CONNECT); + + BluetoothManager manager = getContext().getSystemService(BluetoothManager.class); + mAdapter = manager.getAdapter(); + assertTrue(BTAdapterUtils.enableAdapter(mAdapter, mContext)); + } + + @Override + public void tearDown() throws Exception { + super.tearDown(); + if (!mHasBluetooth) return; + + assertTrue(BTAdapterUtils.disableAdapter(mAdapter, mContext)); + mAdapter = null; + mUiAutomation.dropShellPermissionIdentity(); + } + + private int checkIsProfileEnabledInList(int profile, List<Integer> supportedProfiles) { + final boolean isEnabled = TestUtils.isProfileEnabled(profile); + final boolean isSupported = supportedProfiles.contains(profile); + + if (isEnabled == isSupported) { + return 0; + } + Log.e(TAG, "Profile config does not match for profile: " + + BluetoothProfile.getProfileName(profile) + + ". Config currently return: " + isEnabled + + ". Is profile in the list: " + isSupported); + return 1; + } + + public void testProfileEnabledValueInList() { + if (!mHasBluetooth) { + return; + } + mUiAutomation.adoptShellPermissionIdentity(BLUETOOTH_CONNECT, BLUETOOTH_PRIVILEGED); + final List<Integer> pList = mAdapter.getSupportedProfiles(); + int wrong_config_in_list = checkIsProfileEnabledInList(BluetoothProfile.A2DP, pList) + + checkIsProfileEnabledInList(BluetoothProfile.A2DP_SINK, pList) + + checkIsProfileEnabledInList(BluetoothProfile.AVRCP_CONTROLLER, pList) + + checkIsProfileEnabledInList(BluetoothProfile.CSIP_SET_COORDINATOR, pList) + + checkIsProfileEnabledInList(BluetoothProfile.GATT, pList) + + checkIsProfileEnabledInList(BluetoothProfile.HAP_CLIENT, pList) + + checkIsProfileEnabledInList(BluetoothProfile.HEADSET, pList) + + checkIsProfileEnabledInList(BluetoothProfile.HEADSET_CLIENT, pList) + + checkIsProfileEnabledInList(BluetoothProfile.HEARING_AID, pList) + + checkIsProfileEnabledInList(BluetoothProfile.HID_DEVICE, pList) + + checkIsProfileEnabledInList(BluetoothProfile.HID_HOST, pList) + + checkIsProfileEnabledInList(BluetoothProfile.LE_AUDIO, pList) + + checkIsProfileEnabledInList(BluetoothProfile.LE_AUDIO_BROADCAST, pList) + + checkIsProfileEnabledInList(BluetoothProfile.LE_AUDIO_BROADCAST_ASSISTANT, pList) + + checkIsProfileEnabledInList(BluetoothProfile.MAP, pList) + + checkIsProfileEnabledInList(BluetoothProfile.MAP_CLIENT, pList) + + checkIsProfileEnabledInList(BluetoothProfile.OPP, pList) + + checkIsProfileEnabledInList(BluetoothProfile.PAN, pList) + + checkIsProfileEnabledInList(BluetoothProfile.PBAP, pList) + + checkIsProfileEnabledInList(BluetoothProfile.PBAP_CLIENT, pList) + + checkIsProfileEnabledInList(BluetoothProfile.SAP, pList) + + checkIsProfileEnabledInList(BluetoothProfile.VOLUME_CONTROL, pList); + + assertEquals("Config does not match adapter hardware support. CHECK THE PREVIOUS LOGS.", + 0, wrong_config_in_list); + } + + private int checkIsProfileEnabled(int profile, int adapterSupport) { + final boolean isEnabled = TestUtils.isProfileEnabled(profile); + final boolean isSupported = BluetoothStatusCodes.FEATURE_SUPPORTED == adapterSupport; + + if (isEnabled == isSupported) { + return 0; + } + Log.e(TAG, "Profile config does not match for profile: " + + BluetoothProfile.getProfileName(profile) + + ". Config currently return: " + TestUtils.isProfileEnabled(profile) + + ". Adapter support return: " + adapterSupport); + return 1; + } + + public void testProfileEnabledValue() { + if (!mHasBluetooth) { + return; + } + int wrong_config = + checkIsProfileEnabled(BluetoothProfile.LE_AUDIO, + mAdapter.isLeAudioSupported()) + + checkIsProfileEnabled(BluetoothProfile.LE_AUDIO_BROADCAST, + mAdapter.isLeAudioBroadcastSourceSupported()) + + checkIsProfileEnabled(BluetoothProfile.LE_AUDIO_BROADCAST_ASSISTANT, + mAdapter.isLeAudioBroadcastAssistantSupported()); + + assertEquals("Config does not match adapter hardware support. CHECK THE PREVIOUS LOGS.", + 0, wrong_config); + } +} diff --git a/tests/tests/keystore/Android.bp b/tests/tests/keystore/Android.bp index 076ce21285f..03c54b1defe 100644 --- a/tests/tests/keystore/Android.bp +++ b/tests/tests/keystore/Android.bp @@ -134,6 +134,8 @@ android_test { "android.test.runner", ], static_libs: [ + "bouncycastle-bcpkix-unbundled", + "bouncycastle-unbundled", "cts-core-test-runner-axt", "wycheproof-keystore", "wycheproof-gson", diff --git a/tests/tests/keystore/src/android/keystore/cts/Curve25519Test.java b/tests/tests/keystore/src/android/keystore/cts/Curve25519Test.java index 30bd40bb196..95d0d0c707e 100644 --- a/tests/tests/keystore/src/android/keystore/cts/Curve25519Test.java +++ b/tests/tests/keystore/src/android/keystore/cts/Curve25519Test.java @@ -30,14 +30,20 @@ import org.junit.Test; import org.junit.runner.RunWith; import java.security.InvalidAlgorithmParameterException; +import java.security.InvalidKeyException; +import java.security.KeyPair; import java.security.KeyPairGenerator; import java.security.KeyStore; import java.security.KeyStoreException; import java.security.NoSuchAlgorithmException; import java.security.NoSuchProviderException; import java.security.ProviderException; +import java.security.Signature; +import java.security.SignatureException; +import java.security.interfaces.EdECPublicKey; import java.security.spec.ECGenParameterSpec; import java.security.spec.NamedParameterSpec; +import java.util.Base64; @RunWith(AndroidJUnit4.class) public class Curve25519Test { @@ -74,23 +80,34 @@ public class Curve25519Test { @Test public void ed25519KeyGenerationAndSigningTest() throws NoSuchAlgorithmException, NoSuchProviderException, - InvalidAlgorithmParameterException { + InvalidAlgorithmParameterException, InvalidKeyException, SignatureException { KeyPairGenerator kpg = KeyPairGenerator.getInstance("EC", "AndroidKeyStore"); final String alias = "ed25519-alias"; deleteEntry(alias); KeyGenParameterSpec keySpec = new KeyGenParameterSpec.Builder(alias, KeyProperties.PURPOSE_SIGN | KeyProperties.PURPOSE_VERIFY) - .setAlgorithmParameterSpec(new ECGenParameterSpec("ed25519")).build(); + .setAlgorithmParameterSpec(new ECGenParameterSpec("ed25519")) + .setDigests(KeyProperties.DIGEST_NONE).build(); kpg.initialize(keySpec); - //TODO(b/214203951): Remove this try/catch once Conscrypt class are available. - try { - kpg.generateKeyPair(); - fail("Should not be supported yet"); - } catch (ProviderException e) { - assertThat(e.getMessage()).isEqualTo("Curve 1.3.101.112 not supported yet"); - } + KeyPair kp = kpg.generateKeyPair(); + assertThat(kp.getPublic()).isInstanceOf(EdECPublicKey.class); + + byte[] data = "helloxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx".getBytes(); + Signature signer = Signature.getInstance("Ed25519"); + signer.initSign(kp.getPrivate()); + signer.update(data); + byte[] sigBytes = signer.sign(); + assertThat(sigBytes.length).isEqualTo(64); + EdECPublicKey publicKey = (EdECPublicKey) kp.getPublic(); + android.util.Log.i("Curve25519Test", "Manually validate: Payload " + + Base64.getEncoder().encodeToString(data) + " encoded key: " + + Base64.getEncoder().encodeToString(kp.getPublic().getEncoded()) + + " signature: " + Base64.getEncoder().encodeToString(sigBytes)); + + //TODO: Verify signature over the data when Conscrypt supports validating Ed25519 + // signatures. } @Test @@ -150,4 +167,4 @@ public class Curve25519Test { assertThat(e.getMessage()).contains("cannot be initialized using NamedParameterSpec"); } } -}
\ No newline at end of file +} diff --git a/tests/tests/media/decoder/src/android/media/decoder/cts/DecoderTest.java b/tests/tests/media/decoder/src/android/media/decoder/cts/DecoderTest.java index 6cf88023662..fee4f04b51c 100644 --- a/tests/tests/media/decoder/src/android/media/decoder/cts/DecoderTest.java +++ b/tests/tests/media/decoder/src/android/media/decoder/cts/DecoderTest.java @@ -2454,16 +2454,36 @@ public class DecoderTest extends MediaTestBase { } @Test - public void testDecodeWithEOSOnLastBuffer() throws Exception { + public void testDecodeM4aWithEOSOnLastBuffer() throws Exception { testDecodeWithEOSOnLastBuffer("sinesweepm4a.m4a"); + } + + @Test + public void testDecodeMp3WithEOSOnLastBuffer() throws Exception { testDecodeWithEOSOnLastBuffer("sinesweepmp3lame.mp3"); testDecodeWithEOSOnLastBuffer("sinesweepmp3smpb.mp3"); + } + + @Test + public void testDecodeOpusWithEOSOnLastBuffer() throws Exception { testDecodeWithEOSOnLastBuffer("sinesweepopus.mkv"); testDecodeWithEOSOnLastBuffer("sinesweepopusmp4.mp4"); + } + + @Test + public void testDecodeWavWithEOSOnLastBuffer() throws Exception { testDecodeWithEOSOnLastBuffer("sinesweepwav.wav"); + } + + @Test + public void testDecodeFlacWithEOSOnLastBuffer() throws Exception { testDecodeWithEOSOnLastBuffer("sinesweepflacmkv.mkv"); testDecodeWithEOSOnLastBuffer("sinesweepflac.flac"); testDecodeWithEOSOnLastBuffer("sinesweepflacmp4.mp4"); + } + + @Test + public void testDecodeOggWithEOSOnLastBuffer() throws Exception { testDecodeWithEOSOnLastBuffer("sinesweepogg.ogg"); testDecodeWithEOSOnLastBuffer("sinesweepoggmkv.mkv"); testDecodeWithEOSOnLastBuffer("sinesweepoggmp4.mp4"); diff --git a/tests/tests/permission4/Android.bp b/tests/tests/permission4/Android.bp index 22b0aa25fe3..bb0fd4bd469 100644 --- a/tests/tests/permission4/Android.bp +++ b/tests/tests/permission4/Android.bp @@ -22,7 +22,6 @@ android_test { name: "CtsPermission4TestCases", sdk_version: "test_current", defaults: ["cts_defaults"], - platform_apis: true, srcs: [ "src/**/*.kt", ], diff --git a/tests/tests/systemui/src/android/systemui/cts/LightBarBaseActivity.java b/tests/tests/systemui/src/android/systemui/cts/LightBarBaseActivity.java index b4c4e3840b5..db2a142ba61 100644 --- a/tests/tests/systemui/src/android/systemui/cts/LightBarBaseActivity.java +++ b/tests/tests/systemui/src/android/systemui/cts/LightBarBaseActivity.java @@ -45,6 +45,10 @@ public class LightBarBaseActivity extends Activity { return mContent.getWindowSystemUiVisibility(); } + public int getLeft() { + return mContent.getLocationOnScreen()[0]; + } + public int getTop() { return mContent.getLocationOnScreen()[1]; } @@ -53,6 +57,10 @@ public class LightBarBaseActivity extends Activity { return mContent.getLocationOnScreen()[1] + mContent.getHeight(); } + public int getRight() { + return mContent.getLocationOnScreen()[0] + mContent.getWidth(); + } + public int getWidth() { return mContent.getWidth(); } diff --git a/tests/tests/systemui/src/android/systemui/cts/LightBarTestBase.java b/tests/tests/systemui/src/android/systemui/cts/LightBarTestBase.java index 0004bcd6e8a..a0e9ffb21d5 100644 --- a/tests/tests/systemui/src/android/systemui/cts/LightBarTestBase.java +++ b/tests/tests/systemui/src/android/systemui/cts/LightBarTestBase.java @@ -59,13 +59,14 @@ public class LightBarTestBase { protected Bitmap takeStatusBarScreenshot(LightBarBaseActivity activity) { Bitmap fullBitmap = getInstrumentation().getUiAutomation().takeScreenshot(); - return Bitmap.createBitmap(fullBitmap, 0, 0, fullBitmap.getWidth(), activity.getTop()); + return Bitmap.createBitmap(fullBitmap, activity.getLeft(), 0, activity.getRight(), + activity.getTop()); } protected Bitmap takeNavigationBarScreenshot(LightBarBaseActivity activity) { Bitmap fullBitmap = getInstrumentation().getUiAutomation().takeScreenshot(); - return Bitmap.createBitmap(fullBitmap, 0, activity.getBottom(), fullBitmap.getWidth(), - fullBitmap.getHeight() - activity.getBottom()); + return Bitmap.createBitmap(fullBitmap, activity.getLeft(), activity.getBottom(), + activity.getRight(), fullBitmap.getHeight() - activity.getBottom()); } protected void dumpBitmap(Bitmap bitmap, String name) { @@ -106,9 +107,7 @@ public class LightBarTestBase { for (int i = 0; i < pixels.length; i++) { int x = i % bitmap.getWidth(); int y = i / bitmap.getWidth(); - - if (pixels[i] == backgroundColor - || isInsideCutout(x, shiftY + y)) { + if (isColorSame(pixels[i], backgroundColor) || isInsideCutout(x, shiftY + y)) { backgroundColorPixelCount++; } } diff --git a/tests/tests/telephony/current/Android.bp b/tests/tests/telephony/current/Android.bp index 973be3f772e..54592673600 100644 --- a/tests/tests/telephony/current/Android.bp +++ b/tests/tests/telephony/current/Android.bp @@ -56,13 +56,7 @@ android_test { "hamcrest-library", "compatibility-device-util-axt", "truth-prebuilt", - "android.hardware.radio.config-V1-java", - "android.hardware.radio.modem-V1-java", - "android.hardware.radio.sim-V1-java", - "android.hardware.radio.network-V1-java", - "android.hardware.radio.data-V1-java", - "android.hardware.radio.messaging-V1-java", - "android.hardware.radio.voice-V1-java", + "android.telephony.mockmodem", ], srcs: [ "src/**/*.java", diff --git a/tests/tests/telephony/current/AndroidManifest.xml b/tests/tests/telephony/current/AndroidManifest.xml index 8befd971e1c..f027c292bef 100644 --- a/tests/tests/telephony/current/AndroidManifest.xml +++ b/tests/tests/telephony/current/AndroidManifest.xml @@ -162,21 +162,6 @@ </intent-filter> </service> - <service android:name="android.telephony.cts.MockModemService" - android:directBootAware="true" - android:persistent="true" - android:exported="true"> - <intent-filter> - <action android:name="android.telephony.cts.iradioconfig"/> - <action android:name="android.telephony.cts.iradiomodem"/> - <action android:name="android.telephony.cts.iradiosim"/> - <action android:name="android.telephony.cts.iradionetwork"/> - <action android:name="android.telephony.cts.iradiodata"/> - <action android:name="android.telephony.cts.iradiomessaging"/> - <action android:name="android.telephony.cts.iradiovoice"/> - </intent-filter> - </service> - <service android:name="android.telephony.cts.FakeCarrierMessagingService" android:permission="android.permission.BIND_CARRIER_SERVICES" diff --git a/tests/tests/telephony/current/mockmodem/Android.bp b/tests/tests/telephony/current/mockmodem/Android.bp new file mode 100644 index 00000000000..0e2a29aee2e --- /dev/null +++ b/tests/tests/telephony/current/mockmodem/Android.bp @@ -0,0 +1,41 @@ +// Copyright (C) 2022 The Android Open Source Project +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package { + default_applicable_licenses: ["Android-Apache-2.0"], +} + +android_library { + name: "android.telephony.mockmodem", + srcs: [ + "src/**/*.java", + ":cts-telephony-utils", + ], + libs: [ + "android-support-annotations", + ], + static_libs: [ + "androidx.test.rules", + "android.hardware.radio.config-V1-java", + "android.hardware.radio.modem-V1-java", + "android.hardware.radio.sim-V1-java", + "android.hardware.radio.network-V1-java", + "android.hardware.radio.data-V1-java", + "android.hardware.radio.messaging-V1-java", + "android.hardware.radio.voice-V1-java", + ], + + min_sdk_version: "30", + platform_apis: true, +} diff --git a/tests/tests/telephony/current/mockmodem/AndroidManifest.xml b/tests/tests/telephony/current/mockmodem/AndroidManifest.xml new file mode 100644 index 00000000000..671794d15b3 --- /dev/null +++ b/tests/tests/telephony/current/mockmodem/AndroidManifest.xml @@ -0,0 +1,37 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- Copyright (C) 2022 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> + +<manifest xmlns:android="http://schemas.android.com/apk/res/android" + package="android.telephony.mockmodem"> + + <!-- Must be debuggable for compat shell commands to work on user builds --> + <application android:debuggable="true"> + <service android:name="android.telephony.mockmodem.MockModemService" + android:directBootAware="true" + android:persistent="true" + android:exported="true"> + <intent-filter> + <action android:name="android.telephony.mockmodem.iradioconfig"/> + <action android:name="android.telephony.mockmodem.iradiomodem"/> + <action android:name="android.telephony.mockmodem.iradiosim"/> + <action android:name="android.telephony.mockmodem.iradionetwork"/> + <action android:name="android.telephony.mockmodem.iradiodata"/> + <action android:name="android.telephony.mockmodem.iradiomessaging"/> + <action android:name="android.telephony.mockmodem.iradiovoice"/> + </intent-filter> + </service> + </application> +</manifest> diff --git a/tests/tests/telephony/current/assets/mock_sim_tw_cht.xml b/tests/tests/telephony/current/mockmodem/assets/mock_sim_tw_cht.xml index aaabe629701..426185a3121 100644 --- a/tests/tests/telephony/current/assets/mock_sim_tw_cht.xml +++ b/tests/tests/telephony/current/mockmodem/assets/mock_sim_tw_cht.xml @@ -1,4 +1,4 @@ -<MockSim numofapp="2" iccid="89886920042507847155"> +<MockSim numofapp="2" atr="3B9F96801FC78031E073FE2111634082918307900099"> <MockSimProfile id="0" type="APPTYPE_USIM"> <PinProfile appstate="APPSTATE_READY"> <Pin1State>PINSTATE_DISABLED</Pin1State> @@ -15,7 +15,9 @@ </MF> <ADF aid="A0000000871002F886FF9289050B00FE"> - <EF name="EF_IMSI" id="6F07">311740123456789</EF> + <EF name="EF_IMSI" id="6F07" command="" mnc-digit="2">466920123456789</EF> + <EF name="EF_ICCID" id="2FE2" command="0xb0">89886920042507847155</EF> + <EF name="EF_ICCID" id="2FE2" command="0xc0">0000000A2FE2040000FFFF01020002</EF> </ADF> </MockSimProfile> diff --git a/tests/tests/telephony/current/mockmodem/assets/mock_sim_tw_fet.xml b/tests/tests/telephony/current/mockmodem/assets/mock_sim_tw_fet.xml new file mode 100644 index 00000000000..4463d8816e8 --- /dev/null +++ b/tests/tests/telephony/current/mockmodem/assets/mock_sim_tw_fet.xml @@ -0,0 +1,23 @@ +<MockSim numofapp="1" atr="3B9E95801FC78031E073FE211B66D001A0E50F0048"> +<MockSimProfile id="0" type="APPTYPE_USIM"> + <PinProfile appstate="APPSTATE_READY"> + <Pin1State>PINSTATE_DISABLED</Pin1State> + <Pin2State>PINSTATE_ENABLED_NOT_VERIFIED</Pin2State> + </PinProfile> + + <FacilityLock> + <FD>LOCK_DISABLED</FD> + <SC>LOCK_DISABLED</SC> + </FacilityLock> + + <MF name="MF" path="3F00"> + <EFDIR name="ADF1" curr_active="true">A0000000871002FF33FFFF8901010100</EFDIR> + </MF> + + <ADF aid="A0000000871002FF33FFFF8901010100"> + <EF name="EF_IMSI" id="6F07" command="" mnc-digit="2">466011122334455</EF> + <EF name="EF_ICCID" id="2FE2" command="0xb0">89886021157300856597</EF> + <EF name="EF_ICCID" id="2FE2" command="0xc0">0000000A2FE2040000FFFF01020002</EF> + </ADF> +</MockSimProfile> +</MockSim>
\ No newline at end of file diff --git a/tests/tests/telephony/current/src/android/telephony/cts/IRadioConfigImpl.java b/tests/tests/telephony/current/mockmodem/src/android/telephony/mockmodem/IRadioConfigImpl.java index b18a355e8de..1eae358e3b0 100644 --- a/tests/tests/telephony/current/src/android/telephony/cts/IRadioConfigImpl.java +++ b/tests/tests/telephony/current/mockmodem/src/android/telephony/mockmodem/IRadioConfigImpl.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package android.telephony.cts; +package android.telephony.mockmodem; import android.hardware.radio.RadioError; import android.hardware.radio.RadioIndicationType; diff --git a/tests/tests/telephony/current/src/android/telephony/cts/IRadioDataImpl.java b/tests/tests/telephony/current/mockmodem/src/android/telephony/mockmodem/IRadioDataImpl.java index 92a22c3aa66..86f1501ae2c 100644 --- a/tests/tests/telephony/current/src/android/telephony/cts/IRadioDataImpl.java +++ b/tests/tests/telephony/current/mockmodem/src/android/telephony/mockmodem/IRadioDataImpl.java @@ -14,9 +14,10 @@ * limitations under the License. */ -package android.telephony.cts; +package android.telephony.mockmodem; import android.hardware.radio.RadioError; +import android.hardware.radio.RadioIndicationType; import android.hardware.radio.RadioResponseInfo; import android.hardware.radio.data.DataProfileInfo; import android.hardware.radio.data.IRadioData; @@ -49,6 +50,8 @@ public class IRadioDataImpl extends IRadioData.Stub { mRadioDataResponse = radioDataResponse; mRadioDataIndication = radioDataIndication; mService.countDownLatch(MockModemService.LATCH_RADIO_INTERFACES_READY); + + unsolEmptyDataCallList(); } @Override @@ -232,4 +235,21 @@ public class IRadioDataImpl extends IRadioData.Stub { public int getInterfaceVersion() { return IRadioData.VERSION; } + + public void unsolEmptyDataCallList() { + Log.d(TAG, "unsolEmptyDataCallList"); + + if (mRadioDataIndication != null) { + android.hardware.radio.data.SetupDataCallResult[] dcList = + new android.hardware.radio.data.SetupDataCallResult[0]; + + try { + mRadioDataIndication.dataCallListChanged(RadioIndicationType.UNSOLICITED, dcList); + } catch (RemoteException ex) { + Log.e(TAG, "Failed to invoke dataCallListChanged change from AIDL. Exception" + ex); + } + } else { + Log.e(TAG, "null mRadioDataIndication"); + } + } } diff --git a/tests/tests/telephony/current/src/android/telephony/cts/IRadioMessagingImpl.java b/tests/tests/telephony/current/mockmodem/src/android/telephony/mockmodem/IRadioMessagingImpl.java index b923a2f00b0..87a52354d80 100644 --- a/tests/tests/telephony/current/src/android/telephony/cts/IRadioMessagingImpl.java +++ b/tests/tests/telephony/current/mockmodem/src/android/telephony/mockmodem/IRadioMessagingImpl.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package android.telephony.cts; +package android.telephony.mockmodem; import android.hardware.radio.RadioError; import android.hardware.radio.RadioIndicationType; @@ -23,14 +23,22 @@ import android.hardware.radio.messaging.IRadioMessaging; import android.hardware.radio.messaging.IRadioMessagingIndication; import android.hardware.radio.messaging.IRadioMessagingResponse; import android.os.RemoteException; +import android.support.annotation.GuardedBy; +import android.util.ArraySet; import android.util.Log; +import java.util.Set; + public class IRadioMessagingImpl extends IRadioMessaging.Stub { private static final String TAG = "MRMSG"; private final MockModemService mService; private IRadioMessagingResponse mRadioMessagingResponse; private IRadioMessagingIndication mRadioMessagingIndication; + @GuardedBy("mGsmBroadcastConfigSet") + private final Set<Integer> mGsmBroadcastConfigSet = new ArraySet<Integer>(); + @GuardedBy("mCdmaBroadcastConfigSet") + private final Set<Integer> mCdmaBroadcastConfigSet = new ArraySet<Integer>(); public IRadioMessagingImpl(MockModemService service) { Log.d(TAG, "Instantiated"); @@ -244,7 +252,20 @@ public class IRadioMessagingImpl extends IRadioMessaging.Stub { int serial, android.hardware.radio.messaging.CdmaBroadcastSmsConfigInfo[] configInfo) { Log.d(TAG, "setCdmaBroadcastConfig"); - RadioResponseInfo rsp = mService.makeSolRsp(serial, RadioError.REQUEST_NOT_SUPPORTED); + int error = RadioError.NONE; + if (configInfo == null || configInfo.length == 0) { + error = RadioError.INVALID_ARGUMENTS; + } else { + synchronized (mCdmaBroadcastConfigSet) { + mCdmaBroadcastConfigSet.clear(); + for (int i = 0; i < configInfo.length; i++) { + Log.d(TAG, "configInfo serviceCategory" + + configInfo[i].serviceCategory); + mCdmaBroadcastConfigSet.add(configInfo[i].serviceCategory); + } + } + } + RadioResponseInfo rsp = mService.makeSolRsp(serial, error); try { mRadioMessagingResponse.setCdmaBroadcastConfigResponse(rsp); } catch (RemoteException ex) { @@ -269,7 +290,27 @@ public class IRadioMessagingImpl extends IRadioMessaging.Stub { int serial, android.hardware.radio.messaging.GsmBroadcastSmsConfigInfo[] configInfo) { Log.d(TAG, "setGsmBroadcastConfig"); - RadioResponseInfo rsp = mService.makeSolRsp(serial, RadioError.REQUEST_NOT_SUPPORTED); + int error = RadioError.NONE; + if (configInfo == null || configInfo.length == 0) { + error = RadioError.INVALID_ARGUMENTS; + } else { + synchronized (mGsmBroadcastConfigSet) { + mGsmBroadcastConfigSet.clear(); + for (int i = 0; i < configInfo.length; i++) { + int startId = configInfo[i].fromServiceId; + int endId = configInfo[i].toServiceId; + boolean selected = configInfo[i].selected; + Log.d(TAG, "configInfo from: " + startId + ", to: " + endId + + ", selected: " + selected); + if (selected) { + for (int j = startId; j <= endId; j++) { + mGsmBroadcastConfigSet.add(j); + } + } + } + } + } + RadioResponseInfo rsp = mService.makeSolRsp(serial, error); try { mRadioMessagingResponse.setGsmBroadcastConfigResponse(rsp); } catch (RemoteException ex) { @@ -425,4 +466,18 @@ public class IRadioMessagingImpl extends IRadioMessaging.Stub { public int getInterfaceVersion() { return IRadioMessaging.VERSION; } + + public Set<Integer> getGsmBroadcastConfigSet() { + synchronized (mGsmBroadcastConfigSet) { + Log.d(TAG, "getBroadcastConfigSet. " + mGsmBroadcastConfigSet); + return mGsmBroadcastConfigSet; + } + } + + public Set<Integer> getCdmaBroadcastConfigSet() { + synchronized (mCdmaBroadcastConfigSet) { + Log.d(TAG, "getBroadcastConfigSet. " + mCdmaBroadcastConfigSet); + return mCdmaBroadcastConfigSet; + } + } } diff --git a/tests/tests/telephony/current/src/android/telephony/cts/IRadioModemImpl.java b/tests/tests/telephony/current/mockmodem/src/android/telephony/mockmodem/IRadioModemImpl.java index 8f6a9a9a269..dbdda3c7546 100644 --- a/tests/tests/telephony/current/src/android/telephony/cts/IRadioModemImpl.java +++ b/tests/tests/telephony/current/mockmodem/src/android/telephony/mockmodem/IRadioModemImpl.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package android.telephony.cts; +package android.telephony.mockmodem; import static com.android.internal.telephony.RILConstants.RIL_REQUEST_RADIO_POWER; diff --git a/tests/tests/telephony/current/src/android/telephony/cts/IRadioNetworkImpl.java b/tests/tests/telephony/current/mockmodem/src/android/telephony/mockmodem/IRadioNetworkImpl.java index fb3dbca39af..9b64082cbe6 100644 --- a/tests/tests/telephony/current/src/android/telephony/cts/IRadioNetworkImpl.java +++ b/tests/tests/telephony/current/mockmodem/src/android/telephony/mockmodem/IRadioNetworkImpl.java @@ -14,16 +14,22 @@ * limitations under the License. */ -package android.telephony.cts; +package android.telephony.mockmodem; import android.hardware.radio.RadioError; +import android.hardware.radio.RadioIndicationType; import android.hardware.radio.RadioResponseInfo; import android.hardware.radio.network.IRadioNetwork; import android.hardware.radio.network.IRadioNetworkIndication; import android.hardware.radio.network.IRadioNetworkResponse; import android.hardware.radio.network.NetworkScanRequest; import android.hardware.radio.network.RadioAccessSpecifier; +import android.hardware.radio.network.RegState; import android.hardware.radio.network.SignalThresholdInfo; +import android.hardware.radio.sim.CardStatus; +import android.os.AsyncResult; +import android.os.Handler; +import android.os.Message; import android.os.RemoteException; import android.util.Log; @@ -33,20 +39,181 @@ public class IRadioNetworkImpl extends IRadioNetwork.Stub { private final MockModemService mService; private IRadioNetworkResponse mRadioNetworkResponse; private IRadioNetworkIndication mRadioNetworkIndication; + private static MockModemConfigInterface[] sMockModemConfigInterfaces; + private Object mCacheUpdateMutex; + private final Handler mHandler; + private int mSubId; - public IRadioNetworkImpl(MockModemService service) { + // ***** Events + static final int EVENT_RADIO_STATE_CHANGED = 1; + static final int EVENT_SIM_STATUS_CHANGED = 2; + static final int EVENT_PREFERRED_MODE_CHANGED = 3; + + // ***** Cache of modem attributes/status + private int mNetworkTypeBitmap; + private int mReasonForDenial; + private boolean mNetworkSelectionMode; + + private int mRadioState; + private boolean mSimReady; + + private MockNetworkService mServiceState; + + public IRadioNetworkImpl( + MockModemService service, MockModemConfigInterface[] interfaces, int instanceId) { Log.d(TAG, "Instantiated"); this.mService = service; + sMockModemConfigInterfaces = interfaces; + mCacheUpdateMutex = new Object(); + mHandler = new IRadioNetworkHandler(); + mSubId = instanceId; + mServiceState = new MockNetworkService(); + + // Default network type GPRS|EDGE|UMTS|HSDPA|HSUPA|HSPA|LTE|HSPA+|GSM|LTE_CA|NR + mNetworkTypeBitmap = + MockNetworkService.GSM + | MockNetworkService.WCDMA + | MockNetworkService.LTE + | MockNetworkService.NR; + mServiceState.updateHighestRegisteredRat(mNetworkTypeBitmap); + + sMockModemConfigInterfaces[mSubId].registerForRadioStateChanged( + mHandler, EVENT_RADIO_STATE_CHANGED, null); + sMockModemConfigInterfaces[mSubId].registerForCardStatusChanged( + mHandler, EVENT_SIM_STATUS_CHANGED, null); + } + + /** Handler class to handle callbacks */ + private final class IRadioNetworkHandler extends Handler { + @Override + public void handleMessage(Message msg) { + AsyncResult ar; + synchronized (mCacheUpdateMutex) { + switch (msg.what) { + case EVENT_SIM_STATUS_CHANGED: + Log.d(TAG, "Received EVENT_SIM_STATUS_CHANGED"); + boolean oldSimReady = mSimReady; + ar = (AsyncResult) msg.obj; + if (ar != null && ar.exception == null) { + mSimReady = updateSimReady(ar); + if (oldSimReady != mSimReady) { + updateNetworkStatus(); + } + } else { + Log.e(TAG, msg.what + " failure. Exception: " + ar.exception); + } + break; + + case EVENT_RADIO_STATE_CHANGED: + Log.d(TAG, "Received EVENT_RADIO_STATE_CHANGED"); + int oldRadioState = mRadioState; + ar = (AsyncResult) msg.obj; + if (ar != null && ar.exception == null) { + mRadioState = (int) ar.result; + Log.i(TAG, "Radio state: " + mRadioState); + if (oldRadioState != mRadioState) { + updateNetworkStatus(); + } + } else { + Log.e(TAG, msg.what + " failure. Exception: " + ar.exception); + } + break; + + case EVENT_PREFERRED_MODE_CHANGED: + Log.d(TAG, "Received EVENT_PREFERRED_MODE_CHANGED"); + mServiceState.updateNetworkStatus( + MockNetworkService.NETWORK_UPDATE_PREFERRED_MODE_CHANGE); + updateNetworkStatus(); + break; + } + } + } + } + + // Implementation of IRadioNetwork utility functions + + private void notifyServiceStateChange() { + Log.d(TAG, "notifyServiceStateChange"); + + Handler handler = sMockModemConfigInterfaces[mSubId].getMockModemConfigHandler(); + Message msg = + handler.obtainMessage( + MockModemConfigBase.EVENT_SERVICE_STATE_CHANGE, mServiceState); + handler.sendMessage(msg); + } + + private void updateNetworkStatus() { + + if (mRadioState != MockModemConfigInterface.RADIO_STATE_ON) { + // Update to OOS state + mServiceState.updateServiceState(RegState.NOT_REG_MT_NOT_SEARCHING_OP); + } else if (!mSimReady) { + // Update to Searching state + mServiceState.updateServiceState(RegState.NOT_REG_MT_SEARCHING_OP); + } else if (mServiceState.isHomeCellExisted() && mServiceState.getIsHomeCamping()) { + // Update to Home state + mServiceState.updateServiceState(RegState.REG_HOME); + } else if (mServiceState.isRoamingCellExisted() && mServiceState.getIsRoamingCamping()) { + // Update to Roaming state + mServiceState.updateServiceState(RegState.REG_ROAMING); + } else { + // Update to Searching state + mServiceState.updateServiceState(RegState.NOT_REG_MT_SEARCHING_OP); + } + + unsolNetworkStateChanged(); + unsolCurrentSignalStrength(); + unsolCellInfoList(); + } + + private boolean updateSimReady(AsyncResult ar) { + String simPlmn = ""; + CardStatus cardStatus = new CardStatus(); + cardStatus = (CardStatus) ar.result; + + if (cardStatus.cardState != CardStatus.STATE_PRESENT) { + return false; + } + + int numApplications = cardStatus.applications.length; + if (numApplications < 1) { + return false; + } + + for (int i = 0; i < numApplications; i++) { + android.hardware.radio.sim.AppStatus rilAppStatus = cardStatus.applications[i]; + if (rilAppStatus.appState == android.hardware.radio.sim.AppStatus.APP_STATE_READY) { + Log.i(TAG, "SIM is ready"); + simPlmn = "46692"; // TODO: Get SIM PLMN, maybe decode from IMSI + mServiceState.updateSimPlmn(simPlmn); + return true; + } + } + + mServiceState.updateSimPlmn(simPlmn); + return false; + } + + public boolean changeNetworkService(int carrierId, boolean registration) { + Log.d(TAG, "changeNetworkService: carrier id(" + carrierId + "): " + registration); + + synchronized (mCacheUpdateMutex) { + // TODO: compare carrierId and sim to decide home or roming + mServiceState.setServiceStatus(false, registration); + updateNetworkStatus(); + } + + return true; } // Implementation of IRadioNetwork functions @Override public void getAllowedNetworkTypesBitmap(int serial) { Log.d(TAG, "getAllowedNetworkTypesBitmap"); - int networkTypeBitmap = 0; - RadioResponseInfo rsp = mService.makeSolRsp(serial, RadioError.REQUEST_NOT_SUPPORTED); + int networkTypeBitmap = mNetworkTypeBitmap; + RadioResponseInfo rsp = mService.makeSolRsp(serial); try { mRadioNetworkResponse.getAllowedNetworkTypesBitmapResponse(rsp, networkTypeBitmap); } catch (RemoteException ex) { @@ -112,12 +279,15 @@ public class IRadioNetworkImpl extends IRadioNetwork.Stub { @Override public void getCellInfoList(int serial) { Log.d(TAG, "getCellInfoList"); + android.hardware.radio.network.CellInfo[] cells; - android.hardware.radio.network.CellInfo[] cellInfo = - new android.hardware.radio.network.CellInfo[0]; - RadioResponseInfo rsp = mService.makeSolRsp(serial, RadioError.REQUEST_NOT_SUPPORTED); + synchronized (mCacheUpdateMutex) { + cells = mServiceState.getCells(); + } + + RadioResponseInfo rsp = mService.makeSolRsp(serial); try { - mRadioNetworkResponse.getCellInfoListResponse(rsp, cellInfo); + mRadioNetworkResponse.getCellInfoListResponse(rsp, cells); } catch (RemoteException ex) { Log.e(TAG, "Failed to getCellInfoList from AIDL. Exception" + ex); } @@ -129,9 +299,25 @@ public class IRadioNetworkImpl extends IRadioNetwork.Stub { android.hardware.radio.network.RegStateResult dataRegResponse = new android.hardware.radio.network.RegStateResult(); + + dataRegResponse.cellIdentity = new android.hardware.radio.network.CellIdentity(); + dataRegResponse.reasonForDenial = mReasonForDenial; + + synchronized (mCacheUpdateMutex) { + dataRegResponse.regState = + mServiceState.getRegistration(android.hardware.radio.network.Domain.PS); + dataRegResponse.rat = mServiceState.getRegistrationRat(); + if (mServiceState.isInService()) { + dataRegResponse.registeredPlmn = + mServiceState.getPrimaryCellOperatorInfo().operatorNumeric; + } + + dataRegResponse.cellIdentity = mServiceState.getPrimaryCellIdentity(); + } + + // TODO: support accessTechnologySpecificInfo dataRegResponse.accessTechnologySpecificInfo = android.hardware.radio.network.AccessTechnologySpecificInfo.noinit(true); - dataRegResponse.cellIdentity = android.hardware.radio.network.CellIdentity.noinit(true); RadioResponseInfo rsp = mService.makeSolRsp(serial); try { @@ -157,10 +343,10 @@ public class IRadioNetworkImpl extends IRadioNetwork.Stub { @Override public void getNetworkSelectionMode(int serial) { Log.d(TAG, "getNetworkSelectionMode"); - boolean manual = false; - RadioResponseInfo rsp = mService.makeSolRsp(serial, RadioError.REQUEST_NOT_SUPPORTED); + + RadioResponseInfo rsp = mService.makeSolRsp(serial); try { - mRadioNetworkResponse.getNetworkSelectionModeResponse(rsp, manual); + mRadioNetworkResponse.getNetworkSelectionModeResponse(rsp, mNetworkSelectionMode); } catch (RemoteException ex) { Log.e(TAG, "Failed to getNetworkSelectionMode from AIDL. Exception" + ex); } @@ -173,7 +359,17 @@ public class IRadioNetworkImpl extends IRadioNetwork.Stub { String longName = ""; String shortName = ""; String numeric = ""; - RadioResponseInfo rsp = mService.makeSolRsp(serial, RadioError.REQUEST_NOT_SUPPORTED); + + synchronized (mCacheUpdateMutex) { + if (mServiceState.isInService()) { + android.hardware.radio.network.OperatorInfo operatorInfo = + mServiceState.getPrimaryCellOperatorInfo(); + longName = operatorInfo.alphaLong; + shortName = operatorInfo.alphaShort; + numeric = operatorInfo.operatorNumeric; + } + } + RadioResponseInfo rsp = mService.makeSolRsp(serial); try { mRadioNetworkResponse.getOperatorResponse(rsp, longName, shortName, numeric); } catch (RemoteException ex) { @@ -187,7 +383,15 @@ public class IRadioNetworkImpl extends IRadioNetwork.Stub { android.hardware.radio.network.SignalStrength signalStrength = new android.hardware.radio.network.SignalStrength(); - RadioResponseInfo rsp = mService.makeSolRsp(serial, RadioError.REQUEST_NOT_SUPPORTED); + + synchronized (mCacheUpdateMutex) { + if (mServiceState.getIsHomeCamping() + && mRadioState == MockModemConfigInterface.RADIO_STATE_ON) { + signalStrength = mServiceState.getSignalStrength(); + } + } + + RadioResponseInfo rsp = mService.makeSolRsp(serial); try { mRadioNetworkResponse.getSignalStrengthResponse(rsp, signalStrength); } catch (RemoteException ex) { @@ -212,8 +416,13 @@ public class IRadioNetworkImpl extends IRadioNetwork.Stub { @Override public void getVoiceRadioTechnology(int serial) { Log.d(TAG, "getVoiceRadioTechnology"); - int rat = 0; - RadioResponseInfo rsp = mService.makeSolRsp(serial, RadioError.REQUEST_NOT_SUPPORTED); + int rat; + + synchronized (mCacheUpdateMutex) { + rat = mServiceState.getRegistrationRat(); + } + + RadioResponseInfo rsp = mService.makeSolRsp(serial); try { mRadioNetworkResponse.getVoiceRadioTechnologyResponse(rsp, rat); } catch (RemoteException ex) { @@ -227,9 +436,25 @@ public class IRadioNetworkImpl extends IRadioNetwork.Stub { android.hardware.radio.network.RegStateResult voiceRegResponse = new android.hardware.radio.network.RegStateResult(); + + voiceRegResponse.cellIdentity = new android.hardware.radio.network.CellIdentity(); + voiceRegResponse.reasonForDenial = mReasonForDenial; + + synchronized (mCacheUpdateMutex) { + voiceRegResponse.regState = + mServiceState.getRegistration(android.hardware.radio.network.Domain.CS); + voiceRegResponse.rat = mServiceState.getRegistrationRat(); + if (mServiceState.isInService()) { + voiceRegResponse.registeredPlmn = + mServiceState.getPrimaryCellOperatorInfo().operatorNumeric; + } + + voiceRegResponse.cellIdentity = mServiceState.getPrimaryCellIdentity(); + } + + // TODO: support accessTechnologySpecificInfo voiceRegResponse.accessTechnologySpecificInfo = android.hardware.radio.network.AccessTechnologySpecificInfo.noinit(true); - voiceRegResponse.cellIdentity = android.hardware.radio.network.CellIdentity.noinit(true); RadioResponseInfo rsp = mService.makeSolRsp(serial); try { @@ -259,8 +484,19 @@ public class IRadioNetworkImpl extends IRadioNetwork.Stub { @Override public void setAllowedNetworkTypesBitmap(int serial, int networkTypeBitmap) { Log.d(TAG, "setAllowedNetworkTypesBitmap"); + boolean isModeChange = false; - RadioResponseInfo rsp = mService.makeSolRsp(serial, RadioError.REQUEST_NOT_SUPPORTED); + if (mNetworkTypeBitmap != networkTypeBitmap) { + mNetworkTypeBitmap = networkTypeBitmap; + synchronized (mCacheUpdateMutex) { + isModeChange = mServiceState.updateHighestRegisteredRat(mNetworkTypeBitmap); + } + if (isModeChange) { + mHandler.obtainMessage(EVENT_PREFERRED_MODE_CHANGED).sendToTarget(); + } + } + + RadioResponseInfo rsp = mService.makeSolRsp(serial); try { mRadioNetworkResponse.setAllowedNetworkTypesBitmapResponse(rsp); } catch (RemoteException ex) { @@ -515,4 +751,71 @@ public class IRadioNetworkImpl extends IRadioNetwork.Stub { public int getInterfaceVersion() { return IRadioNetwork.VERSION; } + + public void unsolNetworkStateChanged() { + Log.d(TAG, "unsolNetworkStateChanged"); + + // Notify other module + notifyServiceStateChange(); + + if (mRadioNetworkIndication != null) { + try { + mRadioNetworkIndication.networkStateChanged(RadioIndicationType.UNSOLICITED); + } catch (RemoteException ex) { + Log.e(TAG, "Failed to invoke networkStateChanged from AIDL. Exception" + ex); + } + } else { + Log.e(TAG, "null mRadioNetworkIndication"); + } + } + + public void unsolCurrentSignalStrength() { + Log.d(TAG, "unsolCurrentSignalStrength"); + if (mRadioState != MockModemConfigInterface.RADIO_STATE_ON) { + return; + } + + if (mRadioNetworkIndication != null) { + android.hardware.radio.network.SignalStrength signalStrength = + new android.hardware.radio.network.SignalStrength(); + + synchronized (mCacheUpdateMutex) { + signalStrength = mServiceState.getSignalStrength(); + } + + try { + mRadioNetworkIndication.currentSignalStrength( + RadioIndicationType.UNSOLICITED, signalStrength); + } catch (RemoteException ex) { + Log.e( + TAG, + "Failed to invoke currentSignalStrength change from AIDL. Exception" + ex); + } + } else { + Log.e(TAG, "null mRadioNetworkIndication"); + } + } + + public void unsolCellInfoList() { + Log.d(TAG, "unsolCellInfoList"); + + if (mRadioState != MockModemConfigInterface.RADIO_STATE_ON) { + return; + } + + if (mRadioNetworkIndication != null) { + android.hardware.radio.network.CellInfo[] cells; + + synchronized (mCacheUpdateMutex) { + cells = mServiceState.getCells(); + } + try { + mRadioNetworkIndication.cellInfoList(RadioIndicationType.UNSOLICITED, cells); + } catch (RemoteException ex) { + Log.e(TAG, "Failed to invoke cellInfoList change from AIDL. Exception" + ex); + } + } else { + Log.e(TAG, "null mRadioNetworkIndication"); + } + } } diff --git a/tests/tests/telephony/current/src/android/telephony/cts/IRadioSimImpl.java b/tests/tests/telephony/current/mockmodem/src/android/telephony/mockmodem/IRadioSimImpl.java index b6e9d001431..7863d53732d 100644 --- a/tests/tests/telephony/current/src/android/telephony/cts/IRadioSimImpl.java +++ b/tests/tests/telephony/current/mockmodem/src/android/telephony/mockmodem/IRadioSimImpl.java @@ -14,7 +14,11 @@ * limitations under the License. */ -package android.telephony.cts; +package android.telephony.mockmodem; + +import static android.telephony.mockmodem.MockSimService.COMMAND_GET_RESPONSE; +import static android.telephony.mockmodem.MockSimService.COMMAND_READ_BINARY; +import static android.telephony.mockmodem.MockSimService.EF_ICCID; import android.hardware.radio.RadioError; import android.hardware.radio.RadioIndicationType; @@ -23,18 +27,19 @@ import android.hardware.radio.sim.CardStatus; import android.hardware.radio.sim.IRadioSim; import android.hardware.radio.sim.IRadioSimIndication; import android.hardware.radio.sim.IRadioSimResponse; +import android.hardware.radio.sim.SimRefreshResult; import android.os.AsyncResult; import android.os.Handler; import android.os.Message; import android.os.RemoteException; -import android.telephony.cts.MockSimService.SimAppData; +import android.telephony.mockmodem.MockModemConfigBase.SimInfoChangedResult; +import android.telephony.mockmodem.MockSimService.SimAppData; import android.util.Log; import java.util.ArrayList; public class IRadioSimImpl extends IRadioSim.Stub { private static final String TAG = "MRSIM"; - private final MockModemService mService; private IRadioSimResponse mRadioSimResponse; private IRadioSimIndication mRadioSimIndication; @@ -46,6 +51,7 @@ public class IRadioSimImpl extends IRadioSim.Stub { // ***** Events static final int EVENT_SIM_CARD_STATUS_CHANGED = 1; static final int EVENT_SIM_APP_DATA_CHANGED = 2; + static final int EVENT_SIM_INFO_CHANGED = 3; // ***** Cache of modem attributes/status private int mNumOfLogicalSim; @@ -71,6 +77,10 @@ public class IRadioSimImpl extends IRadioSim.Stub { // Register events sMockModemConfigInterfaces[mSubId].registerForSimAppDataChanged( mHandler, EVENT_SIM_APP_DATA_CHANGED, null); + + // Register events + sMockModemConfigInterfaces[mSubId].registerForSimInfoChanged( + mHandler, EVENT_SIM_INFO_CHANGED, null); } /** Handler class to handle callbacks */ @@ -106,6 +116,30 @@ public class IRadioSimImpl extends IRadioSim.Stub { Log.e(TAG, msg.what + " failure. Exception: " + ar.exception); } break; + + case EVENT_SIM_INFO_CHANGED: + ar = (AsyncResult) msg.obj; + if (ar != null && ar.exception == null) { + SimInfoChangedResult simInfoChangeResult = + (SimInfoChangedResult) ar.result; + Log.d(TAG, "Received EVENT_SIM_INFO_CHANGED: " + simInfoChangeResult); + SimRefreshResult simRefreshResult = new SimRefreshResult(); + switch (simInfoChangeResult.mSimInfoType) { + case SimInfoChangedResult.SIM_INFO_TYPE_MCC_MNC: + case SimInfoChangedResult.SIM_INFO_TYPE_IMSI: + if (simRefreshResult != null) { + simRefreshResult.type = + SimRefreshResult.TYPE_SIM_FILE_UPDATE; + simRefreshResult.efId = simInfoChangeResult.mEfId; + simRefreshResult.aid = simInfoChangeResult.mAid; + simRefresh(simRefreshResult); + } + break; + } + } else { + Log.e(TAG, msg.what + " failure. Exception: " + ar.exception); + } + break; } } } @@ -244,26 +278,28 @@ public class IRadioSimImpl extends IRadioSim.Stub { boolean isFacilitySupport = true; int responseData = -1; - // TODO: check service class - for (simAppIdx = 0; - simAppIdx < numOfSimApp && isFacilitySupport && !isHandled; - simAppIdx++) { - switch (facility) { - case "FD": // FDN status query - if (appId.equals(mSimAppList.get(simAppIdx).getAid())) { - responseData = mSimAppList.get(simAppIdx).getFdnStatus(); - isHandled = true; - } - break; - case "SC": // PIN1 status query - if (appId.equals(mSimAppList.get(simAppIdx).getAid())) { - responseData = mSimAppList.get(simAppIdx).getPin1State(); - isHandled = true; - } - break; - default: - isFacilitySupport = false; - break; + synchronized (mCacheUpdateMutex) { + // TODO: check service class + for (simAppIdx = 0; + simAppIdx < numOfSimApp && isFacilitySupport && !isHandled; + simAppIdx++) { + switch (facility) { + case "FD": // FDN status query + if (appId.equals(mSimAppList.get(simAppIdx).getAid())) { + responseData = mSimAppList.get(simAppIdx).getFdnStatus(); + isHandled = true; + } + break; + case "SC": // PIN1 status query + if (appId.equals(mSimAppList.get(simAppIdx).getAid())) { + responseData = mSimAppList.get(simAppIdx).getPin1State(); + isHandled = true; + } + break; + default: + isFacilitySupport = false; + break; + } } } @@ -311,10 +347,14 @@ public class IRadioSimImpl extends IRadioSim.Stub { int simAppIdx; boolean isHandled; - for (simAppIdx = 0, isHandled = false; simAppIdx < numOfSimApp && !isHandled; simAppIdx++) { - if (aid.equals(mSimAppList.get(simAppIdx).getAid())) { - imsi = mSimAppList.get(simAppIdx).getImsi(); - isHandled = true; + synchronized (mCacheUpdateMutex) { + for (simAppIdx = 0, isHandled = false; + simAppIdx < numOfSimApp && !isHandled; + simAppIdx++) { + if (aid.equals(mSimAppList.get(simAppIdx).getAid())) { + imsi = mSimAppList.get(simAppIdx).getImsi(); + isHandled = true; + } } } @@ -371,14 +411,117 @@ public class IRadioSimImpl extends IRadioSim.Stub { } } + private String encodeBcdString(String str) { + StringBuffer bcdString = new StringBuffer(); + + if (str.length() % 2 != 0) { + Log.d(TAG, "Invalid string(" + str + ") for Bcd format"); + return ""; + } + + for (int i = 0; i < str.length(); i += 2) { + bcdString.append(str.substring(i + 1, i + 2)); + bcdString.append(str.substring(i, i + 1)); + } + + return bcdString.toString(); + } + + private int getIccIoResult( + android.hardware.radio.sim.IccIoResult iccIoResult, + int command, + int fileId, + String path, + int p1, + int p2, + int p3, + String aid) { + int numOfSimApp = mSimAppList.size(); + int simAppIdx; + boolean foundAid; + int responseError = RadioError.GENERIC_FAILURE; + + if (iccIoResult == null) { + return responseError; + } + + synchronized (mCacheUpdateMutex) { + for (simAppIdx = 0, foundAid = false; simAppIdx < numOfSimApp; simAppIdx++) { + if (aid.equals(mSimAppList.get(simAppIdx).getAid())) { + foundAid = true; + break; + } + } + + if (!foundAid) { + Log.e(TAG, "Not support sim application aid = " + aid); + iccIoResult.sw1 = 0x6A; + iccIoResult.sw2 = 0x82; + } else { + switch (fileId) { + case EF_ICCID: + if (command == COMMAND_READ_BINARY) { + String bcdIccid = + encodeBcdString(mSimAppList.get(simAppIdx).getIccid()); + iccIoResult.simResponse = bcdIccid; + Log.d(TAG, "Get IccIo result: ICCID = " + iccIoResult.simResponse); + iccIoResult.sw1 = 0x90; + responseError = RadioError.NONE; + } else if (command == COMMAND_GET_RESPONSE) { + iccIoResult.simResponse = mSimAppList.get(simAppIdx).getIccidInfo(); + Log.d(TAG, "Get IccIo result: ICCID = " + iccIoResult.simResponse); + iccIoResult.sw1 = 0x90; + responseError = RadioError.NONE; + } else { + Log.d( + TAG, + "Command(" + + command + + ") not support for file id = 0x" + + Integer.toHexString(fileId)); + iccIoResult.sw1 = 0x6A; + iccIoResult.sw2 = 0x82; + } + break; + default: + Log.d(TAG, "Not find EF file id = 0x" + Integer.toHexString(fileId)); + iccIoResult.sw1 = 0x6A; + iccIoResult.sw2 = 0x82; + break; + } + } + } + + return responseError; + } + @Override public void iccIoForApp(int serial, android.hardware.radio.sim.IccIo iccIo) { Log.d(TAG, "iccIoForApp"); - // TODO: cache value + int responseError = RadioError.NONE; android.hardware.radio.sim.IccIoResult iccIoResult = new android.hardware.radio.sim.IccIoResult(); - RadioResponseInfo rsp = mService.makeSolRsp(serial, RadioError.REQUEST_NOT_SUPPORTED); + switch (iccIo.command) { + case COMMAND_READ_BINARY: + case COMMAND_GET_RESPONSE: + responseError = + getIccIoResult( + iccIoResult, + iccIo.command, + iccIo.fileId, + iccIo.path, + iccIo.p1, + iccIo.p2, + iccIo.p3, + iccIo.aid); + break; + default: + responseError = RadioError.REQUEST_NOT_SUPPORTED; + break; + } + + RadioResponseInfo rsp = mService.makeSolRsp(serial, responseError); try { mRadioSimResponse.iccIoForAppResponse(rsp, iccIoResult); } catch (RemoteException ex) { @@ -739,7 +882,7 @@ public class IRadioSimImpl extends IRadioSim.Stub { } } - public void simRefresh(android.hardware.radio.sim.SimRefreshResult refreshResult) { + public void simRefresh(SimRefreshResult refreshResult) { Log.d(TAG, "simRefresh"); if (mRadioSimIndication != null) { diff --git a/tests/tests/telephony/current/src/android/telephony/cts/IRadioVoiceImpl.java b/tests/tests/telephony/current/mockmodem/src/android/telephony/mockmodem/IRadioVoiceImpl.java index c6fdfdf97be..1b525fdd645 100644 --- a/tests/tests/telephony/current/src/android/telephony/cts/IRadioVoiceImpl.java +++ b/tests/tests/telephony/current/mockmodem/src/android/telephony/mockmodem/IRadioVoiceImpl.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package android.telephony.cts; +package android.telephony.mockmodem; import android.hardware.radio.RadioError; import android.hardware.radio.RadioIndicationType; diff --git a/tests/tests/telephony/current/src/android/telephony/cts/MockModemConfigBase.java b/tests/tests/telephony/current/mockmodem/src/android/telephony/mockmodem/MockModemConfigBase.java index a77dd669e8b..86f6a74f258 100644 --- a/tests/tests/telephony/current/src/android/telephony/cts/MockModemConfigBase.java +++ b/tests/tests/telephony/current/mockmodem/src/android/telephony/mockmodem/MockModemConfigBase.java @@ -14,7 +14,9 @@ * limitations under the License. */ -package android.telephony.cts; +package android.telephony.mockmodem; + +import static android.telephony.mockmodem.MockSimService.EF_ICCID; import android.content.Context; import android.hardware.radio.config.PhoneCapability; @@ -23,13 +25,15 @@ import android.hardware.radio.config.SimSlotStatus; import android.hardware.radio.config.SlotPortMapping; import android.hardware.radio.sim.CardStatus; import android.os.AsyncResult; +import android.os.Bundle; import android.os.Handler; import android.os.Message; import android.os.RegistrantList; -import android.telephony.cts.MockSimService.SimAppData; +import android.telephony.mockmodem.MockSimService.SimAppData; import android.util.Log; import java.util.ArrayList; +import java.util.Random; public class MockModemConfigBase implements MockModemConfigInterface { // ***** Instance Variables @@ -39,13 +43,15 @@ public class MockModemConfigBase implements MockModemConfigInterface { private Context mContext; private int mSubId; private int mSimPhyicalId; - private Object mConfigAccess; + private final Object mConfigAccess = new Object(); private int mNumOfSim = MockModemConfigInterface.MAX_NUM_OF_SIM_SLOT; private int mNumOfPhone = MockModemConfigInterface.MAX_NUM_OF_LOGICAL_MODEM; // ***** Events static final int EVENT_SET_RADIO_POWER = 1; static final int EVENT_CHANGE_SIM_PROFILE = 2; + static final int EVENT_SERVICE_STATE_CHANGE = 3; + static final int EVENT_SET_SIM_INFO = 4; // ***** Modem config values private String mBasebandVersion = MockModemConfigInterface.DEFAULT_BASEBAND_VERSION; @@ -76,6 +82,10 @@ public class MockModemConfigBase implements MockModemConfigInterface { // ***** IRadioSim RegistrantLists private RegistrantList mCardStatusChangedRegistrants = new RegistrantList(); private RegistrantList mSimAppDataChangedRegistrants = new RegistrantList(); + private RegistrantList mSimInfoChangedRegistrants = new RegistrantList(); + + // ***** IRadioNetwork RegistrantLists + private RegistrantList mServiceStateChangedRegistrants = new RegistrantList(); public MockModemConfigBase(Context context, int instanceId, int numOfSim, int numOfPhone) { mContext = context; @@ -89,7 +99,6 @@ public class MockModemConfigBase implements MockModemConfigInterface { ? MockModemConfigInterface.MAX_NUM_OF_LOGICAL_MODEM : numOfPhone; mTAG = mTAG + "[" + mSubId + "]"; - mConfigAccess = new Object(); mHandler = new MockModemConfigHandler(); mSimSlotStatus = new SimSlotStatus[mNumOfSim]; mCardStatus = new CardStatus(); @@ -99,6 +108,33 @@ public class MockModemConfigBase implements MockModemConfigInterface { setDefaultConfigValue(); } + public static class SimInfoChangedResult { + public static final int SIM_INFO_TYPE_MCC_MNC = 1; + public static final int SIM_INFO_TYPE_IMSI = 2; + public static final int SIM_INFO_TYPE_ATR = 3; + + public int mSimInfoType; + public int mEfId; + public String mAid; + + public SimInfoChangedResult(int type, int efid, String aid) { + mSimInfoType = type; + mEfId = efid; + mAid = aid; + } + + @Override + public String toString() { + return "SimInfoChangedResult:" + + " simInfoType=" + + mSimInfoType + + " efId=" + + mEfId + + " aId=" + + mAid; + } + } + public class MockModemConfigHandler extends Handler { // ***** Handler implementation @Override @@ -145,11 +181,63 @@ public class MockModemConfigBase implements MockModemConfigInterface { Log.e(mTAG, "Load Sim card failed."); } break; + case EVENT_SERVICE_STATE_CHANGE: + Log.d(mTAG, "EVENT_SERVICE_STATE_CHANGE"); + // Notify object MockNetworkService + mServiceStateChangedRegistrants.notifyRegistrants( + new AsyncResult(null, msg.obj, null)); + break; + case EVENT_SET_SIM_INFO: + int simInfoType = msg.getData().getInt("setSimInfo:type", -1); + String[] simInfoData = msg.getData().getStringArray("setSimInfo:data"); + Log.d( + mTAG, + "EVENT_SET_SIM_INFO: type = " + + simInfoType + + " data length = " + + simInfoData.length); + for (int i = 0; i < simInfoData.length; i++) { + Log.d(mTAG, "simInfoData[" + i + "] = " + simInfoData[i]); + } + SimInfoChangedResult simInfoChangeResult = + setSimInfo(simInfoType, simInfoData); + if (simInfoChangeResult != null) { + switch (simInfoChangeResult.mSimInfoType) { + case SimInfoChangedResult.SIM_INFO_TYPE_MCC_MNC: + case SimInfoChangedResult.SIM_INFO_TYPE_IMSI: + mSimInfoChangedRegistrants.notifyRegistrants( + new AsyncResult(null, simInfoChangeResult, null)); + mSimAppDataChangedRegistrants.notifyRegistrants( + new AsyncResult(null, mSimAppList, null)); + // Card status changed still needed for updating carrier config + // in Telephony Framework + if (mSubId == DEFAULT_SUB_ID) { + mSimSlotStatusChangedRegistrants.notifyRegistrants( + new AsyncResult(null, mSimSlotStatus, null)); + } + mCardStatusChangedRegistrants.notifyRegistrants( + new AsyncResult(null, mCardStatus, null)); + break; + case SimInfoChangedResult.SIM_INFO_TYPE_ATR: + if (mSubId == DEFAULT_SUB_ID) { + mSimSlotStatusChangedRegistrants.notifyRegistrants( + new AsyncResult(null, mSimSlotStatus, null)); + } + mCardStatusChangedRegistrants.notifyRegistrants( + new AsyncResult(null, mCardStatus, null)); + break; + } + } + break; } } } } + public Handler getMockModemConfigHandler() { + return mHandler; + } + private void setDefaultConfigValue() { synchronized (mConfigAccess) { mBasebandVersion = MockModemConfigInterface.DEFAULT_BASEBAND_VERSION; @@ -181,7 +269,9 @@ public class MockModemConfigBase implements MockModemConfigInterface { private void createSIMCards() { for (int i = 0; i < mNumOfSim; i++) { - mSimService[i] = new MockSimService(mContext, i); + if (mSimService[i] == null) { + mSimService[i] = new MockSimService(mContext, i); + } } } @@ -259,6 +349,100 @@ public class MockModemConfigBase implements MockModemConfigInterface { return result; } + private String generateRandomIccid(String baseIccid) { + String newIccid; + Random rnd = new Random(); + StringBuilder randomNum = new StringBuilder(); + + // Generate random 12-digit account id + for (int i = 0; i < 12; i++) { + randomNum.append(rnd.nextInt(10)); + } + + Log.d(mTAG, "Random Num = " + randomNum.toString()); + + // TODO: regenerate checksum + // Simply modify account id from base Iccid + newIccid = + baseIccid.substring(0, 7) + + randomNum.toString() + + baseIccid.substring(baseIccid.length() - 1); + + Log.d(mTAG, "Generate new Iccid = " + newIccid); + + return newIccid; + } + + private SimInfoChangedResult setSimInfo(int simInfoType, String[] simInfoData) { + SimInfoChangedResult result = null; + + if (simInfoData == null) { + Log.e(mTAG, "simInfoData == null"); + return result; + } + + switch (simInfoType) { + case SimInfoChangedResult.SIM_INFO_TYPE_MCC_MNC: + if (simInfoData.length == 2 && simInfoData[0] != null && simInfoData[1] != null) { + String msin = mSimService[mSimPhyicalId].getMsin(); + + // Adjust msin length to make sure IMSI length is valid. + if (simInfoData[1].length() == 3 && msin.length() == 10) { + msin = msin.substring(0, msin.length() - 1); + Log.d(mTAG, "Modify msin = " + msin); + } + mSimService[mSimPhyicalId].setImsi(simInfoData[0], simInfoData[1], msin); + + // Auto-generate a new Iccid to change carrier config id in Android Framework + mSimService[mSimPhyicalId].setICCID( + generateRandomIccid(mSimService[mSimPhyicalId].getICCID())); + updateSimSlotStatus(); + updateCardStatus(); + + result = + new SimInfoChangedResult( + simInfoType, + EF_ICCID, + mSimService[mSimPhyicalId].getActiveSimAppId()); + } + break; + case SimInfoChangedResult.SIM_INFO_TYPE_IMSI: + if (simInfoData.length == 3 + && simInfoData[0] != null + && simInfoData[1] != null + && simInfoData[2] != null) { + mSimService[mSimPhyicalId].setImsi( + simInfoData[0], simInfoData[1], simInfoData[2]); + + // Auto-generate a new Iccid to change carrier config id in Android Framework + mSimService[mSimPhyicalId].setICCID( + generateRandomIccid(mSimService[mSimPhyicalId].getICCID())); + updateSimSlotStatus(); + updateCardStatus(); + + result = + new SimInfoChangedResult( + simInfoType, + EF_ICCID, + mSimService[mSimPhyicalId].getActiveSimAppId()); + } + break; + case SimInfoChangedResult.SIM_INFO_TYPE_ATR: + if (simInfoData[0] != null) { + mSimService[mSimPhyicalId].setATR(simInfoData[0]); + updateSimSlotStatus(); + updateCardStatus(); + result = new SimInfoChangedResult(simInfoType, 0, ""); + } + break; + default: + Log.e(mTAG, "Not support Sim info type(" + simInfoType + ") to modify"); + break; + } + + return result; + } + private void notifyDeviceIdentityChangedRegistrants() { String[] deviceIdentity = new String[4]; synchronized (mConfigAccess) { @@ -382,6 +566,27 @@ public class MockModemConfigBase implements MockModemConfigInterface { mSimAppDataChangedRegistrants.remove(h); } + @Override + public void registerForSimInfoChanged(Handler h, int what, Object obj) { + mSimInfoChangedRegistrants.addUnique(h, what, obj); + } + + @Override + public void unregisterForSimInfoChanged(Handler h) { + mSimInfoChangedRegistrants.remove(h); + } + + // ***** IRadioNetwork notification implementation + @Override + public void registerForServiceStateChanged(Handler h, int what, Object obj) { + mServiceStateChangedRegistrants.addUnique(h, what, obj); + } + + @Override + public void unregisterForServiceStateChanged(Handler h) { + mServiceStateChangedRegistrants.remove(h); + } + // ***** IRadioConfig set APIs implementation // ***** IRadioModem set APIs implementation @@ -408,7 +613,11 @@ public class MockModemConfigBase implements MockModemConfigInterface { @Override public boolean isSimCardPresent(String client) { Log.d(mTAG, "isSimCardPresent from: " + client); - return (mCardStatus.cardState == CardStatus.STATE_PRESENT) ? true : false; + boolean isPresent; + synchronized (mConfigAccess) { + isPresent = (mCardStatus.cardState == CardStatus.STATE_PRESENT) ? true : false; + } + return isPresent; } @Override @@ -419,4 +628,39 @@ public class MockModemConfigBase implements MockModemConfigInterface { msg.getData().putInt("changeSimProfile", simprofileid); mHandler.sendMessage(msg); } + + @Override + public void setSimInfo(int type, String[] data, String client) { + Log.d(mTAG, "setSimInfo: type(" + type + ") from: " + client); + Message msg = mHandler.obtainMessage(EVENT_SET_SIM_INFO); + Bundle bundle = msg.getData(); + bundle.putInt("setSimInfo:type", type); + bundle.putStringArray("setSimInfo:data", data); + mHandler.sendMessage(msg); + } + + @Override + public String getSimInfo(int type, String client) { + Log.d(mTAG, "getSimInfo: type(" + type + ") from: " + client); + String result = ""; + + synchronized (mConfigAccess) { + switch (type) { + case SimInfoChangedResult.SIM_INFO_TYPE_MCC_MNC: + result = mSimService[mSimPhyicalId].getMccMnc(); + break; + case SimInfoChangedResult.SIM_INFO_TYPE_IMSI: + result = mSimService[mSimPhyicalId].getImsi(); + break; + case SimInfoChangedResult.SIM_INFO_TYPE_ATR: + result = mCardStatus.atr; + break; + default: + Log.e(mTAG, "Not support this type of SIM info."); + break; + } + } + + return result; + } } diff --git a/tests/tests/telephony/current/src/android/telephony/cts/MockModemConfigInterface.java b/tests/tests/telephony/current/mockmodem/src/android/telephony/mockmodem/MockModemConfigInterface.java index 32b2908bd4b..5e5c181b9b9 100644 --- a/tests/tests/telephony/current/src/android/telephony/cts/MockModemConfigInterface.java +++ b/tests/tests/telephony/current/mockmodem/src/android/telephony/mockmodem/MockModemConfigInterface.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package android.telephony.cts; +package android.telephony.mockmodem; import android.os.Handler; @@ -42,6 +42,7 @@ public interface MockModemConfigInterface { int DEFAULT_LOGICAL_MODEM2_ID = 1; // ***** Methods + Handler getMockModemConfigHandler(); /** Broadcast all notifications */ void notifyAllRegistrantNotifications(); @@ -89,6 +90,17 @@ public interface MockModemConfigInterface { void unregisterForSimAppDataChanged(Handler h); + /** Register/unregister notification handler for sim info changed */ + void registerForSimInfoChanged(Handler h, int what, Object obj); + + void unregisterForSimInfoChanged(Handler h); + + // ***** IRadioNetwork + /** Register/unregister notification handler for service status changed */ + void registerForServiceStateChanged(Handler h, int what, Object obj); + + void unregisterForServiceStateChanged(Handler h); + /** * Sets the latest radio power state of modem * @@ -112,4 +124,22 @@ public interface MockModemConfigInterface { * @param client for tracking calling client */ void changeSimProfile(int simProfileId, String client); + + /** + * Modify SIM info of the SIM such as MCC/MNC, IMSI, etc. + * + * @param type the type of SIM info to modify. + * @param data to modify for the type of SIM info. + * @param client for tracking calling client + */ + void setSimInfo(int type, String[] data, String client); + + /** + * Get SIM info of the SIM slot, e.g. MCC/MNC, IMSI. + * + * @param type the type of SIM info. + * @param client for tracking calling client + * @return String the SIM info of the queried type. + */ + String getSimInfo(int type, String client); } diff --git a/tests/tests/telephony/current/src/android/telephony/cts/MockModemManager.java b/tests/tests/telephony/current/mockmodem/src/android/telephony/mockmodem/MockModemManager.java index 38e36ddb47b..772c7f8976f 100644 --- a/tests/tests/telephony/current/src/android/telephony/cts/MockModemManager.java +++ b/tests/tests/telephony/current/mockmodem/src/android/telephony/mockmodem/MockModemManager.java @@ -14,7 +14,9 @@ * limitations under the License. */ -package android.telephony.cts; +package android.telephony.mockmodem; + +import static android.telephony.mockmodem.MockSimService.MOCK_SIM_PROFILE_ID_DEFAULT; import static com.android.internal.telephony.RILConstants.RIL_REQUEST_RADIO_POWER; @@ -23,6 +25,7 @@ import android.util.Log; import androidx.test.InstrumentationRegistry; +import java.util.Set; import java.util.concurrent.TimeUnit; public class MockModemManager { @@ -48,7 +51,7 @@ public class MockModemManager { * @return boolean true if the operation is successful, otherwise false. */ public boolean connectMockModemService() throws Exception { - return connectMockModemService(MockSimService.MOCK_SIM_PROFILE_ID_DEFAULT); + return connectMockModemService(MOCK_SIM_PROFILE_ID_DEFAULT); } /** * Bring up Mock Modem Service and connect to it. @@ -114,35 +117,37 @@ public class MockModemManager { } /** - * Query whether an active SIM card is present on this sub or not. + * Query whether an active SIM card is present on this slot or not. * - * @param subId which sub would be checked. + * @param slotId which slot would be checked. * @return boolean true if any sim card inserted, otherwise false. */ - public boolean isSimCardPresent(int subId) throws Exception { - Log.d(TAG, "isSimCardPresent[" + subId + "]"); + public boolean isSimCardPresent(int slotId) throws Exception { + Log.d(TAG, "isSimCardPresent[" + slotId + "]"); MockModemConfigInterface[] configInterfaces = mMockModemService.getMockModemConfigInterfaces(); - return configInterfaces[subId].isSimCardPresent(TAG); + return (configInterfaces != null) ? configInterfaces[slotId].isSimCardPresent(TAG) : false; } /** * Insert a SIM card. * - * @param subId which sub would insert. + * @param slotId which slot would insert. * @param simProfileId which carrier sim card is inserted. * @return boolean true if the operation is successful, otherwise false. */ - public boolean insertSimCard(int subId, int simProfileId) throws Exception { - Log.d(TAG, "insertSimCard[" + subId + "] with profile Id(" + simProfileId + ")"); + public boolean insertSimCard(int slotId, int simProfileId) throws Exception { + Log.d(TAG, "insertSimCard[" + slotId + "] with profile Id(" + simProfileId + ")"); boolean result = true; - if (!isSimCardPresent(subId)) { + if (!isSimCardPresent(slotId)) { MockModemConfigInterface[] configInterfaces = mMockModemService.getMockModemConfigInterfaces(); - configInterfaces[subId].changeSimProfile(simProfileId, TAG); - waitForTelephonyFrameworkDone(1); + if (configInterfaces != null) { + configInterfaces[slotId].changeSimProfile(simProfileId, TAG); + waitForTelephonyFrameworkDone(1); + } } else { Log.d(TAG, "There is a SIM inserted. Need to remove first."); result = false; @@ -153,19 +158,51 @@ public class MockModemManager { /** * Remove a SIM card. * - * @param subId which sub would remove the SIM. + * @param slotId which slot would remove the SIM. + * @return boolean true if the operation is successful, otherwise false. + */ + public boolean removeSimCard(int slotId) throws Exception { + Log.d(TAG, "removeSimCard[" + slotId + "]"); + boolean result = true; + + if (isSimCardPresent(slotId)) { + MockModemConfigInterface[] configInterfaces = + mMockModemService.getMockModemConfigInterfaces(); + if (configInterfaces != null) { + configInterfaces[slotId].changeSimProfile(MOCK_SIM_PROFILE_ID_DEFAULT, TAG); + waitForTelephonyFrameworkDone(1); + } + } else { + Log.d(TAG, "There is no SIM inserted."); + result = false; + } + return result; + } + + /** + * Modify SIM info of the SIM such as MCC/MNC, IMSI, etc. + * + * @param slotId for modifying. + * @param type the type of SIM info to modify. + * @param data to modify for the type of SIM info. * @return boolean true if the operation is successful, otherwise false. */ - public boolean removeSimCard(int subId) throws Exception { - Log.d(TAG, "removeSimCard[" + subId + "]"); + public boolean setSimInfo(int slotId, int type, String[] data) throws Exception { + Log.d(TAG, "setSimInfo[" + slotId + "]"); boolean result = true; - if (isSimCardPresent(subId)) { + if (isSimCardPresent(slotId)) { MockModemConfigInterface[] configInterfaces = mMockModemService.getMockModemConfigInterfaces(); - configInterfaces[subId].changeSimProfile( - MockSimService.MOCK_SIM_PROFILE_ID_DEFAULT, TAG); - waitForTelephonyFrameworkDone(1); + if (configInterfaces != null) { + configInterfaces[slotId].setSimInfo(type, data, TAG); + + // Wait for telephony framework refresh data and carrier config + waitForTelephonyFrameworkDone(2); + } else { + Log.e(TAG, "MockModemConfigInterface == null!"); + result = false; + } } else { Log.d(TAG, "There is no SIM inserted."); result = false; @@ -174,18 +211,41 @@ public class MockModemManager { } /** + * Get SIM info of the SIM slot, e.g. MCC/MNC, IMSI. + * + * @param slotId for the query. + * @param type the type of SIM info. + * @return String the SIM info of the queried type. + */ + public String getSimInfo(int slotId, int type) throws Exception { + Log.d(TAG, "getSimInfo[" + slotId + "]"); + String result = ""; + + if (isSimCardPresent(slotId)) { + MockModemConfigInterface[] configInterfaces = + mMockModemService.getMockModemConfigInterfaces(); + if (configInterfaces != null) { + result = configInterfaces[slotId].getSimInfo(type, TAG); + } + } else { + Log.d(TAG, "There is no SIM inserted."); + } + return result; + } + + /** * Force the response error return for a specific RIL request * - * @param subId which sub needs to be set. + * @param slotId which slot needs to be set. * @param requestId the request/response message ID * @param error RIL_Errno and -1 means to disable the modified mechanism, back to original mock * modem behavior * @return boolean true if the operation is successful, otherwise false. */ - public boolean forceErrorResponse(int subId, int requestId, int error) throws Exception { + public boolean forceErrorResponse(int slotId, int requestId, int error) throws Exception { Log.d( TAG, - "forceErrorResponse[" + subId + "] for request:" + requestId + " ,error:" + error); + "forceErrorResponse[" + slotId + "] for request:" + requestId + " ,error:" + error); boolean result = true; // TODO: support DSDS @@ -200,4 +260,49 @@ public class MockModemManager { } return result; } + + /** + * Make the modem is in service or not. + * + * @param slotId which SIM slot is under the carrierId network. + * @param carrierId which carrier network is used. + * @param registration boolean true if the modem is in service, otherwise false. + * @return boolean true if the operation is successful, otherwise false. + */ + public boolean changeNetworkService(int slotId, int carrierId, boolean registration) + throws Exception { + Log.d( + TAG, + "changeNetworkService[" + + slotId + + "] in carrier (" + + carrierId + + ") " + + registration); + + boolean result; + // TODO: support DSDS for slotId + result = mMockModemService.getIRadioNetwork().changeNetworkService(carrierId, registration); + + waitForTelephonyFrameworkDone(1); + return result; + } + + /** + * get GSM CellBroadcastConfig outputs from IRadioMessagingImpl + * + * @return Set of broadcast configs + */ + public Set<Integer> getGsmBroadcastConfig() { + return mMockModemService.getIRadioMessaging().getGsmBroadcastConfigSet(); + } + + /** + * get CDMA CellBroadcastConfig outputs from IRadioMessagingImpl + * + * @return Set of broadcast configs + */ + public Set<Integer> getCdmaBroadcastConfig() { + return mMockModemService.getIRadioMessaging().getCdmaBroadcastConfigSet(); + } } diff --git a/tests/tests/telephony/current/src/android/telephony/cts/MockModemService.java b/tests/tests/telephony/current/mockmodem/src/android/telephony/mockmodem/MockModemService.java index 741b0e7fb44..f2523a4018e 100644 --- a/tests/tests/telephony/current/src/android/telephony/cts/MockModemService.java +++ b/tests/tests/telephony/current/mockmodem/src/android/telephony/mockmodem/MockModemService.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package android.telephony.cts; +package android.telephony.mockmodem; import android.app.Service; import android.content.Context; @@ -36,13 +36,15 @@ public class MockModemService extends Service { private static final String TAG = "MockModemService"; public static final int TEST_TIMEOUT_MS = 30000; - public static final String IRADIOCONFIG_INTERFACE = "android.telephony.cts.iradioconfig"; - public static final String IRADIOMODEM_INTERFACE = "android.telephony.cts.iradiomodem"; - public static final String IRADIOSIM_INTERFACE = "android.telephony.cts.iradiosim"; - public static final String IRADIONETWORK_INTERFACE = "android.telephony.cts.iradionetwork"; - public static final String IRADIODATA_INTERFACE = "android.telephony.cts.iradiodata"; - public static final String IRADIOMESSAGING_INTERFACE = "android.telephony.cts.iradiomessaging"; - public static final String IRADIOVOICE_INTERFACE = "android.telephony.cts.iradiovoice"; + public static final String IRADIOCONFIG_INTERFACE = "android.telephony.mockmodem.iradioconfig"; + public static final String IRADIOMODEM_INTERFACE = "android.telephony.mockmodem.iradiomodem"; + public static final String IRADIOSIM_INTERFACE = "android.telephony.mockmodem.iradiosim"; + public static final String IRADIONETWORK_INTERFACE = + "android.telephony.mockmodem.iradionetwork"; + public static final String IRADIODATA_INTERFACE = "android.telephony.mockmodem.iradiodata"; + public static final String IRADIOMESSAGING_INTERFACE = + "android.telephony.mockmodem.iradiomessaging"; + public static final String IRADIOVOICE_INTERFACE = "android.telephony.mockmodem.iradiovoice"; public static final String PHONE_ID = "phone_id"; private static Context sContext; @@ -115,7 +117,8 @@ public class MockModemService extends Service { // TODO: Support DSDS sIRadioModemImpl = new IRadioModemImpl(this, sMockModemConfigInterfaces, DEFAULT_SUB_ID); sIRadioSimImpl = new IRadioSimImpl(this, sMockModemConfigInterfaces, DEFAULT_SUB_ID); - sIRadioNetworkImpl = new IRadioNetworkImpl(this); + sIRadioNetworkImpl = + new IRadioNetworkImpl(this, sMockModemConfigInterfaces, DEFAULT_SUB_ID); sIRadioDataImpl = new IRadioDataImpl(this); sIRadioMessagingImpl = new IRadioMessagingImpl(this); sIRadioVoiceImpl = new IRadioVoiceImpl(this); diff --git a/tests/tests/telephony/current/src/android/telephony/cts/MockModemServiceConnector.java b/tests/tests/telephony/current/mockmodem/src/android/telephony/mockmodem/MockModemServiceConnector.java index 039a1e1feb3..803199471a1 100644 --- a/tests/tests/telephony/current/src/android/telephony/cts/MockModemServiceConnector.java +++ b/tests/tests/telephony/current/mockmodem/src/android/telephony/mockmodem/MockModemServiceConnector.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package android.telephony.cts; +package android.telephony.mockmodem; import android.app.Instrumentation; import android.content.ComponentName; @@ -22,6 +22,7 @@ import android.content.Context; import android.content.Intent; import android.content.ServiceConnection; import android.os.IBinder; +import android.telephony.cts.TelephonyUtils; import android.text.TextUtils; import android.util.Log; @@ -33,7 +34,6 @@ class MockModemServiceConnector { private static final String TAG = "MockModemServiceConnector"; - private static final String DEFAULT_SERVICE_NAME = MockModemService.class.getClass().getName(); private static final String COMMAND_BASE = "cmd phone "; private static final String COMMAND_SET_MODEM_SERVICE = "radio set-modem-service "; private static final String COMMAND_GET_MODEM_SERVICE = "radio get-modem-service "; @@ -56,10 +56,8 @@ class MockModemServiceConnector { public void onServiceConnected(ComponentName name, IBinder service) { String serviceName; mMockModemService = ((MockModemService.LocalBinder) service).getService(); - serviceName = mMockModemService.getClass().getName(); - if (!isDefaultMockModemService(serviceName)) { - updateModemServiceName(serviceName); - } + serviceName = name.getPackageName() + "/" + name.getClassName(); + updateModemServiceName(serviceName); mLatch.countDown(); Log.d(TAG, "MockModemServiceConnection - " + serviceName + " onServiceConnected"); } @@ -164,10 +162,6 @@ class MockModemServiceConnector { return result; } - private boolean isDefaultMockModemService(String serviceName) { - return TextUtils.equals(DEFAULT_SERVICE_NAME, serviceName); - } - /** * Bind to the local implementation of MockModemService. * diff --git a/tests/tests/telephony/current/mockmodem/src/android/telephony/mockmodem/MockNetworkService.java b/tests/tests/telephony/current/mockmodem/src/android/telephony/mockmodem/MockNetworkService.java new file mode 100644 index 00000000000..2324cc2062e --- /dev/null +++ b/tests/tests/telephony/current/mockmodem/src/android/telephony/mockmodem/MockNetworkService.java @@ -0,0 +1,688 @@ +/* + * Copyright (C) 2022 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.telephony.mockmodem; + +import android.hardware.radio.network.CellConnectionStatus; +import android.hardware.radio.network.CellInfo; +import android.hardware.radio.network.CellInfoLte; +import android.hardware.radio.network.CellInfoRatSpecificInfo; +import android.hardware.radio.network.CellInfoWcdma; +import android.hardware.radio.network.RegState; +import android.telephony.RadioAccessFamily; +import android.telephony.ServiceState; +import android.util.Log; + +import com.android.internal.telephony.RILConstants; + +import java.util.ArrayList; + +public class MockNetworkService { + private static final String TAG = "MockNetworkService"; + + // Grouping of RAFs + // 2G + public static final int GSM = + RadioAccessFamily.RAF_GSM | RadioAccessFamily.RAF_GPRS | RadioAccessFamily.RAF_EDGE; + public static final int CDMA = + RadioAccessFamily.RAF_IS95A | RadioAccessFamily.RAF_IS95B | RadioAccessFamily.RAF_1xRTT; + // 3G + public static final int EVDO = + RadioAccessFamily.RAF_EVDO_0 + | RadioAccessFamily.RAF_EVDO_A + | RadioAccessFamily.RAF_EVDO_B + | RadioAccessFamily.RAF_EHRPD; + public static final int HS = + RadioAccessFamily.RAF_HSUPA + | RadioAccessFamily.RAF_HSDPA + | RadioAccessFamily.RAF_HSPA + | RadioAccessFamily.RAF_HSPAP; + public static final int WCDMA = HS | RadioAccessFamily.RAF_UMTS; + // 4G + public static final int LTE = RadioAccessFamily.RAF_LTE | RadioAccessFamily.RAF_LTE_CA; + // 5G + public static final int NR = RadioAccessFamily.RAF_NR; + + static final int MOCK_CARRIER_NO_SERVICE = 0; + // TODO: Integrate carrier network parameters with SIM profile + static final int MOCK_CARRIER_CHT = 1; + static final int MOCK_CARRIER_FET = 2; + + // Network status update reason + static final int NETWORK_UPDATE_PREFERRED_MODE_CHANGE = 1; + + private int mCsRegState = RegState.NOT_REG_MT_NOT_SEARCHING_OP; + private int mPsRegState = RegState.NOT_REG_MT_NOT_SEARCHING_OP; + + private String mSimPlmn; + private boolean mIsHomeCamping; + private boolean mIsRoamingCamping; + private int mHomeCarrierId; + private int mRoamingCarrierId; + private int mInServiceCarrierId; + private int mHighRat; + + private ArrayList<MockModemCell> mCellList = new ArrayList<MockModemCell>(); + + private class MockModemCell { + private int mCarrierId; + + // Non-AOSP + public String[] mEHPlmnList; + public String[] mAllowRoamingList; + + // AOSP + private CellInfo[] mCells; + + MockModemCell(int carrierConfig) { + mCarrierId = carrierConfig; + updateHomeRoamingList(); + updateCellList(); + } + + public int getCarrierId() { + return mCarrierId; + } + + public CellInfo[] getCells() { + return mCells; + } + + private void updateHomeRoamingList() { + // TODO: Read from carrier configuration file + switch (mCarrierId) { + case MOCK_CARRIER_CHT: + mEHPlmnList = new String[] {"46692"}; + mAllowRoamingList = new String[] {"310026"}; + break; + case MOCK_CARRIER_FET: + mEHPlmnList = new String[] {"46601"}; + mAllowRoamingList = new String[] {"310026"}; + break; + case MOCK_CARRIER_NO_SERVICE: + default: + break; + } + } + + private void updateCellList() { + // TODO: Read from carrier configuration file + switch (mCarrierId) { + case MOCK_CARRIER_NO_SERVICE: + break; + case MOCK_CARRIER_CHT: + // LTE Cell configuration + CellInfoLte lte = new CellInfoLte(); + lte.cellIdentityLte = new android.hardware.radio.network.CellIdentityLte(); + lte.cellIdentityLte.mcc = "466"; + lte.cellIdentityLte.mnc = "92"; + lte.cellIdentityLte.ci = 101; + lte.cellIdentityLte.pci = 273; + lte.cellIdentityLte.tac = 13100; + lte.cellIdentityLte.earfcn = 9260; + lte.cellIdentityLte.operatorNames = + new android.hardware.radio.network.OperatorInfo(); + lte.cellIdentityLte.operatorNames.alphaLong = "Chung Hwa Telecom"; + lte.cellIdentityLte.operatorNames.alphaShort = "CHT"; + lte.cellIdentityLte.operatorNames.operatorNumeric = "46692"; + lte.cellIdentityLte.additionalPlmns = new String[0]; + lte.cellIdentityLte.bands = new int[0]; + + lte.signalStrengthLte = new android.hardware.radio.network.LteSignalStrength(); + lte.signalStrengthLte.signalStrength = 20; + lte.signalStrengthLte.rsrp = 71; + lte.signalStrengthLte.rsrq = 6; + lte.signalStrengthLte.rssnr = 100; + lte.signalStrengthLte.cqi = 13; + lte.signalStrengthLte.timingAdvance = 0; + lte.signalStrengthLte.cqiTableIndex = 1; + + // WCDMA Cell configuration + CellInfoWcdma wcdma = new CellInfoWcdma(); + wcdma.cellIdentityWcdma = + new android.hardware.radio.network.CellIdentityWcdma(); + wcdma.cellIdentityWcdma.mcc = "466"; + wcdma.cellIdentityWcdma.mnc = "92"; + wcdma.cellIdentityWcdma.lac = 9222; + wcdma.cellIdentityWcdma.cid = 14549; + wcdma.cellIdentityWcdma.psc = 413; + wcdma.cellIdentityWcdma.uarfcn = 10613; + wcdma.cellIdentityWcdma.operatorNames = + new android.hardware.radio.network.OperatorInfo(); + wcdma.cellIdentityWcdma.operatorNames.alphaLong = "Chung Hwa 3G"; + wcdma.cellIdentityWcdma.operatorNames.alphaShort = "CHT"; + wcdma.cellIdentityWcdma.operatorNames.operatorNumeric = "46692"; + wcdma.cellIdentityWcdma.additionalPlmns = new String[0]; + + wcdma.signalStrengthWcdma = + new android.hardware.radio.network.WcdmaSignalStrength(); + wcdma.signalStrengthWcdma.signalStrength = 20; + wcdma.signalStrengthWcdma.bitErrorRate = 3; + wcdma.signalStrengthWcdma.rscp = 45; + wcdma.signalStrengthWcdma.ecno = 25; + + // Fill the cells + mCells = new CellInfo[2]; // TODO: 2 is read from config file + mCells[0] = new CellInfo(); + mCells[0].registered = false; + mCells[0].connectionStatus = CellConnectionStatus.PRIMARY_SERVING; + mCells[0].ratSpecificInfo = new CellInfoRatSpecificInfo(); + mCells[0].ratSpecificInfo.setLte(lte); + + mCells[1] = new CellInfo(); + mCells[1].registered = false; + mCells[1].connectionStatus = CellConnectionStatus.SECONDARY_SERVING; + mCells[1].ratSpecificInfo = new CellInfoRatSpecificInfo(); + mCells[1].ratSpecificInfo.setWcdma(wcdma); + break; + case MOCK_CARRIER_FET: + // WCDMA Cell configuration + CellInfoWcdma wcdma2 = new CellInfoWcdma(); + wcdma2.cellIdentityWcdma = + new android.hardware.radio.network.CellIdentityWcdma(); + wcdma2.cellIdentityWcdma.mcc = "466"; + wcdma2.cellIdentityWcdma.mnc = "01"; + wcdma2.cellIdentityWcdma.lac = 8122; + wcdma2.cellIdentityWcdma.cid = 16249; + wcdma2.cellIdentityWcdma.psc = 413; + wcdma2.cellIdentityWcdma.uarfcn = 10613; + wcdma2.cellIdentityWcdma.operatorNames = + new android.hardware.radio.network.OperatorInfo(); + wcdma2.cellIdentityWcdma.operatorNames.alphaLong = "Far EasTone"; + wcdma2.cellIdentityWcdma.operatorNames.alphaShort = "FET"; + wcdma2.cellIdentityWcdma.operatorNames.operatorNumeric = "46601"; + wcdma2.cellIdentityWcdma.additionalPlmns = new String[0]; + + wcdma2.signalStrengthWcdma = + new android.hardware.radio.network.WcdmaSignalStrength(); + wcdma2.signalStrengthWcdma.signalStrength = 10; + wcdma2.signalStrengthWcdma.bitErrorRate = 6; + wcdma2.signalStrengthWcdma.rscp = 55; + wcdma2.signalStrengthWcdma.ecno = 15; + + // Fill the cells + mCells = new CellInfo[1]; + mCells[0] = new CellInfo(); + mCells[0].registered = false; + mCells[0].connectionStatus = CellConnectionStatus.PRIMARY_SERVING; + mCells[0].ratSpecificInfo = new CellInfoRatSpecificInfo(); + mCells[0].ratSpecificInfo.setWcdma(wcdma2); + break; + default: + break; + } + } + + public android.hardware.radio.network.OperatorInfo getPrimaryCellOperatorInfo() { + android.hardware.radio.network.OperatorInfo operatorInfo = + new android.hardware.radio.network.OperatorInfo(); + for (CellInfo cellInfo : getCells()) { + if (cellInfo.connectionStatus == CellConnectionStatus.PRIMARY_SERVING) { + switch (cellInfo.ratSpecificInfo.getTag()) { + case CellInfoRatSpecificInfo.wcdma: + operatorInfo = + cellInfo.ratSpecificInfo.getWcdma() + .cellIdentityWcdma + .operatorNames; + break; + case CellInfoRatSpecificInfo.lte: + operatorInfo = + cellInfo.ratSpecificInfo.getLte().cellIdentityLte.operatorNames; + break; + default: + break; + } + } + } + + return operatorInfo; + } + + public android.hardware.radio.network.SignalStrength getPrimaryCellSignalStrength() { + android.hardware.radio.network.SignalStrength signalStrength = + new android.hardware.radio.network.SignalStrength(); + + signalStrength.gsm = new android.hardware.radio.network.GsmSignalStrength(); + signalStrength.cdma = new android.hardware.radio.network.CdmaSignalStrength(); + signalStrength.evdo = new android.hardware.radio.network.EvdoSignalStrength(); + signalStrength.lte = new android.hardware.radio.network.LteSignalStrength(); + signalStrength.tdscdma = new android.hardware.radio.network.TdscdmaSignalStrength(); + signalStrength.wcdma = new android.hardware.radio.network.WcdmaSignalStrength(); + signalStrength.nr = new android.hardware.radio.network.NrSignalStrength(); + signalStrength.nr.csiCqiReport = new byte[0]; + + for (CellInfo cellInfo : getCells()) { + if (cellInfo.connectionStatus == CellConnectionStatus.PRIMARY_SERVING) { + switch (cellInfo.ratSpecificInfo.getTag()) { + case CellInfoRatSpecificInfo.wcdma: + signalStrength.wcdma = + cellInfo.ratSpecificInfo.getWcdma().signalStrengthWcdma; + break; + case CellInfoRatSpecificInfo.lte: + signalStrength.lte = + cellInfo.ratSpecificInfo.getLte().signalStrengthLte; + break; + default: + break; + } + } + } + + return signalStrength; + } + + public int getPrimaryCellRat() { + int rat = android.hardware.radio.RadioTechnology.UNKNOWN; + + for (CellInfo cellInfo : getCells()) { + if (cellInfo.connectionStatus == CellConnectionStatus.PRIMARY_SERVING) { + switch (cellInfo.ratSpecificInfo.getTag()) { + case CellInfoRatSpecificInfo.wcdma: + // TODO: Need find an element to assign the rat WCDMA, HSUPA, HSDPA, or + // HSPA + rat = android.hardware.radio.RadioTechnology.HSPA; + break; + case CellInfoRatSpecificInfo.lte: + rat = android.hardware.radio.RadioTechnology.LTE; + break; + default: + break; + } + } + } + + return rat; + } + + public android.hardware.radio.network.CellIdentity getPrimaryCellIdentity() { + android.hardware.radio.network.CellIdentity cellIdentity = + android.hardware.radio.network.CellIdentity.noinit(true); + + for (CellInfo cellInfo : getCells()) { + if (cellInfo.connectionStatus == CellConnectionStatus.PRIMARY_SERVING) { + switch (cellInfo.ratSpecificInfo.getTag()) { + case CellInfoRatSpecificInfo.wcdma: + cellIdentity.setWcdma( + cellInfo.ratSpecificInfo.getWcdma().cellIdentityWcdma); + break; + case CellInfoRatSpecificInfo.lte: + cellIdentity.setLte(cellInfo.ratSpecificInfo.getLte().cellIdentityLte); + break; + default: + break; + } + } + } + + return cellIdentity; + } + } + + public MockNetworkService() { + loadMockModemCell(MOCK_CARRIER_CHT); + loadMockModemCell(MOCK_CARRIER_FET); + } + + public void loadMockModemCell(int carrierId) { + if (!mCellList.isEmpty()) { + for (MockModemCell mmc : mCellList) { + if (mmc.getCarrierId() == carrierId) { + Log.d(TAG, "Carrier ID " + carrierId + " is loaded."); + return; + } + } + } + + mCellList.add(new MockModemCell(carrierId)); + } + + private int getHighestRatFromNetworkType(int raf) { + int rat; + int networkMode = RadioAccessFamily.getNetworkTypeFromRaf(raf); + + switch (networkMode) { + case RILConstants.NETWORK_MODE_WCDMA_PREF: + rat = ServiceState.RIL_RADIO_TECHNOLOGY_HSPA; + break; + case RILConstants.NETWORK_MODE_GSM_ONLY: + rat = ServiceState.RIL_RADIO_TECHNOLOGY_GSM; + break; + case RILConstants.NETWORK_MODE_WCDMA_ONLY: + rat = ServiceState.RIL_RADIO_TECHNOLOGY_HSPA; + break; + case RILConstants.NETWORK_MODE_GSM_UMTS: + rat = ServiceState.RIL_RADIO_TECHNOLOGY_HSPA; + break; + case RILConstants.NETWORK_MODE_CDMA: + rat = ServiceState.RIL_RADIO_TECHNOLOGY_IS95A; + break; + case RILConstants.NETWORK_MODE_LTE_CDMA_EVDO: + rat = ServiceState.RIL_RADIO_TECHNOLOGY_LTE; + break; + case RILConstants.NETWORK_MODE_LTE_GSM_WCDMA: + rat = ServiceState.RIL_RADIO_TECHNOLOGY_LTE; + break; + case RILConstants.NETWORK_MODE_LTE_CDMA_EVDO_GSM_WCDMA: + rat = ServiceState.RIL_RADIO_TECHNOLOGY_LTE; + break; + case RILConstants.NETWORK_MODE_LTE_ONLY: + rat = ServiceState.RIL_RADIO_TECHNOLOGY_LTE; + break; + case RILConstants.NETWORK_MODE_LTE_WCDMA: + rat = ServiceState.RIL_RADIO_TECHNOLOGY_LTE; + break; + case RILConstants.NETWORK_MODE_CDMA_NO_EVDO: + rat = ServiceState.RIL_RADIO_TECHNOLOGY_IS95A; + break; + case RILConstants.NETWORK_MODE_EVDO_NO_CDMA: + rat = ServiceState.RIL_RADIO_TECHNOLOGY_EVDO_0; + break; + case RILConstants.NETWORK_MODE_GLOBAL: + // GSM | WCDMA | CDMA | EVDO; + rat = ServiceState.RIL_RADIO_TECHNOLOGY_HSPA; + break; + case RILConstants.NETWORK_MODE_TDSCDMA_ONLY: + rat = ServiceState.RIL_RADIO_TECHNOLOGY_TD_SCDMA; + break; + case RILConstants.NETWORK_MODE_TDSCDMA_WCDMA: + rat = ServiceState.RIL_RADIO_TECHNOLOGY_HSPA; + break; + case RILConstants.NETWORK_MODE_LTE_TDSCDMA: + rat = ServiceState.RIL_RADIO_TECHNOLOGY_LTE; + break; + case RILConstants.NETWORK_MODE_TDSCDMA_GSM: + rat = ServiceState.RIL_RADIO_TECHNOLOGY_TD_SCDMA; + break; + case RILConstants.NETWORK_MODE_LTE_TDSCDMA_GSM: + rat = ServiceState.RIL_RADIO_TECHNOLOGY_LTE; + break; + case RILConstants.NETWORK_MODE_TDSCDMA_GSM_WCDMA: + rat = ServiceState.RIL_RADIO_TECHNOLOGY_HSPA; + break; + case RILConstants.NETWORK_MODE_LTE_TDSCDMA_WCDMA: + rat = ServiceState.RIL_RADIO_TECHNOLOGY_LTE; + break; + case RILConstants.NETWORK_MODE_LTE_TDSCDMA_GSM_WCDMA: + rat = ServiceState.RIL_RADIO_TECHNOLOGY_LTE; + break; + case RILConstants.NETWORK_MODE_TDSCDMA_CDMA_EVDO_GSM_WCDMA: + rat = ServiceState.RIL_RADIO_TECHNOLOGY_HSPA; + break; + case RILConstants.NETWORK_MODE_LTE_TDSCDMA_CDMA_EVDO_GSM_WCDMA: + rat = ServiceState.RIL_RADIO_TECHNOLOGY_LTE; + break; + case RILConstants.NETWORK_MODE_NR_ONLY: + rat = ServiceState.RIL_RADIO_TECHNOLOGY_NR; + break; + case RILConstants.NETWORK_MODE_NR_LTE: + rat = ServiceState.RIL_RADIO_TECHNOLOGY_NR; + break; + case RILConstants.NETWORK_MODE_NR_LTE_CDMA_EVDO: + rat = ServiceState.RIL_RADIO_TECHNOLOGY_NR; + break; + case RILConstants.NETWORK_MODE_NR_LTE_GSM_WCDMA: + rat = ServiceState.RIL_RADIO_TECHNOLOGY_NR; + break; + case RILConstants.NETWORK_MODE_NR_LTE_CDMA_EVDO_GSM_WCDMA: + rat = ServiceState.RIL_RADIO_TECHNOLOGY_NR; + break; + case RILConstants.NETWORK_MODE_NR_LTE_WCDMA: + rat = ServiceState.RIL_RADIO_TECHNOLOGY_NR; + break; + case RILConstants.NETWORK_MODE_NR_LTE_TDSCDMA: + rat = ServiceState.RIL_RADIO_TECHNOLOGY_NR; + break; + case RILConstants.NETWORK_MODE_NR_LTE_TDSCDMA_GSM: + rat = ServiceState.RIL_RADIO_TECHNOLOGY_NR; + break; + case RILConstants.NETWORK_MODE_NR_LTE_TDSCDMA_WCDMA: + rat = ServiceState.RIL_RADIO_TECHNOLOGY_NR; + break; + case RILConstants.NETWORK_MODE_NR_LTE_TDSCDMA_GSM_WCDMA: + rat = ServiceState.RIL_RADIO_TECHNOLOGY_NR; + break; + case RILConstants.NETWORK_MODE_NR_LTE_TDSCDMA_CDMA_EVDO_GSM_WCDMA: + rat = ServiceState.RIL_RADIO_TECHNOLOGY_NR; + break; + default: + rat = ServiceState.RIL_RADIO_TECHNOLOGY_UNKNOWN; + break; + } + return rat; + } + + public android.hardware.radio.network.OperatorInfo getPrimaryCellOperatorInfo() { + android.hardware.radio.network.OperatorInfo operatorInfo = + new android.hardware.radio.network.OperatorInfo(); + + if (mCsRegState == RegState.REG_HOME || mPsRegState == RegState.REG_HOME) { + operatorInfo = getCarrierStatus(mHomeCarrierId).getPrimaryCellOperatorInfo(); + } else if (mCsRegState == RegState.REG_ROAMING || mPsRegState == RegState.REG_ROAMING) { + operatorInfo = getCarrierStatus(mRoamingCarrierId).getPrimaryCellOperatorInfo(); + } + + return operatorInfo; + } + + public android.hardware.radio.network.CellIdentity getPrimaryCellIdentity() { + android.hardware.radio.network.CellIdentity cellIdentity = + android.hardware.radio.network.CellIdentity.noinit(true); + + if (mCsRegState == RegState.REG_HOME || mPsRegState == RegState.REG_HOME) { + cellIdentity = getCarrierStatus(mHomeCarrierId).getPrimaryCellIdentity(); + } else if (mCsRegState == RegState.REG_ROAMING || mPsRegState == RegState.REG_ROAMING) { + cellIdentity = getCarrierStatus(mRoamingCarrierId).getPrimaryCellIdentity(); + } + + return cellIdentity; + } + + public android.hardware.radio.network.CellInfo[] getCells() { + ArrayList<android.hardware.radio.network.CellInfo> cellInfos = new ArrayList<>(); + + for (MockModemCell mmc : mCellList) { + CellInfo[] cells = mmc.getCells(); + if (cells != null) { + for (CellInfo cellInfo : cells) { + cellInfos.add(cellInfo); + } + } + } + + return cellInfos.stream().toArray(android.hardware.radio.network.CellInfo[]::new); + } + + public boolean updateHighestRegisteredRat(int raf) { + + int rat = mHighRat; + mHighRat = getHighestRatFromNetworkType(raf); + + return (rat == mHighRat); + } + + public void updateNetworkStatus(int reason) { + if (reason == NETWORK_UPDATE_PREFERRED_MODE_CHANGE) { + Log.d(TAG, "updateNetworkStatus: NETWORK_UPDATE_PREFERRED_MODE_CHANGE"); + // TODO + } + } + + public int getRegistrationRat() { + int rat = android.hardware.radio.RadioTechnology.UNKNOWN; + + if (mCsRegState == RegState.REG_HOME || mPsRegState == RegState.REG_HOME) { + rat = getCarrierStatus(mHomeCarrierId).getPrimaryCellRat(); + } else if (mCsRegState == RegState.REG_ROAMING || mPsRegState == RegState.REG_ROAMING) { + rat = getCarrierStatus(mRoamingCarrierId).getPrimaryCellRat(); + } + + return rat; + } + + public android.hardware.radio.network.SignalStrength getSignalStrength() { + android.hardware.radio.network.SignalStrength signalStrength = + new android.hardware.radio.network.SignalStrength(); + + if (mCsRegState == RegState.REG_HOME || mPsRegState == RegState.REG_HOME) { + signalStrength = getCarrierStatus(mHomeCarrierId).getPrimaryCellSignalStrength(); + } else if (mCsRegState == RegState.REG_ROAMING || mPsRegState == RegState.REG_ROAMING) { + signalStrength = getCarrierStatus(mRoamingCarrierId).getPrimaryCellSignalStrength(); + } else { + // TODO + } + + return signalStrength; + } + + public int getRegistration(int domain) { + if (domain == android.hardware.radio.network.Domain.CS) { + return mCsRegState; + } else { + return mPsRegState; + } + } + + public boolean isInService() { + return ((mCsRegState == RegState.REG_HOME) + || (mPsRegState == RegState.REG_HOME) + || (mCsRegState == RegState.REG_ROAMING) + || (mPsRegState == RegState.REG_ROAMING)); + } + + public void updateSimPlmn(String simPlmn) { + mSimPlmn = simPlmn; + + // Reset mHomeCarrierId and mRoamingCarrierId + mHomeCarrierId = MOCK_CARRIER_NO_SERVICE; + mRoamingCarrierId = MOCK_CARRIER_NO_SERVICE; + + if (mSimPlmn == null || mSimPlmn.isEmpty()) return; + + if (mCellList.isEmpty()) return; + + for (MockModemCell mmc : mCellList) { + + if (isHomeCellExisted() && isRoamingCellExisted()) break; + + // Find out which cell is Home cell + for (String plmn : mmc.mEHPlmnList) { + if (!isHomeCellExisted() && mSimPlmn.equals(plmn)) { + mHomeCarrierId = mmc.getCarrierId(); + Log.d(TAG, "Cell ID: Home Cell " + mHomeCarrierId); + } + } + + // Find out which cell is Home cell + for (String plmn : mmc.mAllowRoamingList) { + if (!isRoamingCellExisted() && mSimPlmn.equals(plmn)) { + mRoamingCarrierId = mmc.getCarrierId(); + Log.d(TAG, "Cell ID: Roaming Cell " + mRoamingCarrierId); + } + } + } + } + + /** + * Set the device enters IN SERVICE + * + * @param isRoaming boolean true if the camping network is Roaming service, otherwise Home + * service + * @param inService boolean true if the deviec enters carrier coverge, otherwise the device + * leaves the carrier coverage. + */ + public void setServiceStatus(boolean isRoaming, boolean inService) { + if (isRoaming) { + mIsRoamingCamping = inService; + } else { + mIsHomeCamping = inService; + } + } + + public boolean getIsHomeCamping() { + return mIsHomeCamping; + } + + public boolean getIsRoamingCamping() { + return mIsRoamingCamping; + } + + public boolean isHomeCellExisted() { + return (mHomeCarrierId != MOCK_CARRIER_NO_SERVICE); + } + + public boolean isRoamingCellExisted() { + return (mRoamingCarrierId != MOCK_CARRIER_NO_SERVICE); + } + + public void updateServiceState(int reg) { + Log.d(TAG, "Cell ID: updateServiceState " + reg); + switch (reg) { + case RegState.NOT_REG_MT_SEARCHING_OP: + mCsRegState = RegState.NOT_REG_MT_SEARCHING_OP; + mPsRegState = RegState.NOT_REG_MT_SEARCHING_OP; + break; + case RegState.REG_HOME: + mCsRegState = RegState.REG_HOME; + mPsRegState = RegState.REG_HOME; + break; + case RegState.REG_ROAMING: + mCsRegState = RegState.REG_ROAMING; + mPsRegState = RegState.REG_ROAMING; + break; + case RegState.NOT_REG_MT_NOT_SEARCHING_OP: + default: + mCsRegState = RegState.NOT_REG_MT_NOT_SEARCHING_OP; + mPsRegState = RegState.NOT_REG_MT_NOT_SEARCHING_OP; + break; + } + + // TODO: mCsRegState and mPsReState may be changed by the registration denied reason set by + // TestCase + + for (MockModemCell mmc : mCellList) { + boolean registered; + if ((mCsRegState == RegState.REG_HOME || mPsRegState == RegState.REG_HOME) + && mHomeCarrierId == mmc.getCarrierId()) { + registered = true; + } else if ((mCsRegState == RegState.REG_ROAMING || mPsRegState == RegState.REG_ROAMING) + && mRoamingCarrierId == mmc.getCarrierId()) { + registered = true; + } else { + registered = false; + } + + CellInfo[] cells = mmc.getCells(); + if (cells != null) { + for (CellInfo cellInfo : cells) { + cellInfo.registered = registered; + } + } + } + } + + public MockModemCell getCarrierStatus(int carrierId) { + for (MockModemCell mmc : mCellList) { + if (mmc.getCarrierId() == carrierId) return mmc; + } + + return null; + } + + @Override + public String toString() { + return "isInService():" + isInService() + " Rat:" + getRegistrationRat() + ""; + } +} diff --git a/tests/tests/telephony/current/src/android/telephony/cts/MockSimService.java b/tests/tests/telephony/current/mockmodem/src/android/telephony/mockmodem/MockSimService.java index 2e43c5402d6..81839255dec 100644 --- a/tests/tests/telephony/current/src/android/telephony/cts/MockSimService.java +++ b/tests/tests/telephony/current/mockmodem/src/android/telephony/mockmodem/MockSimService.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package android.telephony.cts; +package android.telephony.mockmodem; import android.content.Context; import android.hardware.radio.sim.AppStatus; @@ -26,6 +26,7 @@ import org.xmlpull.v1.XmlPullParser; import java.io.InputStream; import java.util.ArrayList; +import java.util.Locale; public class MockSimService { private static final String TAG = "MockSimService"; @@ -33,7 +34,16 @@ public class MockSimService { /* Support SIM card identify */ public static final int MOCK_SIM_PROFILE_ID_DEFAULT = 0; // SIM Absent public static final int MOCK_SIM_PROFILE_ID_TWN_CHT = 1; - public static final int MOCK_SIM_PROFILE_ID_MAX = 2; + public static final int MOCK_SIM_PROFILE_ID_TWN_FET = 2; + public static final int MOCK_SIM_PROFILE_ID_MAX = 3; + + /* Type of SIM IO command */ + public static final int COMMAND_READ_BINARY = 0xb0; + public static final int COMMAND_GET_RESPONSE = 0xc0; + + /* EF Id definition */ + public static final int EF_ICCID = 0x2FE2; + public static final int EF_IMSI = 0x6F07; /* SIM profile XML TAG definition */ private static final String MOCK_SIM_TAG = "MockSim"; @@ -111,7 +121,6 @@ public class MockSimService { // SIM card data private int mSimProfileId; - private String mICCID; private String mEID; private String mATR; private int mUniversalPinState; @@ -120,6 +129,9 @@ public class MockSimService { private ArrayList<SimAppData> mSimAppList; public class SimAppData { + private static final int EF_INFO_DATA = 0; + private static final int EF_BINARY_DATA = 1; + private int mSimAppId; private String mAid; private boolean mIsCurrentActive; @@ -127,12 +139,25 @@ public class MockSimService { private int mFdnStatus; private int mPin1State; private String mImsi; + private String mMcc; + private String mMnc; + private String mMsin; + private String[] mIccid; - public SimAppData(int simappid, String aid, String path) { + private void initSimAppData(int simappid, String aid, String path, boolean status) { mSimAppId = simappid; mAid = aid; - mIsCurrentActive = false; + mIsCurrentActive = status; mPath = path; + mIccid = new String[2]; + } + + public SimAppData(int simappid, String aid, String path) { + initSimAppData(simappid, aid, path, false); + } + + public SimAppData(int simappid, String aid, String path, boolean status) { + initSimAppData(simappid, aid, path, status); } public int getSimAppId() { @@ -168,11 +193,53 @@ public class MockSimService { } public String getImsi() { - return mImsi; + return mMcc + mMnc + mMsin; + } + + public void setImsi(String mcc, String mnc, String msin) { + setMcc(mcc); + setMnc(mnc); + setMsin(msin); + } + + public String getMcc() { + return mMcc; + } + + public void setMcc(String mcc) { + mMcc = mcc; + } + + public String getMnc() { + return mMnc; + } + + public void setMnc(String mnc) { + mMnc = mnc; + } + + public String getMsin() { + return mMsin; + } + + public void setMsin(String msin) { + mMsin = msin; + } + + public String getIccidInfo() { + return mIccid[EF_INFO_DATA]; + } + + public void setIccidInfo(String info) { + mIccid[EF_INFO_DATA] = info; + } + + public String getIccid() { + return mIccid[EF_BINARY_DATA]; } - public void setImsi(String imsi) { - mImsi = imsi; + public void setIccid(String iccid) { + mIccid[EF_BINARY_DATA] = iccid; } } @@ -269,8 +336,10 @@ public class MockSimService { mSimProfileInfoList[idx] = new SimProfileInfo(idx); switch (idx) { case MOCK_SIM_PROFILE_ID_TWN_CHT: - String filename = "mock_sim_tw_cht.xml"; - mSimProfileInfoList[idx].setXmlFile(filename); + mSimProfileInfoList[idx].setXmlFile("mock_sim_tw_cht.xml"); + break; + case MOCK_SIM_PROFILE_ID_TWN_FET: + mSimProfileInfoList[idx].setXmlFile("mock_sim_tw_fet.xml"); break; default: break; @@ -443,11 +512,69 @@ public class MockSimService { return idx; } - private boolean storeEfData(String aid, String name, String id, String value) { + private String[] extractImsi(String imsi, int mncDigit) { + String[] result = null; + + Log.d(TAG, "IMSI = " + imsi + ", mnc-digit = " + mncDigit); + + if (imsi.length() > 15 && imsi.length() < 5) { + Log.d(TAG, "Invalid IMSI length."); + return result; + } + + if (mncDigit != 2 && mncDigit != 3) { + Log.d(TAG, "Invalid mnc length."); + return result; + } + + result = new String[3]; + result[0] = imsi.substring(0, 3); // MCC + result[1] = imsi.substring(3, 3 + mncDigit); // MNC + result[2] = imsi.substring(3 + mncDigit, imsi.length()); // MSIN + + Log.d(TAG, "MCC = " + result[0] + " MNC = " + result[1] + " MSIN = " + result[2]); + + return result; + } + + private boolean storeEfData( + String aid, String name, String id, String command, String[] value) { boolean result = true; + + if (value == null) { + Log.e(TAG, "Invalid value of EF field - " + name + "(" + id + ")"); + return false; + } + switch (name) { case "EF_IMSI": - mSimAppList.get(getSimAppDataIndexByAid(aid)).setImsi(value); + if (value.length == 3 + && value[0] != null + && value[0].length() == 3 + && value[1] != null + && (value[1].length() == 2 || value[1].length() == 3) + && value[2] != null + && value[2].length() > 0 + && (value[0].length() + value[1].length() + value[2].length() <= 15)) { + mSimAppList + .get(getSimAppDataIndexByAid(aid)) + .setImsi(value[0], value[1], value[2]); + } else { + result = false; + Log.e(TAG, "Invalid value for EF field - " + name + "(" + id + ")"); + } + break; + case "EF_ICCID": + if (command.length() > 2 + && Integer.parseInt(command.substring(2), 16) == COMMAND_READ_BINARY) { + mSimAppList.get(getSimAppDataIndexByAid(aid)).setIccid(value[0]); + } else if (command.length() > 2 + && Integer.parseInt(command.substring(2), 16) == COMMAND_GET_RESPONSE) { + mSimAppList.get(getSimAppDataIndexByAid(aid)).setIccidInfo(value[0]); + } else { + Log.e(TAG, "No valid Iccid data found"); + result = false; + } break; default: result = false; @@ -471,6 +598,7 @@ public class MockSimService { XmlPullParser parser = Xml.newPullParser(); InputStream input; boolean mocksim_validation = false; + boolean mocksim_pf_validatiion = false; boolean mocksim_mf_validation = false; int appidx = 0; int fd_lock = 0; @@ -484,16 +612,15 @@ public class MockSimService { case XmlPullParser.START_TAG: if (MOCK_SIM_TAG.equals(parser.getName())) { int numofapp = Integer.parseInt(parser.getAttributeValue(0)); - String iccid = parser.getAttributeValue(1); + mATR = parser.getAttributeValue(1); Log.d( TAG, "Found " + MOCK_SIM_TAG + ": numofapp = " + numofapp - + " iccid = " - + iccid); - mICCID = iccid; + + " atr = " + + mATR); mSimApp = new AppStatus[numofapp]; if (mSimApp == null) { Log.e(TAG, "Create SIM app failed!"); @@ -502,7 +629,8 @@ public class MockSimService { } mocksim_validation = true; } else if (mocksim_validation - && MOCK_SIM_PROFILE_TAG.equals(parser.getName())) { + && MOCK_SIM_PROFILE_TAG.equals(parser.getName()) + && appidx < mSimApp.length) { int id = Integer.parseInt(parser.getAttributeValue(0)); int type = convertMockSimAppType(parser.getAttributeValue(1)); mSimApp[appidx] = new AppStatus(); @@ -531,7 +659,9 @@ public class MockSimService { + " (" + type + ")========"); + mocksim_pf_validatiion = true; } else if (mocksim_validation + && mocksim_pf_validatiion && MOCK_PIN_PROFILE_TAG.equals(parser.getName())) { int appstate = convertMockSimAppState(parser.getAttributeValue(0)); mSimApp[appidx].appState = appstate; @@ -545,6 +675,7 @@ public class MockSimService { + appstate + ")"); } else if (mocksim_validation + && mocksim_pf_validatiion && MOCK_PIN1_STATE_TAG.equals(parser.getName())) { String state = parser.nextText(); int pin1state = convertMockSimPinState(state); @@ -559,6 +690,7 @@ public class MockSimService { + pin1state + ")"); } else if (mocksim_validation + && mocksim_pf_validatiion && MOCK_PIN2_STATE_TAG.equals(parser.getName())) { String state = parser.nextText(); int pin2state = convertMockSimPinState(state); @@ -571,7 +703,9 @@ public class MockSimService { + " (" + pin2state + ")"); + mSimApp[appidx].pin2 = pin2state; } else if (mocksim_validation + && mocksim_pf_validatiion && MOCK_FACILITY_LOCK_FD_TAG.equals(parser.getName())) { fd_lock = convertMockSimFacilityLock(parser.nextText()); Log.d( @@ -581,6 +715,7 @@ public class MockSimService { + ": fd lock = " + fd_lock); } else if (mocksim_validation + && mocksim_pf_validatiion && MOCK_FACILITY_LOCK_SC_TAG.equals(parser.getName())) { sc_lock = convertMockSimFacilityLock(parser.nextText()); Log.d( @@ -589,7 +724,9 @@ public class MockSimService { + MOCK_FACILITY_LOCK_SC_TAG + ": sc lock = " + sc_lock); - } else if (mocksim_validation && MOCK_MF_TAG.equals(parser.getName())) { + } else if (mocksim_validation + && mocksim_pf_validatiion + && MOCK_MF_TAG.equals(parser.getName())) { SimAppData simAppData; String name = parser.getAttributeValue(0); String path = parser.getAttributeValue(1); @@ -609,13 +746,14 @@ public class MockSimService { + " path = " + path); } else if (mocksim_validation + && mocksim_pf_validatiion && !mocksim_mf_validation && MOCK_EF_DIR_TAG.equals(parser.getName())) { SimAppData simAppData; String name = parser.getAttributeValue(0); boolean curr_active = Boolean.parseBoolean(parser.getAttributeValue(1)); String aid = parser.nextText(); - simAppData = new SimAppData(appidx, aid, name); + simAppData = new SimAppData(appidx, aid, name, curr_active); if (simAppData == null) { Log.e(TAG, "Create SIM app data failed!"); result = false; @@ -639,33 +777,71 @@ public class MockSimService { + aid); mocksim_mf_validation = true; } else if (mocksim_validation + && mocksim_pf_validatiion && mocksim_mf_validation && MOCK_ADF_TAG.equals(parser.getName())) { String aid = parser.getAttributeValue(0); Log.d(TAG, "Found " + MOCK_ADF_TAG + ": aid = " + aid); adf_aid = aid; } else if (mocksim_validation + && mocksim_pf_validatiion && mocksim_mf_validation && (adf_aid.length() > 0) && MOCK_EF_TAG.equals(parser.getName())) { String name = parser.getAttributeValue(0); String id = parser.getAttributeValue(1); - String value = parser.nextText(); - if (storeEfData(adf_aid, name, id, value)) { - Log.d( - TAG, - "Found " - + MOCK_EF_TAG - + ": name = " - + name - + " id = " - + id); + String command = parser.getAttributeValue(2); + String[] value; + switch (id) { + case "6F07": // EF_IMSI + int mncDigit = Integer.parseInt(parser.getAttributeValue(3)); + String imsi = parser.nextText(); + value = extractImsi(imsi, mncDigit); + if (value != null + && storeEfData(adf_aid, name, id, command, value)) { + Log.d( + TAG, + "Found " + + MOCK_EF_TAG + + ": name = " + + name + + " id = " + + id + + " command = " + + command + + " value = " + + imsi + + " with mnc-digit = " + + mncDigit); + } + break; + default: + value = new String[1]; + if (value != null) { + value[0] = parser.nextText(); + if (storeEfData(adf_aid, name, id, command, value)) { + Log.d( + TAG, + "Found " + + MOCK_EF_TAG + + ": name = " + + name + + " id = " + + id + + " command = " + + command + + " value = " + + value[0]); + } + } + break; } } break; case XmlPullParser.END_TAG: if (mocksim_validation && MOCK_SIM_PROFILE_TAG.equals(parser.getName())) { appidx++; + mocksim_pf_validatiion = false; mocksim_mf_validation = false; } else if (mocksim_validation && MOCK_ADF_TAG.equals(parser.getName())) { adf_aid = ""; @@ -673,7 +849,7 @@ public class MockSimService { break; } } - Log.d(TAG, "Totally create " + appidx + " SIM profiles"); + Log.d(TAG, "Totally create " + Math.min(mSimApp.length, appidx) + " SIM profiles"); mSimProfileInfoList[mSimProfileId].setNumOfSimApp(appidx); input.close(); } catch (Exception e) { @@ -712,7 +888,6 @@ public class MockSimService { if (mSimProfileId != MOCK_SIM_PROFILE_ID_DEFAULT) { switch (mPhysicalSlotId) { case MOCK_SIM_SLOT_1: - mATR = "3B9F96801FC78031E073FE2111634082918307900099"; mEID = DEFAULT_SIM1_EID; break; case MOCK_SIM_SLOT_2: @@ -731,19 +906,16 @@ public class MockSimService { case MOCK_SIM_SLOT_1: mATR = DEFAULT_SIM1_ATR; mEID = DEFAULT_SIM1_EID; - mICCID = DEFAULT_SIM1_ICCID; mUniversalPinState = DEFAULT_SIM1_UNIVERSAL_PIN_STATE; break; case MOCK_SIM_SLOT_2: mATR = DEFAULT_SIM2_ATR; mEID = DEFAULT_SIM2_EID; - mICCID = DEFAULT_SIM2_ICCID; mUniversalPinState = DEFAULT_SIM2_UNIVERSAL_PIN_STATE; break; case MOCK_SIM_SLOT_3: mATR = DEFAULT_SIM3_ATR; mEID = DEFAULT_SIM3_EID; - mICCID = DEFAULT_SIM3_ICCID; mUniversalPinState = DEFAULT_SIM3_UNIVERSAL_PIN_STATE; break; } @@ -789,12 +961,54 @@ public class MockSimService { return mEID; } + public boolean setATR(String atr) { + // TODO: add any ATR format check + mATR = atr; + return true; + } + public String getATR() { return mATR; } + public boolean setICCID(String iccid) { + boolean result = false; + SimAppData activeSimAppData = getActiveSimAppData(); + + // TODO: add iccid format check + if (activeSimAppData != null) { + String iccidInfo = activeSimAppData.getIccidInfo(); + int dataFileSize = iccid.length() / 2; + String dataFileSizeStr = Integer.toString(dataFileSize, 16); + + Log.d(TAG, "Data file size = " + dataFileSizeStr); + if (dataFileSizeStr.length() <= 4) { + dataFileSizeStr = String.format("%04x", dataFileSize).toUpperCase(Locale.ROOT); + // Data file size index is 2 and 3 in byte array of iccid info data. + iccidInfo = iccidInfo.substring(0, 4) + dataFileSizeStr + iccidInfo.substring(8); + Log.d(TAG, "Update iccid info = " + iccidInfo); + activeSimAppData.setIccidInfo(iccidInfo); + activeSimAppData.setIccid(iccid); + result = true; + } else { + Log.e(TAG, "Data file size(" + iccidInfo.length() + ") is too large."); + } + } else { + Log.e(TAG, "activeSimAppData = null"); + } + + return result; + } + public String getICCID() { - return mICCID; + String iccid = ""; + SimAppData activeSimAppData = getActiveSimAppData(); + + if (activeSimAppData != null) { + iccid = activeSimAppData.getIccid(); + } + + return iccid; } public int getUniversalPinState() { @@ -824,4 +1038,132 @@ public class MockSimService { public ArrayList<SimAppData> getSimAppList() { return mSimAppList; } + + public SimAppData getActiveSimAppData() { + SimAppData activeSimAppData = null; + + for (int simAppIdx = 0; simAppIdx < mSimAppList.size(); simAppIdx++) { + if (mSimAppList.get(simAppIdx).isCurrentActive()) { + activeSimAppData = mSimAppList.get(simAppIdx); + break; + } + } + + return activeSimAppData; + } + + public String getActiveSimAppId() { + String aid = ""; + SimAppData activeSimAppData = getActiveSimAppData(); + + if (activeSimAppData != null) { + aid = activeSimAppData.getAid(); + } + + return aid; + } + + private boolean setMcc(String mcc) { + boolean result = false; + + if (mcc.length() == 3) { + SimAppData activeSimAppData = getActiveSimAppData(); + if (activeSimAppData != null) { + activeSimAppData.setMcc(mcc); + result = true; + } + } + + return result; + } + + private boolean setMnc(String mnc) { + boolean result = false; + + if (mnc.length() == 2 || mnc.length() == 3) { + SimAppData activeSimAppData = getActiveSimAppData(); + if (activeSimAppData != null) { + activeSimAppData.setMnc(mnc); + result = true; + } + } + + return result; + } + + public String getMccMnc() { + String mcc; + String mnc; + String result = ""; + SimAppData activeSimAppData = getActiveSimAppData(); + + if (activeSimAppData != null) { + mcc = activeSimAppData.getMcc(); + mnc = activeSimAppData.getMnc(); + if (mcc != null + && mcc.length() == 3 + && mnc != null + && (mnc.length() == 2 || mnc.length() == 3)) { + result = mcc + mnc; + } else { + Log.e(TAG, "Invalid Mcc or Mnc."); + } + } + return result; + } + + public String getMsin() { + String result = ""; + SimAppData activeSimAppData = getActiveSimAppData(); + + if (activeSimAppData != null) { + result = activeSimAppData.getMsin(); + if (result.length() <= 0 || result.length() > 10) { + Log.e(TAG, "Invalid Msin."); + } + } + + return result; + } + + public boolean setImsi(String mcc, String mnc, String msin) { + boolean result = false; + + if (msin.length() > 0 && (mcc.length() + mnc.length() + msin.length()) <= 15) { + SimAppData activeSimAppData = getActiveSimAppData(); + if (activeSimAppData != null) { + setMcc(mcc); + setMnc(mnc); + activeSimAppData.setMsin(msin); + result = true; + } else { + Log.e(TAG, "activeSimAppData = null"); + } + } else { + Log.e(TAG, "Invalid IMSI"); + } + + return result; + } + + public String getImsi() { + String imsi = ""; + String mccmnc; + String msin; + SimAppData activeSimAppData = getActiveSimAppData(); + + if (activeSimAppData != null) { + mccmnc = getMccMnc(); + msin = activeSimAppData.getMsin(); + if (mccmnc.length() > 0 + && msin != null + && msin.length() > 0 + && (mccmnc.length() + msin.length()) <= 15) { + imsi = mccmnc + msin; + } else { + Log.e(TAG, "Invalid Imsi."); + } + } + return imsi; + } } diff --git a/tests/tests/telephony/current/src/android/telephony/cts/PhysicalChannelConfigTest.java b/tests/tests/telephony/current/src/android/telephony/cts/PhysicalChannelConfigTest.java index a11cd287fff..15d06356336 100644 --- a/tests/tests/telephony/current/src/android/telephony/cts/PhysicalChannelConfigTest.java +++ b/tests/tests/telephony/current/src/android/telephony/cts/PhysicalChannelConfigTest.java @@ -18,6 +18,7 @@ package android.telephony.cts; import static com.google.common.truth.Truth.assertThat; import static org.junit.Assert.assertEquals; +import static org.junit.Assert.fail; import android.telephony.AccessNetworkConstants; import android.telephony.PhysicalChannelConfig; @@ -27,7 +28,6 @@ import android.telephony.TelephonyManager; import org.junit.Before; import org.junit.Test; - public class PhysicalChannelConfigTest { private static final int[] CONTEXT_IDS = new int[] {123, 555, 1, 0}; @@ -66,20 +66,21 @@ public class PhysicalChannelConfigTest { @Test public void testInvalidPhysicalChannelConfig() { - mPhysicalChannelConfig = new PhysicalChannelConfig.Builder() - .setNetworkType(NETWORK_TYPE_LTE) - .setPhysicalCellId(PHYSICAL_INVALID_CELL_ID) - .setCellConnectionStatus(CONNECTION_STATUS) - .setCellBandwidthDownlinkKhz(CELL_BANDWIDTH) - .setCellBandwidthUplinkKhz(CELL_BANDWIDTH) - .setContextIds(CONTEXT_IDS) - .setFrequencyRange(FREQUENCY_RANGE) - .setDownlinkChannelNumber(CHANNEL_NUMBER) - .setUplinkChannelNumber(CHANNEL_NUMBER) - .setBand(BAND) - .build(); - assertThat(PHYSICAL_INVALID_CELL_ID) - .isNotEqualTo(mPhysicalChannelConfig.getPhysicalCellId()); + try { + mPhysicalChannelConfig = new PhysicalChannelConfig.Builder() + .setNetworkType(NETWORK_TYPE_LTE) + .setPhysicalCellId(PHYSICAL_INVALID_CELL_ID) + .setCellConnectionStatus(CONNECTION_STATUS) + .setCellBandwidthDownlinkKhz(CELL_BANDWIDTH) + .setCellBandwidthUplinkKhz(CELL_BANDWIDTH) + .setContextIds(CONTEXT_IDS) + .setFrequencyRange(FREQUENCY_RANGE) + .setDownlinkChannelNumber(CHANNEL_NUMBER) + .setUplinkChannelNumber(CHANNEL_NUMBER) + .setBand(BAND) + .build(); + fail("Physical cell Id: 1008 is over limit"); + } catch (IllegalArgumentException expected) { } } @Test diff --git a/tests/tests/telephony/current/src/android/telephony/cts/TelephonyManagerTest.java b/tests/tests/telephony/current/src/android/telephony/cts/TelephonyManagerTest.java index 3dcc9027165..1e8eaa6e689 100644 --- a/tests/tests/telephony/current/src/android/telephony/cts/TelephonyManagerTest.java +++ b/tests/tests/telephony/current/src/android/telephony/cts/TelephonyManagerTest.java @@ -3621,6 +3621,9 @@ public class TelephonyManagerTest { return; } + // Perform this test on default data subscription. + mTelephonyManager = getContext().getSystemService(TelephonyManager.class) + .createForSubscriptionId(SubscriptionManager.getDefaultDataSubscriptionId()); ShellIdentityUtils.invokeMethodWithShellPermissionsNoReturn( mTelephonyManager, (tm) -> tm.setDataEnabledForReason(TelephonyManager.DATA_ENABLED_REASON_THERMAL, @@ -3658,6 +3661,9 @@ public class TelephonyManagerTest { return; } + // Perform this test on default data subscription. + mTelephonyManager = getContext().getSystemService(TelephonyManager.class) + .createForSubscriptionId(SubscriptionManager.getDefaultDataSubscriptionId()); ShellIdentityUtils.invokeMethodWithShellPermissionsNoReturn( mTelephonyManager, (tm) -> tm.setDataEnabledForReason(TelephonyManager.DATA_ENABLED_REASON_POLICY, @@ -3695,6 +3701,9 @@ public class TelephonyManagerTest { return; } + // Perform this test on default data subscription. + mTelephonyManager = getContext().getSystemService(TelephonyManager.class) + .createForSubscriptionId(SubscriptionManager.getDefaultDataSubscriptionId()); ShellIdentityUtils.invokeMethodWithShellPermissionsNoReturn( mTelephonyManager, (tm) -> tm.setDataEnabledForReason(TelephonyManager.DATA_ENABLED_REASON_CARRIER, @@ -4464,6 +4473,7 @@ public class TelephonyManagerTest { return; } + boolean connectedToNrCell = false; for (CellInfo cellInfo : mTelephonyManager.getAllCellInfo()) { CellIdentity cellIdentity = cellInfo.getCellIdentity(); int[] bands; @@ -4481,11 +4491,21 @@ public class TelephonyManagerTest { || (band >= AccessNetworkConstants.NgranBands.BAND_257 && band <= AccessNetworkConstants.NgranBands.BAND_261)); } + if (cellInfo.isRegistered()) { + connectedToNrCell = true; + } } else { continue; } assertTrue(bands.length > 0); } + + if (connectedToNrCell) { + assertEquals(TelephonyManager.NETWORK_TYPE_NR, mTelephonyManager.getDataNetworkType()); + } else { + assertNotEquals(TelephonyManager.NETWORK_TYPE_NR, + mTelephonyManager.getDataNetworkType()); + } } /** diff --git a/tests/tests/telephony/current/src/android/telephony/cts/TelephonyManagerTestOnMockModem.java b/tests/tests/telephony/current/src/android/telephony/cts/TelephonyManagerTestOnMockModem.java index 265cb1d0a84..81850a81b1c 100644 --- a/tests/tests/telephony/current/src/android/telephony/cts/TelephonyManagerTestOnMockModem.java +++ b/tests/tests/telephony/current/src/android/telephony/cts/TelephonyManagerTestOnMockModem.java @@ -15,6 +15,8 @@ */ package android.telephony.cts; +import static android.telephony.mockmodem.MockSimService.MOCK_SIM_PROFILE_ID_TWN_CHT; + import static com.android.internal.telephony.RILConstants.INTERNAL_ERR; import static com.android.internal.telephony.RILConstants.RIL_REQUEST_RADIO_POWER; @@ -28,7 +30,11 @@ import android.content.Context; import android.content.pm.PackageManager; import android.os.Build; import android.os.SystemProperties; +import android.telephony.AccessNetworkConstants; +import android.telephony.NetworkRegistrationInfo; +import android.telephony.ServiceState; import android.telephony.TelephonyManager; +import android.telephony.mockmodem.MockModemManager; import android.util.Log; import androidx.test.InstrumentationRegistry; @@ -50,6 +56,7 @@ public class TelephonyManagerTestOnMockModem { private static TelephonyManager sTelephonyManager; private static final String ALLOW_MOCK_MODEM_PROPERTY = "persist.radio.allow_mock_modem"; private static final boolean DEBUG = !"user".equals(Build.TYPE); + private static boolean sIsMultiSimDevice; @BeforeClass public static void beforeAllTests() throws Exception { @@ -63,6 +70,14 @@ public class TelephonyManagerTestOnMockModem { sTelephonyManager = (TelephonyManager) getContext().getSystemService(Context.TELEPHONY_SERVICE); + sIsMultiSimDevice = isMultiSim(sTelephonyManager); + + //TODO: Support DSDS b/210073692 + if (sIsMultiSimDevice) { + Log.d(TAG, "Not support MultiSIM"); + return; + } + sMockModemManager = new MockModemManager(); assertNotNull(sMockModemManager); assertTrue(sMockModemManager.connectMockModemService()); @@ -76,6 +91,11 @@ public class TelephonyManagerTestOnMockModem { return; } + //TODO: Support DSDS b/210073692 + if (sIsMultiSimDevice) { + return; + } + // Rebind all interfaces which is binding to MockModemService to default. assertNotNull(sMockModemManager); assertTrue(sMockModemManager.disconnectMockModemService()); @@ -85,6 +105,8 @@ public class TelephonyManagerTestOnMockModem { @Before public void beforeTest() { assumeTrue(hasTelephonyFeature()); + //TODO: Support DSDS b/210073692 + assumeTrue(!sIsMultiSimDevice); } private static Context getContext() { @@ -100,6 +122,10 @@ public class TelephonyManagerTestOnMockModem { return true; } + private static boolean isMultiSim(TelephonyManager tm) { + return tm != null && tm.getPhoneCount() > 1; + } + private static void enforceMockModemDeveloperSetting() throws Exception { boolean isAllowed = SystemProperties.getBoolean(ALLOW_MOCK_MODEM_PROPERTY, false); // Check for developer settings for user build. Always allow for debug builds @@ -110,6 +136,26 @@ public class TelephonyManagerTestOnMockModem { } } + private int getRegState(int domain) { + int reg; + + InstrumentationRegistry.getInstrumentation() + .getUiAutomation() + .adoptShellPermissionIdentity("android.permission.READ_PHONE_STATE"); + + ServiceState ss = sTelephonyManager.getServiceState(); + assertNotNull(ss); + + NetworkRegistrationInfo nri = + ss.getNetworkRegistrationInfo(domain, AccessNetworkConstants.TRANSPORT_TYPE_WWAN); + assertNotNull(nri); + + reg = nri.getRegistrationState(); + Log.d(TAG, "SS: " + nri.registrationStateToString(reg)); + + return reg; + } + @Test public void testSimStateChange() throws Throwable { Log.d(TAG, "TelephonyManagerTestOnMockModem#testSimStateChange"); @@ -123,9 +169,7 @@ public class TelephonyManagerTestOnMockModem { .contains(simCardState)); // Insert a SIM - assertTrue( - sMockModemManager.insertSimCard( - slotId, MockSimService.MOCK_SIM_PROFILE_ID_TWN_CHT)); + assertTrue(sMockModemManager.insertSimCard(slotId, MOCK_SIM_PROFILE_ID_TWN_CHT)); simCardState = sTelephonyManager.getSimCardState(); assertEquals(TelephonyManager.SIM_STATE_PRESENT, simCardState); @@ -236,4 +280,43 @@ public class TelephonyManagerTestOnMockModem { assertTrue(result); assertEquals(sTelephonyManager.getRadioPowerState(), radioState); } + + @Test + public void testServiceStateChange() throws Throwable { + Log.d(TAG, "TelephonyManagerTestOnMockModem#testServiceStateChange"); + + int slotId = 0; + + // Insert a SIM + sMockModemManager.insertSimCard(slotId, MOCK_SIM_PROFILE_ID_TWN_CHT); + + // Expect: Seaching State + TimeUnit.SECONDS.sleep(2); + assertEquals( + getRegState(NetworkRegistrationInfo.DOMAIN_CS), + NetworkRegistrationInfo.REGISTRATION_STATE_NOT_REGISTERED_SEARCHING); + + // Enter Service + Log.d(TAG, "testServiceStateChange: Enter Service"); + sMockModemManager.changeNetworkService(slotId, MOCK_SIM_PROFILE_ID_TWN_CHT, true); + + // Expect: Home State + TimeUnit.SECONDS.sleep(2); + assertEquals( + getRegState(NetworkRegistrationInfo.DOMAIN_CS), + NetworkRegistrationInfo.REGISTRATION_STATE_HOME); + + // Leave Service + Log.d(TAG, "testServiceStateChange: Leave Service"); + sMockModemManager.changeNetworkService(slotId, MOCK_SIM_PROFILE_ID_TWN_CHT, false); + + // Expect: Seaching State + TimeUnit.SECONDS.sleep(2); + assertEquals( + getRegState(NetworkRegistrationInfo.DOMAIN_CS), + NetworkRegistrationInfo.REGISTRATION_STATE_NOT_REGISTERED_SEARCHING); + + // Remove the SIM + sMockModemManager.removeSimCard(slotId); + } } diff --git a/tests/tests/view/src/android/view/cts/SystemGestureExclusionRectsTest.java b/tests/tests/view/src/android/view/cts/SystemGestureExclusionRectsTest.java index e911e176f94..b3f294514ce 100644 --- a/tests/tests/view/src/android/view/cts/SystemGestureExclusionRectsTest.java +++ b/tests/tests/view/src/android/view/cts/SystemGestureExclusionRectsTest.java @@ -110,7 +110,7 @@ public class SystemGestureExclusionRectsTest { mActivityRule.runOnUiThread(() -> { final View v = activity.findViewById(R.id.animating_view); final ViewTreeObserver vto = v.getViewTreeObserver(); - v.getLocationOnScreen(location); + v.getLocationInWindow(location); vto.addOnSystemGestureExclusionRectsChangedListener(vtoListener); v.setSystemGestureExclusionRects( diff --git a/tools/cts-tradefed/res/config/cts-automated.xml b/tools/cts-tradefed/res/config/cts-automated.xml index 80bcea74c9a..6b07c63cf8a 100644 --- a/tools/cts-tradefed/res/config/cts-automated.xml +++ b/tools/cts-tradefed/res/config/cts-automated.xml @@ -24,6 +24,7 @@ <option name="skip-preconditions" value="false" /> <option name="skip-system-status-check" value="com.android.compatibility.common.tradefed.targetprep.NetworkConnectivityChecker" /> + <option name="wifi-check:disable" value="true" /> <!-- Tell all AndroidJUnitTests to exclude certain annotations --> <option name="compatibility:test-arg" value="com.android.tradefed.testtype.AndroidJUnitTest:exclude-annotation:android.platform.test.annotations.RestrictedBuildTest" /> diff --git a/tools/cts-tradefed/res/config/cts-known-failures.xml b/tools/cts-tradefed/res/config/cts-known-failures.xml index 93e79354b7c..401590bb75f 100644 --- a/tools/cts-tradefed/res/config/cts-known-failures.xml +++ b/tools/cts-tradefed/res/config/cts-known-failures.xml @@ -255,6 +255,7 @@ <option name="compatibility:exclude-filter" value="CtsDevicePolicyManagerTestCases com.android.cts.devicepolicy.MixedManagedProfileOwnerTest#testSetCameraDisabledLogged" /> <option name="compatibility:exclude-filter" value="CtsDevicePolicyManagerTestCases com.android.cts.devicepolicy.MixedProfileOwnerTest#testSetCameraDisabledLogged" /> + <!-- b/204721335 --> <option name="compatibility:exclude-filter" value="CtsWindowManagerJetpackTestCases android.server.wm.jetpack.SidecarTest#testSidecarInterface_onWindowLayoutChangeListener" /> |