From a5a0d94023b2d9b7c9019fc40e7479995b82066c Mon Sep 17 00:00:00 2001 From: Svetoslav Date: Wed, 1 Jul 2015 19:49:58 -0700 Subject: [PATCH] Make granting default SMS and Phone permissions robust The default dialer and sms apps are provided by the telecomm stak which is brought up asynchronously as a service to which the system binds. Hence, by the time we grant default permissions this service is not bound and we do not know the default dialer (accidentally the default SMS app is available before the service is up). Now the default permission grant code is robust to handle both cases of the default sms and phone apps being available at grant time or asynchronously. bug:22208642 Change-Id: I6385a0432368731aa9caea046d57eccbfb5abac0 --- .../pm/DefaultPermissionGrantPolicy.java | 79 ++++++++++----- .../server/telecom/TelecomLoaderService.java | 95 ++++++++++++++++--- 2 files changed, 136 insertions(+), 38 deletions(-) diff --git a/services/core/java/com/android/server/pm/DefaultPermissionGrantPolicy.java b/services/core/java/com/android/server/pm/DefaultPermissionGrantPolicy.java index cb7d932164f50..cb65b757ffce4 100644 --- a/services/core/java/com/android/server/pm/DefaultPermissionGrantPolicy.java +++ b/services/core/java/com/android/server/pm/DefaultPermissionGrantPolicy.java @@ -287,20 +287,6 @@ final class DefaultPermissionGrantPolicy { grantRuntimePermissionsLPw(setupPackage, SETTINGS_PERMISSIONS, userId); } - // Dialer - if (dialerAppPackageNames != null) { - for (String dialerAppPackageName : dialerAppPackageNames) { - PackageParser.Package dialerPackage = getPackageLPr(dialerAppPackageName); - if (dialerPackage != null - && doesPackageSupportRuntimePermissions(dialerPackage)) { - grantRuntimePermissionsLPw(dialerPackage, PHONE_PERMISSIONS, userId); - grantRuntimePermissionsLPw(dialerPackage, CONTACTS_PERMISSIONS, userId); - grantRuntimePermissionsLPw(dialerPackage, SMS_PERMISSIONS, userId); - grantRuntimePermissionsLPw(dialerPackage, MICROPHONE_PERMISSIONS, userId); - } - } - } - // Camera Intent cameraIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE); PackageParser.Package cameraPackage = getDefaultSystemHandlerActivityPackageLPr( @@ -342,15 +328,37 @@ final class DefaultPermissionGrantPolicy { grantRuntimePermissionsLPw(storagePackage, STORAGE_PERMISSIONS, userId); } + // Dialer + if (dialerAppPackageNames == null) { + Intent dialerIntent = new Intent(Intent.ACTION_DIAL); + PackageParser.Package dialerPackage = getDefaultSystemHandlerActivityPackageLPr( + dialerIntent, userId); + if (dialerPackage != null) { + grantDefaultPermissionsToDefaultSystemDialerAppLPr(dialerPackage, userId); + } + } else { + for (String dialerAppPackageName : dialerAppPackageNames) { + PackageParser.Package dialerPackage = getSystemPackageLPr(dialerAppPackageName); + if (dialerPackage != null) { + grantDefaultPermissionsToDefaultSystemDialerAppLPr(dialerPackage, userId); + } + } + } + // SMS - if (smsAppPackageNames != null) { + if (smsAppPackageNames == null) { + Intent smsIntent = new Intent(Intent.ACTION_MAIN); + smsIntent.addCategory(Intent.CATEGORY_APP_MESSAGING); + PackageParser.Package smsPackage = getDefaultSystemHandlerActivityPackageLPr( + smsIntent, userId); + if (smsPackage != null) { + grantDefaultPermissionsToDefaultSystemSmsAppLPr(smsPackage, userId); + } + } else { for (String smsPackageName : smsAppPackageNames) { - PackageParser.Package smsPackage = getPackageLPr(smsPackageName); - if (smsPackage != null - && doesPackageSupportRuntimePermissions(smsPackage)) { - grantRuntimePermissionsLPw(smsPackage, PHONE_PERMISSIONS, userId); - grantRuntimePermissionsLPw(smsPackage, CONTACTS_PERMISSIONS, userId); - grantRuntimePermissionsLPw(smsPackage, SMS_PERMISSIONS, userId); + PackageParser.Package smsPackage = getSystemPackageLPr(smsPackageName); + if (smsPackage != null) { + grantDefaultPermissionsToDefaultSystemSmsAppLPr(smsPackage, userId); } } } @@ -379,8 +387,8 @@ final class DefaultPermissionGrantPolicy { } // Calendar provider sync adapters - List calendarSyncAdapters = - getHeadlessSyncAdapterPackagesLPr(calendarSyncAdapterPackages, + List calendarSyncAdapters = getHeadlessSyncAdapterPackagesLPr( + calendarSyncAdapterPackages, userId); final int calendarSyncAdapterCount = calendarSyncAdapters.size(); for (int i = 0; i < calendarSyncAdapterCount; i++) { @@ -403,8 +411,8 @@ final class DefaultPermissionGrantPolicy { } // Contacts provider sync adapters - List contactsSyncAdapters = - getHeadlessSyncAdapterPackagesLPr(contactsSyncAdapterPackages, + List contactsSyncAdapters = getHeadlessSyncAdapterPackagesLPr( + contactsSyncAdapterPackages, userId); final int contactsSyncAdapterCount = contactsSyncAdapters.size(); for (int i = 0; i < contactsSyncAdapterCount; i++) { @@ -541,6 +549,27 @@ final class DefaultPermissionGrantPolicy { } } + private void grantDefaultPermissionsToDefaultSystemDialerAppLPr( + PackageParser.Package dialerPackage, int userId) { + if (doesPackageSupportRuntimePermissions(dialerPackage)) { + grantRuntimePermissionsLPw(dialerPackage, PHONE_PERMISSIONS, userId); + grantRuntimePermissionsLPw(dialerPackage, CONTACTS_PERMISSIONS, userId); + grantRuntimePermissionsLPw(dialerPackage, SMS_PERMISSIONS, userId); + grantRuntimePermissionsLPw(dialerPackage, MICROPHONE_PERMISSIONS, userId); + } + } + + + private void grantDefaultPermissionsToDefaultSystemSmsAppLPr( + PackageParser.Package smsPackage, int userId) { + if (doesPackageSupportRuntimePermissions(smsPackage)) { + grantRuntimePermissionsLPw(smsPackage, PHONE_PERMISSIONS, userId); + grantRuntimePermissionsLPw(smsPackage, CONTACTS_PERMISSIONS, userId); + grantRuntimePermissionsLPw(smsPackage, SMS_PERMISSIONS, userId); + } + } + + public void grantDefaultPermissionsToDefaultSmsAppLPr(String packageName, int userId) { Log.i(TAG, "Granting permissions to default sms app for user:" + userId); if (packageName == null) { diff --git a/services/core/java/com/android/server/telecom/TelecomLoaderService.java b/services/core/java/com/android/server/telecom/TelecomLoaderService.java index b165b42c51bdf..c2ce572262dae 100644 --- a/services/core/java/com/android/server/telecom/TelecomLoaderService.java +++ b/services/core/java/com/android/server/telecom/TelecomLoaderService.java @@ -31,8 +31,11 @@ import android.os.ServiceManager; import android.os.UserHandle; import android.provider.Settings; import android.telecom.DefaultDialerManager; +import android.util.IntArray; import android.util.Slog; +import android.util.SparseBooleanArray; +import com.android.internal.annotations.GuardedBy; import com.android.internal.telephony.SmsApplication; import com.android.server.LocalServices; import com.android.server.SystemService; @@ -59,6 +62,41 @@ public class TelecomLoaderService extends SystemService { }, 0); SmsApplication.getDefaultMmsApplication(mContext, false); ServiceManager.addService(Context.TELECOM_SERVICE, service); + + synchronized (mLock) { + if (mDefaultSmsAppRequests != null || mDefaultDialerAppRequests != null) { + final PackageManagerInternal packageManagerInternal = LocalServices + .getService(PackageManagerInternal.class); + + if (mDefaultSmsAppRequests != null) { + ComponentName smsComponent = SmsApplication.getDefaultSmsApplication( + mContext, true); + if (smsComponent != null) { + final int requestCount = mDefaultSmsAppRequests.size(); + for (int i = requestCount - 1; i >= 0; i--) { + final int userid = mDefaultSmsAppRequests.get(i); + mDefaultSmsAppRequests.remove(i); + packageManagerInternal.grantDefaultPermissionsToDefaultSmsApp( + smsComponent.getPackageName(), userid); + } + } + } + + if (mDefaultDialerAppRequests != null) { + String packageName = DefaultDialerManager.getDefaultDialerApplication( + mContext); + if (packageName != null) { + final int requestCount = mDefaultDialerAppRequests.size(); + for (int i = requestCount - 1; i >= 0; i--) { + final int userId = mDefaultDialerAppRequests.get(i); + mDefaultDialerAppRequests.remove(i); + packageManagerInternal.grantDefaultPermissionsToDefaultDialerApp( + packageName, userId); + } + } + } + } + } } catch (RemoteException e) { Slog.w(TAG, "Failed linking to death."); } @@ -76,7 +114,17 @@ public class TelecomLoaderService extends SystemService { private static final String SERVICE_ACTION = "com.android.ITelecomService"; + private final Object mLock = new Object(); + + @GuardedBy("mLock") + private IntArray mDefaultSmsAppRequests; + + @GuardedBy("mLock") + private IntArray mDefaultDialerAppRequests; + private final Context mContext; + + @GuardedBy("mLock") private TelecomServiceConnection mServiceConnection; public TelecomLoaderService(Context context) { @@ -98,24 +146,27 @@ public class TelecomLoaderService extends SystemService { } private void connectToTelecom() { - if (mServiceConnection != null) { - // TODO: Is unbinding worth doing or wait for system to rebind? - mContext.unbindService(mServiceConnection); - mServiceConnection = null; - } + synchronized (mLock) { + if (mServiceConnection != null) { + // TODO: Is unbinding worth doing or wait for system to rebind? + mContext.unbindService(mServiceConnection); + mServiceConnection = null; + } - TelecomServiceConnection serviceConnection = new TelecomServiceConnection(); - Intent intent = new Intent(SERVICE_ACTION); - intent.setComponent(SERVICE_COMPONENT); - int flags = Context.BIND_IMPORTANT | Context.BIND_FOREGROUND_SERVICE - | Context.BIND_AUTO_CREATE; + TelecomServiceConnection serviceConnection = new TelecomServiceConnection(); + Intent intent = new Intent(SERVICE_ACTION); + intent.setComponent(SERVICE_COMPONENT); + int flags = Context.BIND_IMPORTANT | Context.BIND_FOREGROUND_SERVICE + | Context.BIND_AUTO_CREATE; - // Bind to Telecom and register the service - if (mContext.bindServiceAsUser(intent, serviceConnection, flags, UserHandle.OWNER)) { - mServiceConnection = serviceConnection; + // Bind to Telecom and register the service + if (mContext.bindServiceAsUser(intent, serviceConnection, flags, UserHandle.OWNER)) { + mServiceConnection = serviceConnection; + } } } + private void registerDefaultAppProviders() { final PackageManagerInternal packageManagerInternal = LocalServices.getService( PackageManagerInternal.class); @@ -125,6 +176,15 @@ public class TelecomLoaderService extends SystemService { new PackageManagerInternal.PackagesProvider() { @Override public String[] getPackages(int userId) { + synchronized (mLock) { + if (mServiceConnection == null) { + if (mDefaultSmsAppRequests == null) { + mDefaultSmsAppRequests = new IntArray(); + } + mDefaultSmsAppRequests.add(userId); + return null; + } + } ComponentName smsComponent = SmsApplication.getDefaultSmsApplication( mContext, true); if (smsComponent != null) { @@ -139,6 +199,15 @@ public class TelecomLoaderService extends SystemService { new PackageManagerInternal.PackagesProvider() { @Override public String[] getPackages(int userId) { + synchronized (mLock) { + if (mServiceConnection == null) { + if (mDefaultDialerAppRequests == null) { + mDefaultDialerAppRequests = new IntArray(); + } + mDefaultDialerAppRequests.add(userId); + return null; + } + } String packageName = DefaultDialerManager.getDefaultDialerApplication(mContext); if (packageName != null) { return new String[]{packageName};