diff options
author | Hall Liu <hallliu@google.com> | 2019-12-31 14:31:18 -0800 |
---|---|---|
committer | Hall Liu <hallliu@google.com> | 2019-12-31 14:41:02 -0800 |
commit | 35c243caa4226aa5ebc4418a8c65f299ec143ebc (patch) | |
tree | 2546e332eda46876577f084c2b4c42e184ad7e02 /tests/TelephonyCommonTests | |
parent | 967232eef39645e7f53195f458848e6238e1a0ce (diff) |
Clean up SmsApplication and expose getDefaultSmsPackage
- Clean up usages of hidden AppOpsManager APIs in SmsApplication
- Add unit tests for SmsApplication
- Expose RoleManager#getDefaultSmsPackage for use in SmsApplication.
Bug: 146834818
Test: atest SmsApplicationTest
Change-Id: I4ab49d7f6274389e7de7cd7223cab3c433936044
Diffstat (limited to 'tests/TelephonyCommonTests')
5 files changed, 347 insertions, 0 deletions
diff --git a/tests/TelephonyCommonTests/Android.bp b/tests/TelephonyCommonTests/Android.bp new file mode 100644 index 000000000000..16189c8e0ac8 --- /dev/null +++ b/tests/TelephonyCommonTests/Android.bp @@ -0,0 +1,48 @@ +// +// Copyright (C) 2019 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. +// + +android_test { + name: "TelephonyCommonTests", + srcs: [ + ":framework-telephony-common-sources", + "**/*.java", + ], + static_libs: [ + "mockito-target-extended", + "androidx.test.rules", + "truth-prebuilt", + "platform-test-annotations", + "androidx.core_core", + "androidx.fragment_fragment", + "androidx.test.ext.junit" + ], + + jni_libs: ["libdexmakerjvmtiagent"], + + // We need to rename SmsApplication to the test package or else it'll get clobbered by the + // hidden api checker + jarjar_rules: "jarjar-rules.txt", + + // Uncomment this and comment out the jarjar rule if you want to attach a debugger and step + // through the renamed classes. + //platform_apis: true, + + libs: [ + "android.test.runner", + "android.test.mock", + "android.test.base", + ], +} diff --git a/tests/TelephonyCommonTests/AndroidManifest.xml b/tests/TelephonyCommonTests/AndroidManifest.xml new file mode 100644 index 000000000000..63f38c6af2cb --- /dev/null +++ b/tests/TelephonyCommonTests/AndroidManifest.xml @@ -0,0 +1,30 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- Copyright (C) 2019 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="com.android.internal.telephony.tests" + android:debuggable="true"> + + <application android:label="TelephonyCommonTests" + android:debuggable="true"> + <uses-library android:name="android.test.runner" /> + </application> + + <instrumentation android:name="androidx.test.runner.AndroidJUnitRunner" + android:targetPackage="com.android.internal.telephony.tests" + android:label="Telephony common tests" + android:debuggable="true"/> +</manifest> diff --git a/tests/TelephonyCommonTests/AndroidTest.xml b/tests/TelephonyCommonTests/AndroidTest.xml new file mode 100644 index 000000000000..e9fdabcaf136 --- /dev/null +++ b/tests/TelephonyCommonTests/AndroidTest.xml @@ -0,0 +1,30 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- + ~ Copyright (C) 2019 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. + --> +<configuration description="Runs Telephony Common Test Cases."> + <option name="test-suite-tag" value="apct" /> + <option name="test-suite-tag" value="apct-instrumentation" /> + <target_preparer class="com.android.tradefed.targetprep.suite.SuiteApkInstaller"> + <option name="cleanup-apks" value="true" /> + <option name="test-file-name" value="TelephonyCommonTests.apk" /> + </target_preparer> + + <option name="test-tag" value="TelephonyCommonTests" /> + <test class="com.android.tradefed.testtype.AndroidJUnitTest" > + <option name="package" value="com.android.internal.telephony.tests" /> + <option name="runner" value="androidx.test.runner.AndroidJUnitRunner" /> + </test> +</configuration> diff --git a/tests/TelephonyCommonTests/jarjar-rules.txt b/tests/TelephonyCommonTests/jarjar-rules.txt new file mode 100644 index 000000000000..fe3471973c6e --- /dev/null +++ b/tests/TelephonyCommonTests/jarjar-rules.txt @@ -0,0 +1 @@ +rule com.android.internal.telephony.SmsApplication* com.android.internal.telephony.tests.SmsApplication@1 diff --git a/tests/TelephonyCommonTests/src/com/android/internal/telephony/tests/SmsApplicationTest.java b/tests/TelephonyCommonTests/src/com/android/internal/telephony/tests/SmsApplicationTest.java new file mode 100644 index 000000000000..6d0ee1891ac9 --- /dev/null +++ b/tests/TelephonyCommonTests/src/com/android/internal/telephony/tests/SmsApplicationTest.java @@ -0,0 +1,238 @@ +/* + * Copyright (C) 2019 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.internal.telephony.tests; + +import static org.junit.Assert.assertEquals; +import static org.mockito.ArgumentMatchers.anyInt; +import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.ArgumentMatchers.nullable; +import static org.mockito.Mockito.atLeastOnce; +import static org.mockito.Mockito.doAnswer; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +import android.Manifest; +import android.app.AppOpsManager; +import android.app.role.RoleManager; +import android.content.ComponentName; +import android.content.Context; +import android.content.Intent; +import android.content.pm.ActivityInfo; +import android.content.pm.ApplicationInfo; +import android.content.pm.PackageInfo; +import android.content.pm.PackageManager; +import android.content.pm.ResolveInfo; +import android.content.pm.ServiceInfo; +import android.os.UserHandle; +import android.provider.Telephony; +import android.telephony.TelephonyManager; + +import androidx.test.ext.junit.runners.AndroidJUnit4; + +import com.android.internal.telephony.SmsApplication; + +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; + +import java.util.Collections; +import java.util.List; + +/** + * Unit tests for the {@link SmsApplication} utility class + */ +@RunWith(AndroidJUnit4.class) +public class SmsApplicationTest { + private static final ComponentName TEST_COMPONENT_NAME = + ComponentName.unflattenFromString("com.android.test/.TestSmsApp"); + private static final String MMS_RECEIVER_NAME = "TestMmsReceiver"; + private static final String RESPOND_VIA_SMS_NAME = "TestRespondViaSmsHandler"; + private static final String SEND_TO_NAME = "TestSendTo"; + private static final int SMS_APP_UID = 10001; + + private static final int FAKE_PHONE_UID = 10002; + private static final int FAKE_MMS_UID = 10003; + private static final int FAKE_BT_UID = 10004; + private static final int FAKE_TELEPHONY_PROVIDER_UID = 10005; + + private static final String[] APP_OPS_TO_CHECK = { + AppOpsManager.OPSTR_READ_SMS, + AppOpsManager.OPSTR_WRITE_SMS, + AppOpsManager.OPSTR_RECEIVE_SMS, + AppOpsManager.OPSTR_RECEIVE_WAP_PUSH, + AppOpsManager.OPSTR_SEND_SMS, + AppOpsManager.OPSTR_READ_CELL_BROADCASTS + }; + + @Mock private Context mContext; + @Mock private TelephonyManager mTelephonyManager; + @Mock private RoleManager mRoleManager; + @Mock private PackageManager mPackageManager; + @Mock private AppOpsManager mAppOpsManager; + + @Before + public void setUp() throws Exception { + MockitoAnnotations.initMocks(this); + when(mContext.getSystemService(Context.TELEPHONY_SERVICE)).thenReturn(mTelephonyManager); + when(mContext.getSystemService(Context.ROLE_SERVICE)).thenReturn(mRoleManager); + when(mContext.getPackageManager()).thenReturn(mPackageManager); + when(mContext.getSystemService(RoleManager.class)).thenReturn(mRoleManager); + when(mContext.getSystemService(AppOpsManager.class)).thenReturn(mAppOpsManager); + + doAnswer(invocation -> getResolveInfosForIntent(invocation.getArgument(0))) + .when(mPackageManager) + .queryBroadcastReceiversAsUser(nullable(Intent.class), anyInt(), anyInt()); + doAnswer(invocation -> getResolveInfosForIntent(invocation.getArgument(0))) + .when(mPackageManager) + .queryIntentActivitiesAsUser(nullable(Intent.class), anyInt(), anyInt()); + doAnswer(invocation -> getResolveInfosForIntent(invocation.getArgument(0))) + .when(mPackageManager) + .queryIntentServicesAsUser(nullable(Intent.class), anyInt(), + nullable(UserHandle.class)); + + when(mTelephonyManager.isSmsCapable()).thenReturn(true); + when(mRoleManager.isRoleAvailable(RoleManager.ROLE_SMS)).thenReturn(true); + when(mRoleManager.getDefaultSmsPackage(anyInt())) + .thenReturn(TEST_COMPONENT_NAME.getPackageName()); + + for (String opStr : APP_OPS_TO_CHECK) { + when(mAppOpsManager.unsafeCheckOp( + opStr, SMS_APP_UID, TEST_COMPONENT_NAME.getPackageName())) + .thenReturn(AppOpsManager.MODE_ALLOWED); + } + } + + @Test + public void testGetDefaultSmsApplication() { + assertEquals(TEST_COMPONENT_NAME, + SmsApplication.getDefaultSmsApplicationAsUser(mContext, false, 0)); + } + + @Test + public void testGetDefaultSmsApplicationWithAppOpsFix() throws Exception { + when(mAppOpsManager.unsafeCheckOp(AppOpsManager.OPSTR_READ_SMS, SMS_APP_UID, + TEST_COMPONENT_NAME.getPackageName())) + .thenReturn(AppOpsManager.MODE_IGNORED); + setupPackageInfosForCoreApps(); + + assertEquals(TEST_COMPONENT_NAME, + SmsApplication.getDefaultSmsApplicationAsUser(mContext, true, 0)); + verify(mAppOpsManager, atLeastOnce()).setUidMode(AppOpsManager.OPSTR_READ_SMS, SMS_APP_UID, + AppOpsManager.MODE_ALLOWED); + } + + private void setupPackageInfosForCoreApps() throws Exception { + PackageInfo phonePackageInfo = new PackageInfo(); + ApplicationInfo phoneApplicationInfo = new ApplicationInfo(); + phoneApplicationInfo.uid = FAKE_PHONE_UID; + phonePackageInfo.applicationInfo = phoneApplicationInfo; + when(mPackageManager.getPackageInfo(eq(SmsApplication.PHONE_PACKAGE_NAME), anyInt())) + .thenReturn(phonePackageInfo); + + PackageInfo mmsPackageInfo = new PackageInfo(); + ApplicationInfo mmsApplicationInfo = new ApplicationInfo(); + mmsApplicationInfo.uid = FAKE_MMS_UID; + mmsPackageInfo.applicationInfo = mmsApplicationInfo; + when(mPackageManager.getPackageInfo(eq(SmsApplication.MMS_SERVICE_PACKAGE_NAME), anyInt())) + .thenReturn(mmsPackageInfo); + + PackageInfo bluetoothPackageInfo = new PackageInfo(); + ApplicationInfo bluetoothApplicationInfo = new ApplicationInfo(); + bluetoothApplicationInfo.uid = FAKE_BT_UID; + bluetoothPackageInfo.applicationInfo = bluetoothApplicationInfo; + when(mPackageManager.getPackageInfo(eq(SmsApplication.BLUETOOTH_PACKAGE_NAME), anyInt())) + .thenReturn(bluetoothPackageInfo); + + PackageInfo telephonyProviderPackageInfo = new PackageInfo(); + ApplicationInfo telephonyProviderApplicationInfo = new ApplicationInfo(); + telephonyProviderApplicationInfo.uid = FAKE_TELEPHONY_PROVIDER_UID; + telephonyProviderPackageInfo.applicationInfo = telephonyProviderApplicationInfo; + when(mPackageManager.getPackageInfo( + eq(SmsApplication.TELEPHONY_PROVIDER_PACKAGE_NAME), anyInt())) + .thenReturn(telephonyProviderPackageInfo); + } + + private List<ResolveInfo> getResolveInfosForIntent(Intent intent) { + switch (intent.getAction()) { + case Telephony.Sms.Intents.SMS_DELIVER_ACTION: + return Collections.singletonList(makeSmsDeliverResolveInfo()); + case Telephony.Sms.Intents.WAP_PUSH_DELIVER_ACTION: + return Collections.singletonList(makeWapPushResolveInfo()); + case TelephonyManager.ACTION_RESPOND_VIA_MESSAGE: + return Collections.singletonList(makeRespondViaMessageResolveInfo()); + case Intent.ACTION_SENDTO: + return Collections.singletonList(makeSendToResolveInfo()); + } + return Collections.emptyList(); + } + + private ApplicationInfo makeSmsApplicationInfo() { + ApplicationInfo applicationInfo = new ApplicationInfo(); + applicationInfo.uid = SMS_APP_UID; + return applicationInfo; + } + + private ResolveInfo makeSmsDeliverResolveInfo() { + ResolveInfo info = new ResolveInfo(); + ActivityInfo activityInfo = new ActivityInfo(); + activityInfo.applicationInfo = makeSmsApplicationInfo(); + + activityInfo.permission = Manifest.permission.BROADCAST_SMS; + activityInfo.packageName = TEST_COMPONENT_NAME.getPackageName(); + activityInfo.name = TEST_COMPONENT_NAME.getClassName(); + + info.activityInfo = activityInfo; + return info; + } + + private ResolveInfo makeWapPushResolveInfo() { + ResolveInfo info = new ResolveInfo(); + ActivityInfo activityInfo = new ActivityInfo(); + + activityInfo.permission = Manifest.permission.BROADCAST_WAP_PUSH; + activityInfo.packageName = TEST_COMPONENT_NAME.getPackageName(); + activityInfo.name = MMS_RECEIVER_NAME; + + info.activityInfo = activityInfo; + return info; + } + + private ResolveInfo makeRespondViaMessageResolveInfo() { + ResolveInfo info = new ResolveInfo(); + ServiceInfo serviceInfo = new ServiceInfo(); + + serviceInfo.permission = Manifest.permission.SEND_RESPOND_VIA_MESSAGE; + serviceInfo.packageName = TEST_COMPONENT_NAME.getPackageName(); + serviceInfo.name = RESPOND_VIA_SMS_NAME; + + info.serviceInfo = serviceInfo; + return info; + } + + private ResolveInfo makeSendToResolveInfo() { + ResolveInfo info = new ResolveInfo(); + ActivityInfo activityInfo = new ActivityInfo(); + + activityInfo.packageName = TEST_COMPONENT_NAME.getPackageName(); + activityInfo.name = SEND_TO_NAME; + + info.activityInfo = activityInfo; + return info; + } +} |