Replace callers of SmsApplication with user-aware

methods.

Bug: 250617029
Test: Sending and receiving SMS/MMS,
      atest com.android.internal.telephony.tests.SmsApplicationTest
Change-Id: Idb6671d35bed6a35804b5553f75d461b54273612
This commit is contained in:
Aishwarya Mallampati
2022-10-04 23:35:19 +00:00
parent 0270db12ea
commit 0e16f328f5
8 changed files with 306 additions and 53 deletions

View File

@@ -788,7 +788,7 @@ public class DataManager {
private void updateDefaultSmsApp(@NonNull UserData userData) {
ComponentName component = SmsApplication.getDefaultSmsApplicationAsUser(
mContext, /* updateIfNeeded= */ false, userData.getUserId());
mContext, /* updateIfNeeded= */ false, UserHandle.of(userData.getUserId()));
String defaultSmsApp = component != null ? component.getPackageName() : null;
userData.setDefaultSmsApp(defaultSmsApp);
}

View File

@@ -209,6 +209,15 @@ public final class SmsApplication {
}
}
/**
* Returns the userHandle of the current process, if called from a system app,
* otherwise it returns the caller's userHandle
* @return userHandle of the caller.
*/
private static UserHandle getIncomingUserHandle() {
return UserHandle.of(getIncomingUserId());
}
/**
* Returns the list of available SMS apps defined as apps that are registered for both the
* SMS_RECEIVED_ACTION (SMS) and WAP_PUSH_RECEIVED_ACTION (MMS) broadcasts (and their broadcast
@@ -951,24 +960,28 @@ public final class SmsApplication {
*/
@UnsupportedAppUsage
public static ComponentName getDefaultSmsApplication(Context context, boolean updateIfNeeded) {
return getDefaultSmsApplicationAsUser(context, updateIfNeeded, getIncomingUserId());
return getDefaultSmsApplicationAsUser(context, updateIfNeeded, getIncomingUserHandle());
}
/**
* Gets the default SMS application on a given user
* @param context context from the calling app
* @param updateIfNeeded update the default app if there is no valid default app configured.
* @param userId target user ID.
* @param userHandle target user handle
* if {@code null} is passed in then calling package uid is used to find out target user handle.
* @return component name of the app and class to deliver SMS messages to
*/
@VisibleForTesting
public static ComponentName getDefaultSmsApplicationAsUser(Context context,
boolean updateIfNeeded, int userId) {
boolean updateIfNeeded, @Nullable UserHandle userHandle) {
if (userHandle == null) {
userHandle = getIncomingUserHandle();
}
final long token = Binder.clearCallingIdentity();
try {
ComponentName component = null;
SmsApplicationData smsApplicationData = getApplication(context, updateIfNeeded,
userId);
userHandle.getIdentifier());
if (smsApplicationData != null) {
component = new ComponentName(smsApplicationData.mPackageName,
smsApplicationData.mSmsReceiverClass);
@@ -987,23 +1000,28 @@ public final class SmsApplication {
*/
@UnsupportedAppUsage
public static ComponentName getDefaultMmsApplication(Context context, boolean updateIfNeeded) {
return getDefaultMmsApplicationAsUser(context, updateIfNeeded, getIncomingUserId());
return getDefaultMmsApplicationAsUser(context, updateIfNeeded, getIncomingUserHandle());
}
/**
* Gets the default MMS application on a given user
* @param context context from the calling app
* @param updateIfNeeded update the default app if there is no valid default app configured.
* @param userId target user ID.
* @param userHandle target user handle
* if {@code null} is passed in then calling package uid is used to find out target user handle.
* @return component name of the app and class to deliver MMS messages to.
*/
public static ComponentName getDefaultMmsApplicationAsUser(Context context,
boolean updateIfNeeded, int userId) {
boolean updateIfNeeded, @Nullable UserHandle userHandle) {
if (userHandle == null) {
userHandle = getIncomingUserHandle();
}
final long token = Binder.clearCallingIdentity();
try {
ComponentName component = null;
SmsApplicationData smsApplicationData = getApplication(context, updateIfNeeded,
userId);
userHandle.getIdentifier());
if (smsApplicationData != null) {
component = new ComponentName(smsApplicationData.mPackageName,
smsApplicationData.mMmsReceiverClass);
@@ -1024,23 +1042,28 @@ public final class SmsApplication {
public static ComponentName getDefaultRespondViaMessageApplication(Context context,
boolean updateIfNeeded) {
return getDefaultRespondViaMessageApplicationAsUser(context, updateIfNeeded,
getIncomingUserId());
getIncomingUserHandle());
}
/**
* Gets the default Respond Via Message application on a given user
* @param context context from the calling app
* @param updateIfNeeded update the default app if there is no valid default app configured
* @param userId target user ID.
* @param userHandle target user handle
* if {@code null} is passed in then calling package uid is used to find out target user handle.
* @return component name of the app and class to direct Respond Via Message intent to
*/
public static ComponentName getDefaultRespondViaMessageApplicationAsUser(Context context,
boolean updateIfNeeded, int userId) {
boolean updateIfNeeded, @Nullable UserHandle userHandle) {
if (userHandle == null) {
userHandle = getIncomingUserHandle();
}
final long token = Binder.clearCallingIdentity();
try {
ComponentName component = null;
SmsApplicationData smsApplicationData = getApplication(context, updateIfNeeded,
userId);
userHandle.getIdentifier());
if (smsApplicationData != null) {
component = new ComponentName(smsApplicationData.mPackageName,
smsApplicationData.mRespondViaMessageClass);
@@ -1062,6 +1085,7 @@ public final class SmsApplication {
public static ComponentName getDefaultSendToApplication(Context context,
boolean updateIfNeeded) {
int userId = getIncomingUserId();
final long token = Binder.clearCallingIdentity();
try {
ComponentName component = null;
@@ -1087,7 +1111,7 @@ public final class SmsApplication {
public static ComponentName getDefaultExternalTelephonyProviderChangedApplication(
Context context, boolean updateIfNeeded) {
return getDefaultExternalTelephonyProviderChangedApplicationAsUser(context, updateIfNeeded,
getIncomingUserId());
getIncomingUserHandle());
}
/**
@@ -1095,16 +1119,21 @@ public final class SmsApplication {
* MmsProvider on a given user.
* @param context context from the calling app
* @param updateIfNeeded update the default app if there is no valid default app configured
* @param userId target user ID.
* @param userHandle target user handle
* if {@code null} is passed in then calling package uid is used to find out target user handle.
* @return component name of the app and class to deliver change intents to.
*/
public static ComponentName getDefaultExternalTelephonyProviderChangedApplicationAsUser(
Context context, boolean updateIfNeeded, int userId) {
Context context, boolean updateIfNeeded, @Nullable UserHandle userHandle) {
if (userHandle == null) {
userHandle = getIncomingUserHandle();
}
final long token = Binder.clearCallingIdentity();
try {
ComponentName component = null;
SmsApplicationData smsApplicationData = getApplication(context, updateIfNeeded,
userId);
userHandle.getIdentifier());
if (smsApplicationData != null
&& smsApplicationData.mProviderChangedReceiverClass != null) {
component = new ComponentName(smsApplicationData.mPackageName,
@@ -1124,23 +1153,28 @@ public final class SmsApplication {
*/
public static ComponentName getDefaultSimFullApplication(
Context context, boolean updateIfNeeded) {
return getDefaultSimFullApplicationAsUser(context, updateIfNeeded, getIncomingUserId());
return getDefaultSimFullApplicationAsUser(context, updateIfNeeded, getIncomingUserHandle());
}
/**
* Gets the default application that handles sim full event on a given user.
* @param context context from the calling app
* @param updateIfNeeded update the default app if there is no valid default app configured
* @param userId target user ID.
* @param userHandle target user handle
* if {@code null} is passed in then calling package uid is used to find out target user handle.
* @return component name of the app and class to deliver change intents to
*/
public static ComponentName getDefaultSimFullApplicationAsUser(Context context,
boolean updateIfNeeded, int userId) {
boolean updateIfNeeded, @Nullable UserHandle userHandle) {
if (userHandle == null) {
userHandle = getIncomingUserHandle();
}
final long token = Binder.clearCallingIdentity();
try {
ComponentName component = null;
SmsApplicationData smsApplicationData = getApplication(context, updateIfNeeded,
userId);
userHandle.getIdentifier());
if (smsApplicationData != null
&& smsApplicationData.mSimFullReceiverClass != null) {
component = new ComponentName(smsApplicationData.mPackageName,
@@ -1153,19 +1187,35 @@ public final class SmsApplication {
}
/**
* Returns whether need to wrgetIncomingUserIdite the SMS message to SMS database for this
* package.
* Returns whether it is required to write the SMS message to SMS database for this package.
*
* @param packageName the name of the package to be checked
* @param context context from the calling app
* @return true if it is required to write SMS message to SMS database for this package.
*
* <p>
* Caller must pass in the correct user context if calling from a singleton service.
*/
@UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
public static boolean shouldWriteMessageForPackage(String packageName, Context context) {
return !shouldWriteMessageForPackageAsUser(packageName, context, getIncomingUserId());
return !shouldWriteMessageForPackageAsUser(packageName, context, getIncomingUserHandle());
}
/**
* Returns whether it is required to write the SMS message to SMS database for this package.
*
* @param packageName the name of the package to be checked
* @param context context from the calling app
* @param userHandle target user handle
* if {@code null} is passed in then calling package uid is used to find out target user handle.
* @return true if it is required to write SMS message to SMS database for this package.
*
* <p>
* Caller must pass in the correct user context if calling from a singleton service.
*/
public static boolean shouldWriteMessageForPackageAsUser(String packageName, Context context,
int userId) {
return !isDefaultSmsApplicationAsUser(context, packageName, userId);
@Nullable UserHandle userHandle) {
return !isDefaultSmsApplicationAsUser(context, packageName, userHandle);
}
/**
@@ -1177,7 +1227,7 @@ public final class SmsApplication {
*/
@UnsupportedAppUsage
public static boolean isDefaultSmsApplication(Context context, String packageName) {
return isDefaultSmsApplicationAsUser(context, packageName, getIncomingUserId());
return isDefaultSmsApplicationAsUser(context, packageName, getIncomingUserHandle());
}
/**
@@ -1185,16 +1235,22 @@ public final class SmsApplication {
*
* @param context context from the calling app
* @param packageName the name of the package to be checked
* @param userId target user ID.
* @param userHandle target user handle
* if {@code null} is passed in then calling package uid is used to find out target user handle.
* @return true if the package is default sms app or bluetooth
*/
public static boolean isDefaultSmsApplicationAsUser(Context context, String packageName,
int userId) {
@Nullable UserHandle userHandle) {
if (packageName == null) {
return false;
}
if (userHandle == null) {
userHandle = getIncomingUserHandle();
}
ComponentName component = getDefaultSmsApplicationAsUser(context, false,
userId);
userHandle);
if (component == null) {
return false;
}
@@ -1222,7 +1278,7 @@ public final class SmsApplication {
*/
@UnsupportedAppUsage
public static boolean isDefaultMmsApplication(Context context, String packageName) {
return isDefaultMmsApplicationAsUser(context, packageName, getIncomingUserId());
return isDefaultMmsApplicationAsUser(context, packageName, getIncomingUserHandle());
}
/**
@@ -1230,17 +1286,22 @@ public final class SmsApplication {
*
* @param context context from the calling app
* @param packageName the name of the package to be checked
* @param userId target user ID.
* @param userHandle target user handle
* if {@code null} is passed in then calling package uid is used to find out target user handle.
* @return true if the package is default mms app or bluetooth
*/
public static boolean isDefaultMmsApplicationAsUser(Context context, String packageName,
int userId) {
@Nullable UserHandle userHandle) {
if (packageName == null) {
return false;
}
if (userHandle == null) {
userHandle = getIncomingUserHandle();
}
ComponentName component = getDefaultMmsApplicationAsUser(context, false,
userId);
userHandle);
if (component == null) {
return false;
}

View File

@@ -27,6 +27,8 @@ import android.os.Binder;
import android.os.Bundle;
import android.os.PersistableBundle;
import android.os.SystemProperties;
import android.os.UserHandle;
import android.telephony.SubscriptionManager;
import android.telephony.TelephonyManager;
import java.io.PrintWriter;
@@ -212,4 +214,30 @@ public final class TelephonyUtils {
return "UNKNOWN(" + mobileDataPolicy + ")";
}
}
}
/**
* Utility method to get user handle associated with this subscription.
*
* This method should be used internally as it returns null instead of throwing
* IllegalArgumentException or IllegalStateException.
*
* @param context Context object
* @param subId the subId of the subscription.
* @return userHandle associated with this subscription
* or {@code null} if:
* 1. subscription is not associated with any user
* 2. subId is invalid.
* 3. subscription service is not available.
*
* @throws SecurityException if the caller doesn't have permissions required.
*/
@Nullable
public static UserHandle getSubscriptionUserHandle(Context context, int subId) {
UserHandle userHandle = null;
SubscriptionManager subManager = context.getSystemService(SubscriptionManager.class);
if ((subManager != null) && (SubscriptionManager.isValidSubscriptionId(subId))) {
userHandle = subManager.getSubscriptionUserHandle(subId);
}
return userHandle;
}
}

View File

@@ -71,6 +71,7 @@ import android.os.PersistableBundle;
import android.os.RemoteException;
import android.os.ResultReceiver;
import android.os.SystemProperties;
import android.os.UserHandle;
import android.os.WorkSource;
import android.provider.Settings.SettingNotFoundException;
import android.service.carrier.CarrierIdentifier;
@@ -11999,8 +12000,9 @@ public class TelephonyManager {
}
/**
* Gets the default Respond Via Message application, updating the cache if there is no
* respond-via-message application currently configured.
* Get the component name of the default app to direct respond-via-message intent for the
* user associated with this subscription, update the cache if there is no respond-via-message
* application currently configured for this user.
* @return component name of the app and class to direct Respond Via Message intent to, or
* {@code null} if the functionality is not supported.
* @hide
@@ -12009,11 +12011,20 @@ public class TelephonyManager {
@RequiresPermission(Manifest.permission.INTERACT_ACROSS_USERS)
@RequiresFeature(PackageManager.FEATURE_TELEPHONY_MESSAGING)
public @Nullable ComponentName getAndUpdateDefaultRespondViaMessageApplication() {
return SmsApplication.getDefaultRespondViaMessageApplication(mContext, true);
try {
ITelephony telephony = getITelephony();
if (telephony != null) {
return telephony.getDefaultRespondViaMessageApplication(getSubId(), true);
}
} catch (RemoteException e) {
Log.e(TAG, "Error in getAndUpdateDefaultRespondViaMessageApplication: " + e);
}
return null;
}
/**
* Gets the default Respond Via Message application.
* Get the component name of the default app to direct respond-via-message intent for the
* user associated with this subscription.
* @return component name of the app and class to direct Respond Via Message intent to, or
* {@code null} if the functionality is not supported.
* @hide
@@ -12022,7 +12033,15 @@ public class TelephonyManager {
@RequiresPermission(Manifest.permission.INTERACT_ACROSS_USERS)
@RequiresFeature(PackageManager.FEATURE_TELEPHONY_MESSAGING)
public @Nullable ComponentName getDefaultRespondViaMessageApplication() {
return SmsApplication.getDefaultRespondViaMessageApplication(mContext, false);
try {
ITelephony telephony = getITelephony();
if (telephony != null) {
return telephony.getDefaultRespondViaMessageApplication(getSubId(), false);
}
} catch (RemoteException e) {
Log.e(TAG, "Error in getDefaultRespondViaMessageApplication: " + e);
}
return null;
}
/**

View File

@@ -17,6 +17,7 @@
package com.android.internal.telephony;
import android.app.PendingIntent;
import android.content.ComponentName;
import android.content.Intent;
import android.content.IntentSender;
import android.os.Bundle;
@@ -2612,4 +2613,14 @@ interface ITelephony {
* @hide
*/
boolean isRemovableEsimDefaultEuicc(String callingPackage);
/**
* Get the component name of the default app to direct respond-via-message intent for the
* user associated with this subscription, update the cache if there is no respond-via-message
* application currently configured for this user.
* @return component name of the app and class to direct Respond Via Message intent to, or
* {@code null} if the functionality is not supported.
* @hide
*/
ComponentName getDefaultRespondViaMessageApplication(int subId, boolean updateIfNeeded);
}

View File

@@ -47,7 +47,7 @@ android_test {
// Uncomment this and comment out the jarjar rule if you want to attach a debugger and step
// through the renamed classes.
// platform_apis: true,
platform_apis: true,
libs: [
"android.test.runner",

View File

@@ -44,6 +44,7 @@ import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.content.pm.ServiceInfo;
import android.content.res.Resources;
import android.net.Uri;
import android.os.Handler;
import android.os.UserHandle;
@@ -75,9 +76,12 @@ import java.util.stream.Collectors;
public class SmsApplicationTest {
private static final ComponentName TEST_COMPONENT_NAME =
ComponentName.unflattenFromString("com.android.test/.TestSmsApp");
public static final String BLUETOOTH_PACKAGE_NAME = "com.android.bluetooth.services";
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 String EXTERNAL_PROVIDER_CHANGE_NAME = "TestExternalProviderChangeHandler";
private static final String SIM_FULL_NAME = "TestSimFullHandler";
private static final int SMS_APP_UID = 10001;
private static final int FAKE_PHONE_UID = 10002;
@@ -102,6 +106,7 @@ public class SmsApplicationTest {
}).collect(Collectors.toSet());
@Mock private Context mContext;
@Mock private Resources mResources;
@Mock private TelephonyManager mTelephonyManager;
@Mock private RoleManager mRoleManager;
@Mock private PackageManager mPackageManager;
@@ -118,6 +123,9 @@ public class SmsApplicationTest {
when(mContext.getSystemService(UserManager.class)).thenReturn(mUserManager);
when(mContext.getSystemService(AppOpsManager.class)).thenReturn(mAppOpsManager);
when(mContext.createContextAsUser(isNotNull(), anyInt())).thenReturn(mContext);
when(mContext.getResources()).thenReturn(mResources);
when(mResources.getString(eq(com.android.internal.R.string.config_systemBluetoothStack)))
.thenReturn(BLUETOOTH_PACKAGE_NAME);
doAnswer(invocation -> getResolveInfosForIntent(invocation.getArgument(0)))
.when(mPackageManager)
@@ -146,24 +154,46 @@ public class SmsApplicationTest {
}
}
@Test
public void testGetDefaultSmsApplication() {
public void testGetDefaultSmsApplicationAsUser() {
assertEquals(TEST_COMPONENT_NAME,
SmsApplication.getDefaultSmsApplicationAsUser(mContext, false, 0));
SmsApplication.getDefaultSmsApplicationAsUser(mContext, false,
UserHandle.SYSTEM));
}
@Test
public void testGetDefaultMmsApplicationAsUser() {
ComponentName componentName = SmsApplication.getDefaultMmsApplicationAsUser(mContext,
false, UserHandle.SYSTEM);
assertEquals(TEST_COMPONENT_NAME.getPackageName(), componentName.getPackageName());
assertEquals(MMS_RECEIVER_NAME, componentName.getClassName());
}
@Test
public void testGetDefaultMmsApplication() {
assertEquals(TEST_COMPONENT_NAME,
SmsApplication.getDefaultMmsApplicationAsUser(mContext, false,
UserHandle.USER_SYSTEM));
public void testGetDefaultExternalTelephonyProviderChangedApplicationAsUser() {
ComponentName componentName = SmsApplication
.getDefaultExternalTelephonyProviderChangedApplicationAsUser(mContext,
false, UserHandle.SYSTEM);
assertEquals(TEST_COMPONENT_NAME.getPackageName(), componentName.getPackageName());
assertEquals(EXTERNAL_PROVIDER_CHANGE_NAME, componentName.getClassName());
}
@Test
public void testGetDefaultExternalTelephonyProviderChangedApplication() {
assertEquals(TEST_COMPONENT_NAME,
SmsApplication.getDefaultExternalTelephonyProviderChangedApplicationAsUser(mContext,
false, UserHandle.USER_SYSTEM));
public void testGetDefaultRespondViaMessageApplicationAsUserAsUser() {
ComponentName componentName = SmsApplication.getDefaultRespondViaMessageApplicationAsUser(
mContext, false, UserHandle.SYSTEM);
assertEquals(TEST_COMPONENT_NAME.getPackageName(), componentName.getPackageName());
assertEquals(RESPOND_VIA_SMS_NAME, componentName.getClassName());
}
@Test
public void testGetDefaultSimFullApplicationAsUser() {
ComponentName componentName = SmsApplication.getDefaultSimFullApplicationAsUser(mContext,
false, UserHandle.SYSTEM);
assertEquals(TEST_COMPONENT_NAME.getPackageName(), componentName.getPackageName());
assertEquals(SIM_FULL_NAME, componentName.getClassName());
}
@Test
@@ -174,7 +204,8 @@ public class SmsApplicationTest {
setupPackageInfosForCoreApps();
assertEquals(TEST_COMPONENT_NAME,
SmsApplication.getDefaultSmsApplicationAsUser(mContext, true, 0));
SmsApplication.getDefaultSmsApplicationAsUser(mContext, true,
UserHandle.SYSTEM));
verify(mAppOpsManager, atLeastOnce()).setUidMode(AppOpsManager.OPSTR_READ_SMS, SMS_APP_UID,
AppOpsManager.MODE_ALLOWED);
}
@@ -251,6 +282,10 @@ public class SmsApplicationTest {
return Collections.singletonList(makeRespondViaMessageResolveInfo());
case Intent.ACTION_SENDTO:
return Collections.singletonList(makeSendToResolveInfo());
case Telephony.Sms.Intents.ACTION_EXTERNAL_PROVIDER_CHANGE:
return Collections.singletonList(makeExternalProviderChangeResolveInfo());
case Telephony.Sms.Intents.SIM_FULL_ACTION:
return Collections.singletonList(makeSimFullResolveInfo());
}
return Collections.emptyList();
}
@@ -308,4 +343,26 @@ public class SmsApplicationTest {
info.activityInfo = activityInfo;
return info;
}
private ResolveInfo makeExternalProviderChangeResolveInfo() {
ResolveInfo info = new ResolveInfo();
ActivityInfo activityInfo = new ActivityInfo();
activityInfo.packageName = TEST_COMPONENT_NAME.getPackageName();
activityInfo.name = EXTERNAL_PROVIDER_CHANGE_NAME;
info.activityInfo = activityInfo;
return info;
}
private ResolveInfo makeSimFullResolveInfo() {
ResolveInfo info = new ResolveInfo();
ActivityInfo activityInfo = new ActivityInfo();
activityInfo.packageName = TEST_COMPONENT_NAME.getPackageName();
activityInfo.name = SIM_FULL_NAME;
info.activityInfo = activityInfo;
return info;
}
}

View File

@@ -0,0 +1,77 @@
/*
* 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 com.android.internal.telephony.tests;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.eq;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.verify;
import android.content.Context;
import android.telephony.SubscriptionManager;
import com.android.internal.telephony.util.TelephonyUtils;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.mockito.Mock;
import org.mockito.junit.MockitoJUnit;
import org.mockito.junit.MockitoRule;
public class TelephonyUtilsTest {
@Rule
public final MockitoRule mockito = MockitoJUnit.rule();
// Mocked classes
@Mock
private Context mContext;
@Mock
private SubscriptionManager mSubscriptionManager;
@Before
public void setup() {
doReturn(mSubscriptionManager).when(mContext)
.getSystemService(eq(SubscriptionManager.class));
}
@Test
public void getSubscriptionUserHandle_subId_invalid() {
int invalidSubId = -10;
doReturn(false).when(mSubscriptionManager).isActiveSubscriptionId(eq(invalidSubId));
TelephonyUtils.getSubscriptionUserHandle(mContext, invalidSubId);
// getSubscriptionUserHandle should not be called if subID is inactive.
verify(mSubscriptionManager, never()).getSubscriptionUserHandle(eq(invalidSubId));
}
@Test
public void getSubscriptionUserHandle_subId_valid() {
int activeSubId = 1;
doReturn(true).when(mSubscriptionManager).isActiveSubscriptionId(eq(activeSubId));
TelephonyUtils.getSubscriptionUserHandle(mContext, activeSubId);
// getSubscriptionUserHandle should be called if subID is active.
verify(mSubscriptionManager, times(1)).getSubscriptionUserHandle(eq(activeSubId));
}
}