Loading telephony/common/com/android/internal/telephony/PackageChangeReceiver.java +19 −15 Original line number Diff line number Diff line Loading @@ -24,17 +24,17 @@ import android.content.Intent; import android.content.IntentFilter; import android.net.Uri; import android.os.Handler; import android.os.HandlerThread; import android.os.Looper; import android.os.UserHandle; import com.android.internal.os.BackgroundThread; /** * Helper class for monitoring the state of packages: adding, removing, * updating, and disappearing and reappearing on the SD card. */ public abstract class PackageChangeReceiver extends BroadcastReceiver { static final IntentFilter sPackageIntentFilter = new IntentFilter(); private static HandlerThread sHandlerThread; static { sPackageIntentFilter.addAction(Intent.ACTION_PACKAGE_ADDED); sPackageIntentFilter.addAction(Intent.ACTION_PACKAGE_REMOVED); Loading @@ -43,28 +43,24 @@ public abstract class PackageChangeReceiver extends BroadcastReceiver { sPackageIntentFilter.addAction(Intent.ACTION_PACKAGE_RESTARTED); sPackageIntentFilter.addDataScheme("package"); } // Keep an instance of Context around as long as we still want the receiver: // if the instance of Context gets garbage-collected, it'll unregister the receiver, so only // unset when we want to unregister. Context mRegisteredContext; /** * To register the intents that needed for monitoring the state of packages * To register the intents that needed for monitoring the state of packages. Once this method * has been called on an instance of {@link PackageChangeReceiver}, all subsequent calls must * have the same {@code user} argument. */ public void register(@NonNull Context context, @Nullable Looper thread, @Nullable UserHandle user) { if (mRegisteredContext != null) { throw new IllegalStateException("Already registered"); } Handler handler = (thread == null) ? BackgroundThread.getHandler() : new Handler(thread); mRegisteredContext = context; if (handler != null) { if (user != null) { context.registerReceiverAsUser(this, user, sPackageIntentFilter, null, handler); } else { context.registerReceiver(this, sPackageIntentFilter, null, handler); } } else { throw new NullPointerException(); } Handler handler = new Handler(thread == null ? getStaticLooper() : thread); mRegisteredContext = user == null ? context : context.createContextAsUser(user, 0); mRegisteredContext.registerReceiver(this, sPackageIntentFilter, null, handler); } /** Loading @@ -78,6 +74,14 @@ public abstract class PackageChangeReceiver extends BroadcastReceiver { mRegisteredContext = null; } private static synchronized Looper getStaticLooper() { if (sHandlerThread == null) { sHandlerThread = new HandlerThread(PackageChangeReceiver.class.getSimpleName()); sHandlerThread.start(); } return sHandlerThread.getLooper(); } /** * This method is invoked when receive the Intent.ACTION_PACKAGE_ADDED */ Loading telephony/common/com/android/internal/telephony/SmsApplication.java +35 −31 Original line number Diff line number Diff line Loading @@ -58,7 +58,7 @@ import java.util.concurrent.ExecutionException; import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeoutException; import java.util.function.Consumer; import java.util.stream.Collectors; /** Loading Loading @@ -250,6 +250,7 @@ public final class SmsApplication { private static Collection<SmsApplicationData> getApplicationCollectionInternal( Context context, int userId) { PackageManager packageManager = context.getPackageManager(); UserHandle userHandle = UserHandle.of(userId); // Get the list of apps registered for SMS Intent intent = new Intent(Intents.SMS_DELIVER_ACTION); Loading @@ -258,7 +259,7 @@ public final class SmsApplication { } List<ResolveInfo> smsReceivers = packageManager.queryBroadcastReceiversAsUser(intent, PackageManager.MATCH_DIRECT_BOOT_AWARE | PackageManager.MATCH_DIRECT_BOOT_UNAWARE, userId); userHandle); HashMap<String, SmsApplicationData> receivers = new HashMap<String, SmsApplicationData>(); Loading @@ -285,7 +286,7 @@ public final class SmsApplication { intent.setDataAndType(null, "application/vnd.wap.mms-message"); List<ResolveInfo> mmsReceivers = packageManager.queryBroadcastReceiversAsUser(intent, PackageManager.MATCH_DIRECT_BOOT_AWARE | PackageManager.MATCH_DIRECT_BOOT_UNAWARE, userId); userHandle); for (ResolveInfo resolveInfo : mmsReceivers) { final ActivityInfo activityInfo = resolveInfo.activityInfo; if (activityInfo == null) { Loading Loading @@ -327,7 +328,7 @@ public final class SmsApplication { Uri.fromParts(SCHEME_SMSTO, "", null)); List<ResolveInfo> sendToActivities = packageManager.queryIntentActivitiesAsUser(intent, PackageManager.MATCH_DIRECT_BOOT_AWARE | PackageManager.MATCH_DIRECT_BOOT_UNAWARE, userId); userHandle); for (ResolveInfo resolveInfo : sendToActivities) { final ActivityInfo activityInfo = resolveInfo.activityInfo; if (activityInfo == null) { Loading @@ -345,7 +346,7 @@ public final class SmsApplication { List<ResolveInfo> smsAppChangedReceivers = packageManager.queryBroadcastReceiversAsUser(intent, PackageManager.MATCH_DIRECT_BOOT_AWARE | PackageManager.MATCH_DIRECT_BOOT_UNAWARE, userId); | PackageManager.MATCH_DIRECT_BOOT_UNAWARE, userHandle); if (DEBUG_MULTIUSER) { Log.i(LOG_TAG, "getApplicationCollectionInternal smsAppChangedActivities=" + smsAppChangedReceivers); Loading @@ -372,7 +373,7 @@ public final class SmsApplication { List<ResolveInfo> providerChangedReceivers = packageManager.queryBroadcastReceiversAsUser(intent, PackageManager.MATCH_DIRECT_BOOT_AWARE | PackageManager.MATCH_DIRECT_BOOT_UNAWARE, userId); | PackageManager.MATCH_DIRECT_BOOT_UNAWARE, userHandle); if (DEBUG_MULTIUSER) { Log.i(LOG_TAG, "getApplicationCollectionInternal providerChangedActivities=" + providerChangedReceivers); Loading @@ -399,7 +400,7 @@ public final class SmsApplication { List<ResolveInfo> simFullReceivers = packageManager.queryBroadcastReceiversAsUser(intent, PackageManager.MATCH_DIRECT_BOOT_AWARE | PackageManager.MATCH_DIRECT_BOOT_UNAWARE, userId); | PackageManager.MATCH_DIRECT_BOOT_UNAWARE, userHandle); if (DEBUG_MULTIUSER) { Log.i(LOG_TAG, "getApplicationCollectionInternal simFullReceivers=" + simFullReceivers); Loading Loading @@ -631,7 +632,8 @@ public final class SmsApplication { } // We only make the change if the new package is valid PackageManager packageManager = context.getPackageManager(); PackageManager packageManager = context.createContextAsUser(userHandle, 0).getPackageManager(); Collection<SmsApplicationData> applications = getApplicationCollectionInternal( context, userId); SmsApplicationData oldAppData = oldPackageName != null ? Loading @@ -642,8 +644,7 @@ public final class SmsApplication { AppOpsManager appOps = (AppOpsManager)context.getSystemService(Context.APP_OPS_SERVICE); if (oldPackageName != null) { try { int uid = packageManager.getPackageInfoAsUser( oldPackageName, 0, userId).applicationInfo.uid; int uid = packageManager.getPackageInfo(oldPackageName, 0).applicationInfo.uid; setExclusiveAppops(oldPackageName, appOps, uid, AppOpsManager.MODE_DEFAULT); } catch (NameNotFoundException e) { Rlog.w(LOG_TAG, "Old SMS package not found: " + oldPackageName); Loading Loading @@ -807,9 +808,16 @@ public final class SmsApplication { } private void onPackageChanged() { PackageManager packageManager = mContext.getPackageManager(); int userId; try { userId = getSendingUser().getIdentifier(); } catch (NullPointerException e) { // This should never happen in prod -- unit tests will put the receiver into a // unusual state where the pending result is null, which produces a NPE when calling // getSendingUserId. Just pretend like it's the system user for testing. userId = UserHandle.USER_SYSTEM; } Context userContext = mContext; final int userId = getSendingUserId(); if (userId != UserHandle.USER_SYSTEM) { try { userContext = mContext.createPackageContextAsUser(mContext.getPackageName(), 0, Loading @@ -820,10 +828,11 @@ public final class SmsApplication { } } } PackageManager packageManager = userContext.getPackageManager(); // Ensure this component is still configured as the preferred activity ComponentName componentName = getDefaultSendToApplication(userContext, true); if (componentName != null) { configurePreferredActivity(packageManager, componentName, userId); configurePreferredActivity(packageManager, componentName); } } } Loading @@ -835,41 +844,36 @@ public final class SmsApplication { @UnsupportedAppUsage private static void configurePreferredActivity(PackageManager packageManager, ComponentName componentName, int userId) { ComponentName componentName) { // Add the four activity preferences we want to direct to this app. replacePreferredActivity(packageManager, componentName, userId, SCHEME_SMS); replacePreferredActivity(packageManager, componentName, userId, SCHEME_SMSTO); replacePreferredActivity(packageManager, componentName, userId, SCHEME_MMS); replacePreferredActivity(packageManager, componentName, userId, SCHEME_MMSTO); replacePreferredActivity(packageManager, componentName, SCHEME_SMS); replacePreferredActivity(packageManager, componentName, SCHEME_SMSTO); replacePreferredActivity(packageManager, componentName, SCHEME_MMS); replacePreferredActivity(packageManager, componentName, SCHEME_MMSTO); } /** * Updates the ACTION_SENDTO activity to the specified component for the specified scheme. */ private static void replacePreferredActivity(PackageManager packageManager, ComponentName componentName, int userId, String scheme) { ComponentName componentName, String scheme) { // Build the set of existing activities that handle this scheme Intent intent = new Intent(Intent.ACTION_SENDTO, Uri.fromParts(scheme, "", null)); List<ResolveInfo> resolveInfoList = packageManager.queryIntentActivitiesAsUser( intent, PackageManager.MATCH_DEFAULT_ONLY | PackageManager.GET_RESOLVED_FILTER, userId); List<ResolveInfo> resolveInfoList = packageManager.queryIntentActivities( intent, PackageManager.MATCH_DEFAULT_ONLY | PackageManager.GET_RESOLVED_FILTER); // Build the set of ComponentNames for these activities final int n = resolveInfoList.size(); ComponentName[] set = new ComponentName[n]; for (int i = 0; i < n; i++) { ResolveInfo info = resolveInfoList.get(i); set[i] = new ComponentName(info.activityInfo.packageName, info.activityInfo.name); } List<ComponentName> components = resolveInfoList.stream().map(info -> new ComponentName(info.activityInfo.packageName, info.activityInfo.name)) .collect(Collectors.toList()); // Update the preferred SENDTO activity for the specified scheme IntentFilter intentFilter = new IntentFilter(); intentFilter.addAction(Intent.ACTION_SENDTO); intentFilter.addCategory(Intent.CATEGORY_DEFAULT); intentFilter.addDataScheme(scheme); packageManager.replacePreferredActivityAsUser(intentFilter, packageManager.replacePreferredActivity(intentFilter, IntentFilter.MATCH_CATEGORY_SCHEME + IntentFilter.MATCH_ADJUSTMENT_NORMAL, set, componentName, userId); components, componentName); } /** Loading tests/TelephonyCommonTests/jarjar-rules.txt +2 −0 Original line number Diff line number Diff line rule com.android.internal.telephony.SmsApplication* com.android.internal.telephony.tests.SmsApplication@1 rule android.telephony.PackageChangeReceiver* com.android.internal.telephony.tests.PackageChangeReceiver@1 rule com.android.internal.os.BackgroundThread* com.android.internal.telephony.tests.BackgroundThread@1 tests/TelephonyCommonTests/src/com/android/internal/telephony/tests/SmsApplicationTest.java +55 −2 Original line number Diff line number Diff line Loading @@ -17,26 +17,34 @@ package com.android.internal.telephony.tests; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; import static org.mockito.ArgumentMatchers.anyInt; import static org.mockito.ArgumentMatchers.eq; import static org.mockito.ArgumentMatchers.isNotNull; import static org.mockito.ArgumentMatchers.isNull; import static org.mockito.ArgumentMatchers.nullable; import static org.mockito.Mockito.atLeastOnce; import static org.mockito.Mockito.doAnswer; import static org.mockito.Mockito.times; 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.BroadcastReceiver; import android.content.ComponentName; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; 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.net.Uri; import android.os.Handler; import android.os.UserHandle; import android.provider.Telephony; import android.telephony.TelephonyManager; Loading @@ -48,11 +56,15 @@ import com.android.internal.telephony.SmsApplication; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.ArgumentCaptor; import org.mockito.Mock; import org.mockito.MockitoAnnotations; import java.util.Arrays; import java.util.Collections; import java.util.List; import java.util.Set; import java.util.stream.Collectors; /** * Unit tests for the {@link SmsApplication} utility class Loading Loading @@ -80,6 +92,13 @@ public class SmsApplicationTest { AppOpsManager.OPSTR_READ_CELL_BROADCASTS }; private static final Set<String> SCHEMES_FOR_PREFERRED_APP = Arrays.stream(new String[]{ "mms", "mmsto", "sms", "smsto" }).collect(Collectors.toSet()); @Mock private Context mContext; @Mock private TelephonyManager mTelephonyManager; @Mock private RoleManager mRoleManager; Loading @@ -94,13 +113,16 @@ public class SmsApplicationTest { when(mContext.getPackageManager()).thenReturn(mPackageManager); when(mContext.getSystemService(RoleManager.class)).thenReturn(mRoleManager); when(mContext.getSystemService(AppOpsManager.class)).thenReturn(mAppOpsManager); when(mContext.createContextAsUser(isNotNull(), anyInt())).thenReturn(mContext); doAnswer(invocation -> getResolveInfosForIntent(invocation.getArgument(0))) .when(mPackageManager) .queryBroadcastReceiversAsUser(nullable(Intent.class), anyInt(), anyInt()); .queryBroadcastReceiversAsUser(nullable(Intent.class), anyInt(), nullable(UserHandle.class)); doAnswer(invocation -> getResolveInfosForIntent(invocation.getArgument(0))) .when(mPackageManager) .queryIntentActivitiesAsUser(nullable(Intent.class), anyInt(), anyInt()); .queryIntentActivitiesAsUser(nullable(Intent.class), anyInt(), nullable(UserHandle.class)); doAnswer(invocation -> getResolveInfosForIntent(invocation.getArgument(0))) .when(mPackageManager) .queryIntentServicesAsUser(nullable(Intent.class), anyInt(), Loading Loading @@ -137,6 +159,37 @@ public class SmsApplicationTest { AppOpsManager.MODE_ALLOWED); } @Test public void testPackageChanged() throws Exception { setupPackageInfosForCoreApps(); SmsApplication.initSmsPackageMonitor(mContext); verify(mContext).createContextAsUser(eq(UserHandle.ALL), anyInt()); ArgumentCaptor<BroadcastReceiver> captor = ArgumentCaptor.forClass(BroadcastReceiver.class); verify(mContext).registerReceiver(captor.capture(), isNotNull(), isNull(), nullable(Handler.class)); BroadcastReceiver smsPackageMonitor = captor.getValue(); Intent packageChangedIntent = new Intent(Intent.ACTION_PACKAGE_CHANGED); packageChangedIntent.setData( Uri.fromParts("package", TEST_COMPONENT_NAME.getPackageName(), null)); smsPackageMonitor.onReceive(mContext, packageChangedIntent); ArgumentCaptor<IntentFilter> intentFilterCaptor = ArgumentCaptor.forClass(IntentFilter.class); verify(mPackageManager, times(SCHEMES_FOR_PREFERRED_APP.size())) .replacePreferredActivity(intentFilterCaptor.capture(), eq(IntentFilter.MATCH_CATEGORY_SCHEME | IntentFilter.MATCH_ADJUSTMENT_NORMAL), isNotNull(List.class), eq(new ComponentName(TEST_COMPONENT_NAME.getPackageName(), SEND_TO_NAME))); Set<String> capturedSchemes = intentFilterCaptor.getAllValues().stream() .map(intentFilter -> intentFilter.getDataScheme(0)) .collect(Collectors.toSet()); assertEquals(SCHEMES_FOR_PREFERRED_APP.size(), capturedSchemes.size()); assertTrue(SCHEMES_FOR_PREFERRED_APP.containsAll(capturedSchemes)); } private void setupPackageInfosForCoreApps() throws Exception { PackageInfo phonePackageInfo = new PackageInfo(); ApplicationInfo phoneApplicationInfo = new ApplicationInfo(); Loading tests/TelephonyCommonTests/Android.bp +1 −1 File changed.Contains only whitespace changes. Show changes Loading
telephony/common/com/android/internal/telephony/PackageChangeReceiver.java +19 −15 Original line number Diff line number Diff line Loading @@ -24,17 +24,17 @@ import android.content.Intent; import android.content.IntentFilter; import android.net.Uri; import android.os.Handler; import android.os.HandlerThread; import android.os.Looper; import android.os.UserHandle; import com.android.internal.os.BackgroundThread; /** * Helper class for monitoring the state of packages: adding, removing, * updating, and disappearing and reappearing on the SD card. */ public abstract class PackageChangeReceiver extends BroadcastReceiver { static final IntentFilter sPackageIntentFilter = new IntentFilter(); private static HandlerThread sHandlerThread; static { sPackageIntentFilter.addAction(Intent.ACTION_PACKAGE_ADDED); sPackageIntentFilter.addAction(Intent.ACTION_PACKAGE_REMOVED); Loading @@ -43,28 +43,24 @@ public abstract class PackageChangeReceiver extends BroadcastReceiver { sPackageIntentFilter.addAction(Intent.ACTION_PACKAGE_RESTARTED); sPackageIntentFilter.addDataScheme("package"); } // Keep an instance of Context around as long as we still want the receiver: // if the instance of Context gets garbage-collected, it'll unregister the receiver, so only // unset when we want to unregister. Context mRegisteredContext; /** * To register the intents that needed for monitoring the state of packages * To register the intents that needed for monitoring the state of packages. Once this method * has been called on an instance of {@link PackageChangeReceiver}, all subsequent calls must * have the same {@code user} argument. */ public void register(@NonNull Context context, @Nullable Looper thread, @Nullable UserHandle user) { if (mRegisteredContext != null) { throw new IllegalStateException("Already registered"); } Handler handler = (thread == null) ? BackgroundThread.getHandler() : new Handler(thread); mRegisteredContext = context; if (handler != null) { if (user != null) { context.registerReceiverAsUser(this, user, sPackageIntentFilter, null, handler); } else { context.registerReceiver(this, sPackageIntentFilter, null, handler); } } else { throw new NullPointerException(); } Handler handler = new Handler(thread == null ? getStaticLooper() : thread); mRegisteredContext = user == null ? context : context.createContextAsUser(user, 0); mRegisteredContext.registerReceiver(this, sPackageIntentFilter, null, handler); } /** Loading @@ -78,6 +74,14 @@ public abstract class PackageChangeReceiver extends BroadcastReceiver { mRegisteredContext = null; } private static synchronized Looper getStaticLooper() { if (sHandlerThread == null) { sHandlerThread = new HandlerThread(PackageChangeReceiver.class.getSimpleName()); sHandlerThread.start(); } return sHandlerThread.getLooper(); } /** * This method is invoked when receive the Intent.ACTION_PACKAGE_ADDED */ Loading
telephony/common/com/android/internal/telephony/SmsApplication.java +35 −31 Original line number Diff line number Diff line Loading @@ -58,7 +58,7 @@ import java.util.concurrent.ExecutionException; import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeoutException; import java.util.function.Consumer; import java.util.stream.Collectors; /** Loading Loading @@ -250,6 +250,7 @@ public final class SmsApplication { private static Collection<SmsApplicationData> getApplicationCollectionInternal( Context context, int userId) { PackageManager packageManager = context.getPackageManager(); UserHandle userHandle = UserHandle.of(userId); // Get the list of apps registered for SMS Intent intent = new Intent(Intents.SMS_DELIVER_ACTION); Loading @@ -258,7 +259,7 @@ public final class SmsApplication { } List<ResolveInfo> smsReceivers = packageManager.queryBroadcastReceiversAsUser(intent, PackageManager.MATCH_DIRECT_BOOT_AWARE | PackageManager.MATCH_DIRECT_BOOT_UNAWARE, userId); userHandle); HashMap<String, SmsApplicationData> receivers = new HashMap<String, SmsApplicationData>(); Loading @@ -285,7 +286,7 @@ public final class SmsApplication { intent.setDataAndType(null, "application/vnd.wap.mms-message"); List<ResolveInfo> mmsReceivers = packageManager.queryBroadcastReceiversAsUser(intent, PackageManager.MATCH_DIRECT_BOOT_AWARE | PackageManager.MATCH_DIRECT_BOOT_UNAWARE, userId); userHandle); for (ResolveInfo resolveInfo : mmsReceivers) { final ActivityInfo activityInfo = resolveInfo.activityInfo; if (activityInfo == null) { Loading Loading @@ -327,7 +328,7 @@ public final class SmsApplication { Uri.fromParts(SCHEME_SMSTO, "", null)); List<ResolveInfo> sendToActivities = packageManager.queryIntentActivitiesAsUser(intent, PackageManager.MATCH_DIRECT_BOOT_AWARE | PackageManager.MATCH_DIRECT_BOOT_UNAWARE, userId); userHandle); for (ResolveInfo resolveInfo : sendToActivities) { final ActivityInfo activityInfo = resolveInfo.activityInfo; if (activityInfo == null) { Loading @@ -345,7 +346,7 @@ public final class SmsApplication { List<ResolveInfo> smsAppChangedReceivers = packageManager.queryBroadcastReceiversAsUser(intent, PackageManager.MATCH_DIRECT_BOOT_AWARE | PackageManager.MATCH_DIRECT_BOOT_UNAWARE, userId); | PackageManager.MATCH_DIRECT_BOOT_UNAWARE, userHandle); if (DEBUG_MULTIUSER) { Log.i(LOG_TAG, "getApplicationCollectionInternal smsAppChangedActivities=" + smsAppChangedReceivers); Loading @@ -372,7 +373,7 @@ public final class SmsApplication { List<ResolveInfo> providerChangedReceivers = packageManager.queryBroadcastReceiversAsUser(intent, PackageManager.MATCH_DIRECT_BOOT_AWARE | PackageManager.MATCH_DIRECT_BOOT_UNAWARE, userId); | PackageManager.MATCH_DIRECT_BOOT_UNAWARE, userHandle); if (DEBUG_MULTIUSER) { Log.i(LOG_TAG, "getApplicationCollectionInternal providerChangedActivities=" + providerChangedReceivers); Loading @@ -399,7 +400,7 @@ public final class SmsApplication { List<ResolveInfo> simFullReceivers = packageManager.queryBroadcastReceiversAsUser(intent, PackageManager.MATCH_DIRECT_BOOT_AWARE | PackageManager.MATCH_DIRECT_BOOT_UNAWARE, userId); | PackageManager.MATCH_DIRECT_BOOT_UNAWARE, userHandle); if (DEBUG_MULTIUSER) { Log.i(LOG_TAG, "getApplicationCollectionInternal simFullReceivers=" + simFullReceivers); Loading Loading @@ -631,7 +632,8 @@ public final class SmsApplication { } // We only make the change if the new package is valid PackageManager packageManager = context.getPackageManager(); PackageManager packageManager = context.createContextAsUser(userHandle, 0).getPackageManager(); Collection<SmsApplicationData> applications = getApplicationCollectionInternal( context, userId); SmsApplicationData oldAppData = oldPackageName != null ? Loading @@ -642,8 +644,7 @@ public final class SmsApplication { AppOpsManager appOps = (AppOpsManager)context.getSystemService(Context.APP_OPS_SERVICE); if (oldPackageName != null) { try { int uid = packageManager.getPackageInfoAsUser( oldPackageName, 0, userId).applicationInfo.uid; int uid = packageManager.getPackageInfo(oldPackageName, 0).applicationInfo.uid; setExclusiveAppops(oldPackageName, appOps, uid, AppOpsManager.MODE_DEFAULT); } catch (NameNotFoundException e) { Rlog.w(LOG_TAG, "Old SMS package not found: " + oldPackageName); Loading Loading @@ -807,9 +808,16 @@ public final class SmsApplication { } private void onPackageChanged() { PackageManager packageManager = mContext.getPackageManager(); int userId; try { userId = getSendingUser().getIdentifier(); } catch (NullPointerException e) { // This should never happen in prod -- unit tests will put the receiver into a // unusual state where the pending result is null, which produces a NPE when calling // getSendingUserId. Just pretend like it's the system user for testing. userId = UserHandle.USER_SYSTEM; } Context userContext = mContext; final int userId = getSendingUserId(); if (userId != UserHandle.USER_SYSTEM) { try { userContext = mContext.createPackageContextAsUser(mContext.getPackageName(), 0, Loading @@ -820,10 +828,11 @@ public final class SmsApplication { } } } PackageManager packageManager = userContext.getPackageManager(); // Ensure this component is still configured as the preferred activity ComponentName componentName = getDefaultSendToApplication(userContext, true); if (componentName != null) { configurePreferredActivity(packageManager, componentName, userId); configurePreferredActivity(packageManager, componentName); } } } Loading @@ -835,41 +844,36 @@ public final class SmsApplication { @UnsupportedAppUsage private static void configurePreferredActivity(PackageManager packageManager, ComponentName componentName, int userId) { ComponentName componentName) { // Add the four activity preferences we want to direct to this app. replacePreferredActivity(packageManager, componentName, userId, SCHEME_SMS); replacePreferredActivity(packageManager, componentName, userId, SCHEME_SMSTO); replacePreferredActivity(packageManager, componentName, userId, SCHEME_MMS); replacePreferredActivity(packageManager, componentName, userId, SCHEME_MMSTO); replacePreferredActivity(packageManager, componentName, SCHEME_SMS); replacePreferredActivity(packageManager, componentName, SCHEME_SMSTO); replacePreferredActivity(packageManager, componentName, SCHEME_MMS); replacePreferredActivity(packageManager, componentName, SCHEME_MMSTO); } /** * Updates the ACTION_SENDTO activity to the specified component for the specified scheme. */ private static void replacePreferredActivity(PackageManager packageManager, ComponentName componentName, int userId, String scheme) { ComponentName componentName, String scheme) { // Build the set of existing activities that handle this scheme Intent intent = new Intent(Intent.ACTION_SENDTO, Uri.fromParts(scheme, "", null)); List<ResolveInfo> resolveInfoList = packageManager.queryIntentActivitiesAsUser( intent, PackageManager.MATCH_DEFAULT_ONLY | PackageManager.GET_RESOLVED_FILTER, userId); List<ResolveInfo> resolveInfoList = packageManager.queryIntentActivities( intent, PackageManager.MATCH_DEFAULT_ONLY | PackageManager.GET_RESOLVED_FILTER); // Build the set of ComponentNames for these activities final int n = resolveInfoList.size(); ComponentName[] set = new ComponentName[n]; for (int i = 0; i < n; i++) { ResolveInfo info = resolveInfoList.get(i); set[i] = new ComponentName(info.activityInfo.packageName, info.activityInfo.name); } List<ComponentName> components = resolveInfoList.stream().map(info -> new ComponentName(info.activityInfo.packageName, info.activityInfo.name)) .collect(Collectors.toList()); // Update the preferred SENDTO activity for the specified scheme IntentFilter intentFilter = new IntentFilter(); intentFilter.addAction(Intent.ACTION_SENDTO); intentFilter.addCategory(Intent.CATEGORY_DEFAULT); intentFilter.addDataScheme(scheme); packageManager.replacePreferredActivityAsUser(intentFilter, packageManager.replacePreferredActivity(intentFilter, IntentFilter.MATCH_CATEGORY_SCHEME + IntentFilter.MATCH_ADJUSTMENT_NORMAL, set, componentName, userId); components, componentName); } /** Loading
tests/TelephonyCommonTests/jarjar-rules.txt +2 −0 Original line number Diff line number Diff line rule com.android.internal.telephony.SmsApplication* com.android.internal.telephony.tests.SmsApplication@1 rule android.telephony.PackageChangeReceiver* com.android.internal.telephony.tests.PackageChangeReceiver@1 rule com.android.internal.os.BackgroundThread* com.android.internal.telephony.tests.BackgroundThread@1
tests/TelephonyCommonTests/src/com/android/internal/telephony/tests/SmsApplicationTest.java +55 −2 Original line number Diff line number Diff line Loading @@ -17,26 +17,34 @@ package com.android.internal.telephony.tests; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; import static org.mockito.ArgumentMatchers.anyInt; import static org.mockito.ArgumentMatchers.eq; import static org.mockito.ArgumentMatchers.isNotNull; import static org.mockito.ArgumentMatchers.isNull; import static org.mockito.ArgumentMatchers.nullable; import static org.mockito.Mockito.atLeastOnce; import static org.mockito.Mockito.doAnswer; import static org.mockito.Mockito.times; 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.BroadcastReceiver; import android.content.ComponentName; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; 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.net.Uri; import android.os.Handler; import android.os.UserHandle; import android.provider.Telephony; import android.telephony.TelephonyManager; Loading @@ -48,11 +56,15 @@ import com.android.internal.telephony.SmsApplication; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.ArgumentCaptor; import org.mockito.Mock; import org.mockito.MockitoAnnotations; import java.util.Arrays; import java.util.Collections; import java.util.List; import java.util.Set; import java.util.stream.Collectors; /** * Unit tests for the {@link SmsApplication} utility class Loading Loading @@ -80,6 +92,13 @@ public class SmsApplicationTest { AppOpsManager.OPSTR_READ_CELL_BROADCASTS }; private static final Set<String> SCHEMES_FOR_PREFERRED_APP = Arrays.stream(new String[]{ "mms", "mmsto", "sms", "smsto" }).collect(Collectors.toSet()); @Mock private Context mContext; @Mock private TelephonyManager mTelephonyManager; @Mock private RoleManager mRoleManager; Loading @@ -94,13 +113,16 @@ public class SmsApplicationTest { when(mContext.getPackageManager()).thenReturn(mPackageManager); when(mContext.getSystemService(RoleManager.class)).thenReturn(mRoleManager); when(mContext.getSystemService(AppOpsManager.class)).thenReturn(mAppOpsManager); when(mContext.createContextAsUser(isNotNull(), anyInt())).thenReturn(mContext); doAnswer(invocation -> getResolveInfosForIntent(invocation.getArgument(0))) .when(mPackageManager) .queryBroadcastReceiversAsUser(nullable(Intent.class), anyInt(), anyInt()); .queryBroadcastReceiversAsUser(nullable(Intent.class), anyInt(), nullable(UserHandle.class)); doAnswer(invocation -> getResolveInfosForIntent(invocation.getArgument(0))) .when(mPackageManager) .queryIntentActivitiesAsUser(nullable(Intent.class), anyInt(), anyInt()); .queryIntentActivitiesAsUser(nullable(Intent.class), anyInt(), nullable(UserHandle.class)); doAnswer(invocation -> getResolveInfosForIntent(invocation.getArgument(0))) .when(mPackageManager) .queryIntentServicesAsUser(nullable(Intent.class), anyInt(), Loading Loading @@ -137,6 +159,37 @@ public class SmsApplicationTest { AppOpsManager.MODE_ALLOWED); } @Test public void testPackageChanged() throws Exception { setupPackageInfosForCoreApps(); SmsApplication.initSmsPackageMonitor(mContext); verify(mContext).createContextAsUser(eq(UserHandle.ALL), anyInt()); ArgumentCaptor<BroadcastReceiver> captor = ArgumentCaptor.forClass(BroadcastReceiver.class); verify(mContext).registerReceiver(captor.capture(), isNotNull(), isNull(), nullable(Handler.class)); BroadcastReceiver smsPackageMonitor = captor.getValue(); Intent packageChangedIntent = new Intent(Intent.ACTION_PACKAGE_CHANGED); packageChangedIntent.setData( Uri.fromParts("package", TEST_COMPONENT_NAME.getPackageName(), null)); smsPackageMonitor.onReceive(mContext, packageChangedIntent); ArgumentCaptor<IntentFilter> intentFilterCaptor = ArgumentCaptor.forClass(IntentFilter.class); verify(mPackageManager, times(SCHEMES_FOR_PREFERRED_APP.size())) .replacePreferredActivity(intentFilterCaptor.capture(), eq(IntentFilter.MATCH_CATEGORY_SCHEME | IntentFilter.MATCH_ADJUSTMENT_NORMAL), isNotNull(List.class), eq(new ComponentName(TEST_COMPONENT_NAME.getPackageName(), SEND_TO_NAME))); Set<String> capturedSchemes = intentFilterCaptor.getAllValues().stream() .map(intentFilter -> intentFilter.getDataScheme(0)) .collect(Collectors.toSet()); assertEquals(SCHEMES_FOR_PREFERRED_APP.size(), capturedSchemes.size()); assertTrue(SCHEMES_FOR_PREFERRED_APP.containsAll(capturedSchemes)); } private void setupPackageInfosForCoreApps() throws Exception { PackageInfo phonePackageInfo = new PackageInfo(); ApplicationInfo phoneApplicationInfo = new ApplicationInfo(); Loading
tests/TelephonyCommonTests/Android.bp +1 −1 File changed.Contains only whitespace changes. Show changes