diff options
11 files changed, 784 insertions, 160 deletions
diff --git a/core/java/android/content/pm/ApplicationInfo.java b/core/java/android/content/pm/ApplicationInfo.java index 9fb6f4d..6feb860 100644 --- a/core/java/android/content/pm/ApplicationInfo.java +++ b/core/java/android/content/pm/ApplicationInfo.java @@ -962,6 +962,13 @@ public class ApplicationInfo extends PackageItemInfo implements Parcelable { /** * @hide */ + public boolean isPrivilegedApp() { + return (privateFlags & ApplicationInfo.PRIVATE_FLAG_PRIVILEGED) != 0; + } + + /** + * @hide + */ public boolean isUpdatedSystemApp() { return (flags & ApplicationInfo.FLAG_UPDATED_SYSTEM_APP) != 0; } diff --git a/core/java/android/content/pm/PackageManagerInternal.java b/core/java/android/content/pm/PackageManagerInternal.java new file mode 100644 index 0000000..7599bd6 --- /dev/null +++ b/core/java/android/content/pm/PackageManagerInternal.java @@ -0,0 +1,58 @@ +/* + * Copyright (C) 2015 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.content.pm; + +import android.annotation.NonNull; + +/** + * Package manager local system service interface. + * + * @hide Only for use within the system server. + */ +public abstract class PackageManagerInternal { + + /** + * Provider for package names. + */ + public interface PackagesProvider { + + /** + * Gets the packages for a given user. + * @param userId The user id. + * @return The package names. + */ + public String[] getPackages(int userId); + } + + /** + * Sets the location provider packages provider. + * @param provider The packages provider. + */ + public abstract void setLocationPackagesProvider(PackagesProvider provider); + + /** + * Sets the input method packages provider. + * @param provider The packages provider. + */ + public abstract void setImePackagesProvider(PackagesProvider provider); + + /** + * Sets the voice interaction packages provider. + * @param provider The packages provider. + */ + public abstract void setVoiceInteractionPackagesProvider(PackagesProvider provider); +} diff --git a/core/java/android/content/pm/PackageParser.java b/core/java/android/content/pm/PackageParser.java index 287e0c5..faf71ee 100644 --- a/core/java/android/content/pm/PackageParser.java +++ b/core/java/android/content/pm/PackageParser.java @@ -4508,6 +4508,13 @@ public class PackageParser { /** * @hide */ + public boolean isPrivilegedApp() { + return applicationInfo.isPrivilegedApp(); + } + + /** + * @hide + */ public boolean isUpdatedSystemApp() { return applicationInfo.isUpdatedSystemApp(); } diff --git a/services/core/java/com/android/server/InputMethodManagerService.java b/services/core/java/com/android/server/InputMethodManagerService.java index a5d536e..9a9a4ae 100644 --- a/services/core/java/com/android/server/InputMethodManagerService.java +++ b/services/core/java/com/android/server/InputMethodManagerService.java @@ -16,6 +16,7 @@ package com.android.server; import android.annotation.NonNull; +import android.content.pm.PackageManagerInternal; import com.android.internal.content.PackageMonitor; import com.android.internal.inputmethod.InputMethodSubtypeSwitchingController; import com.android.internal.inputmethod.InputMethodSubtypeSwitchingController.ImeSubtypeListItem; @@ -31,6 +32,7 @@ import com.android.internal.view.IInputMethodClient; import com.android.internal.view.IInputMethodManager; import com.android.internal.view.IInputMethodSession; import com.android.internal.view.InputBindResult; +import com.android.server.pm.UserManagerService; import com.android.server.statusbar.StatusBarManagerService; import com.android.server.wm.WindowManagerService; @@ -859,6 +861,38 @@ public class InputMethodManagerService extends IInputMethodManager.Stub // mSettings should be created before buildInputMethodListLocked mSettings = new InputMethodSettings( mRes, context.getContentResolver(), mMethodMap, mMethodList, userId); + + // Let the package manager query which are the default imes + // as they get certain permissions granted by default. + PackageManagerInternal packageManagerInternal = LocalServices.getService( + PackageManagerInternal.class); + packageManagerInternal.setImePackagesProvider( + new PackageManagerInternal.PackagesProvider() { + @Override + public String[] getPackages(int userId) { + synchronized (mMethodMap) { + final int currentUserId = mSettings.getCurrentUserId(); + // TODO: We are switching the current user id in the settings + // object to query it and then revert the user id. Ideally, we + // should call a API in settings with the user id as an argument. + mSettings.setCurrentUserId(userId); + List<InputMethodInfo> imes = mSettings + .getEnabledInputMethodListLocked(); + String[] packageNames = null; + if (imes != null) { + final int imeCount = imes.size(); + packageNames = new String[imeCount]; + for (int i = 0; i < imeCount; i++) { + InputMethodInfo ime = imes.get(i); + packageNames[i] = ime.getPackageName(); + } + } + mSettings.setCurrentUserId(currentUserId); + return packageNames; + } + } + }); + updateCurrentProfileIds(); mFileManager = new InputMethodFileManager(mMethodMap, userId); synchronized (mMethodMap) { diff --git a/services/core/java/com/android/server/LocationManagerService.java b/services/core/java/com/android/server/LocationManagerService.java index c76fc1c..c98f33e 100644 --- a/services/core/java/com/android/server/LocationManagerService.java +++ b/services/core/java/com/android/server/LocationManagerService.java @@ -16,6 +16,7 @@ package com.android.server; +import android.content.pm.PackageManagerInternal; import com.android.internal.content.PackageMonitor; import com.android.internal.location.ProviderProperties; import com.android.internal.location.ProviderRequest; @@ -218,6 +219,19 @@ public class LocationManagerService extends ILocationManager.Stub { mContext = context; mAppOps = (AppOpsManager)context.getSystemService(Context.APP_OPS_SERVICE); + // Let the package manager query which are the default location + // providers as they get certain permissions granted by default. + PackageManagerInternal packageManagerInternal = LocalServices.getService( + PackageManagerInternal.class); + packageManagerInternal.setLocationPackagesProvider( + new PackageManagerInternal.PackagesProvider() { + @Override + public String[] getPackages(int userId) { + return mContext.getResources().getStringArray( + com.android.internal.R.array.config_locationProviderPackageNames); + } + }); + if (D) Log.d(TAG, "Constructed"); // most startup is deferred until systemReady() diff --git a/services/core/java/com/android/server/pm/DefaultPermissionGrantPolicy.java b/services/core/java/com/android/server/pm/DefaultPermissionGrantPolicy.java new file mode 100644 index 0000000..fe3103b --- /dev/null +++ b/services/core/java/com/android/server/pm/DefaultPermissionGrantPolicy.java @@ -0,0 +1,521 @@ +/* + * Copyright (C) 2015 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.server.pm; + +import android.Manifest; +import android.content.Intent; +import android.content.pm.ApplicationInfo; +import android.content.pm.PackageManager; +import android.content.pm.PackageManagerInternal.PackagesProvider; +import android.content.pm.PackageParser; +import android.content.pm.ResolveInfo; +import android.net.Uri; +import android.os.Build; +import android.os.UserHandle; +import android.provider.MediaStore; +import android.util.ArraySet; +import android.util.Log; + +import java.io.File; +import java.util.ArrayList; +import java.util.List; +import java.util.Set; + +import static android.os.Process.FIRST_APPLICATION_UID; + +/** + * This class is the policy for granting runtime permissions to + * platform components and default handlers in the system such + * that the device is usable out-of-the-box. For example, the + * shell UID is a part of the system and the Phone app should + * have phone related permission by default. + */ +final class DefaultPermissionGrantPolicy { + private static final String TAG = "DefaultPermissionGrantPolicy"; + private static final boolean DEBUG = false; + + private static final String PACKAGE_MIME_TYPE = "application/vnd.android.package-archive"; + + private static final Set<String> PHONE_PERMISSIONS = new ArraySet<>(); + static { + PHONE_PERMISSIONS.add(Manifest.permission.READ_PHONE_STATE); + PHONE_PERMISSIONS.add(Manifest.permission.CALL_PHONE); + PHONE_PERMISSIONS.add( Manifest.permission.READ_CALL_LOG); + PHONE_PERMISSIONS.add(Manifest.permission.WRITE_CALL_LOG); + PHONE_PERMISSIONS.add(Manifest.permission.ADD_VOICEMAIL); + PHONE_PERMISSIONS.add(Manifest.permission.USE_SIP); + PHONE_PERMISSIONS.add(Manifest.permission.PROCESS_OUTGOING_CALLS); + } + + private static final Set<String> CONTACTS_PERMISSIONS = new ArraySet<>(); + static { + CONTACTS_PERMISSIONS.add(Manifest.permission.READ_CONTACTS); + CONTACTS_PERMISSIONS.add(Manifest.permission.WRITE_CONTACTS); + } + + private static final Set<String> LOCATION_PERMISSIONS = new ArraySet<>(); + static { + LOCATION_PERMISSIONS.add(Manifest.permission.ACCESS_FINE_LOCATION); + LOCATION_PERMISSIONS.add(Manifest.permission.ACCESS_COARSE_LOCATION); + } + + private static final Set<String> CALENDAR_PERMISSIONS = new ArraySet<>(); + static { + CALENDAR_PERMISSIONS.add(Manifest.permission.READ_CALENDAR); + CALENDAR_PERMISSIONS.add(Manifest.permission.WRITE_CALENDAR); + } + + private static final Set<String> SMS_PERMISSIONS = new ArraySet<>(); + static { + SMS_PERMISSIONS.add(Manifest.permission.SEND_SMS); + SMS_PERMISSIONS.add(Manifest.permission.RECEIVE_SMS); + SMS_PERMISSIONS.add(Manifest.permission.READ_SMS); + SMS_PERMISSIONS.add(Manifest.permission.RECEIVE_WAP_PUSH); + SMS_PERMISSIONS.add(Manifest.permission.RECEIVE_MMS); + SMS_PERMISSIONS.add(Manifest.permission.READ_CELL_BROADCASTS); + } + + private static final Set<String> MICROPHONE_PERMISSIONS = new ArraySet<>(); + static { + MICROPHONE_PERMISSIONS.add(Manifest.permission.RECORD_AUDIO); + } + + private static final Set<String> CAMERA_PERMISSIONS = new ArraySet<>(); + static { + CAMERA_PERMISSIONS.add(Manifest.permission.CAMERA); + } + + private static final Set<String> SENSORS_PERMISSIONS = new ArraySet<>(); + static { + SENSORS_PERMISSIONS.add(Manifest.permission.BODY_SENSORS); + } + + private static final Set<String> STORAGE_PERMISSIONS = new ArraySet<>(); + static { +// STORAGE_PERMISSIONS.add(Manifest.permission.READ_EXTERNAL_STORAGE); + STORAGE_PERMISSIONS.add(Manifest.permission.WRITE_EXTERNAL_STORAGE); + } + + private static final Set<String> SETTINGS_PERMISSIONS = new ArraySet<>(); + static { + SETTINGS_PERMISSIONS.add(Manifest.permission.WRITE_SETTINGS); + } + + private static final Set<String> INSTALLER_PERMISSIONS = new ArraySet<>(); + static { + INSTALLER_PERMISSIONS.add(Manifest.permission.GRANT_REVOKE_PERMISSIONS); + INSTALLER_PERMISSIONS.add(Manifest.permission.INTERACT_ACROSS_USERS_FULL); + INSTALLER_PERMISSIONS.add(Manifest.permission.CLEAR_APP_USER_DATA); + INSTALLER_PERMISSIONS.add(Manifest.permission.KILL_UID); + } + + private static final Set<String> VERIFIER_PERMISSIONS = new ArraySet<>(); + static { + INSTALLER_PERMISSIONS.add(Manifest.permission.GRANT_REVOKE_PERMISSIONS); + } + + private final PackageManagerService mService; + + private PackagesProvider mImePackagesProvider; + private PackagesProvider mLocationPackagesProvider; + private PackagesProvider mVoiceInteractionPackagesProvider; + + public DefaultPermissionGrantPolicy(PackageManagerService service) { + mService = service; + } + + public void setImePackagesProviderLPr(PackagesProvider provider) { + mImePackagesProvider = provider; + } + + public void setLocationPackagesProviderLPw(PackagesProvider provider) { + mLocationPackagesProvider = provider; + } + + public void setVoiceInteractionPackagesProviderLPw(PackagesProvider provider) { + mVoiceInteractionPackagesProvider = provider; + } + + public void grantDefaultPermissions(int userId) { + grantPermissionsToSysComponentsAndPrivApps(userId); + grantDefaultSystemHandlerPermissions(userId); + } + + private void grantPermissionsToSysComponentsAndPrivApps(int userId) { + Log.i(TAG, "Granting permissions to platform components"); + + synchronized (mService.mPackages) { + for (PackageParser.Package pkg : mService.mPackages.values()) { + if (!isSysComponentOrPersistentPrivApp(pkg) + || !doesPackageSupportRuntimePermissions(pkg)) { + continue; + } + final int permissionCount = pkg.requestedPermissions.size(); + for (int i = 0; i < permissionCount; i++) { + String permission = pkg.requestedPermissions.get(i); + BasePermission bp = mService.mSettings.mPermissions.get(permission); + if (bp != null && bp.isRuntime()) { + final int flags = mService.getPermissionFlags(permission, + pkg.packageName, userId); + if ((flags & PackageManager.FLAG_PERMISSION_SYSTEM_FIXED) == 0) { + mService.grantRuntimePermission(pkg.packageName, permission, userId); + mService.updatePermissionFlags(permission, pkg.packageName, + PackageManager.MASK_PERMISSION_FLAGS, + PackageManager.FLAG_PERMISSION_SYSTEM_FIXED, userId); + if (DEBUG) { + Log.i(TAG, "Granted " + permission + " to system component " + + pkg.packageName); + } + } + } + } + } + } + } + + private void grantDefaultSystemHandlerPermissions(int userId) { + Log.i(TAG, "Granting permissions to default platform handlers"); + + final PackagesProvider imePackagesProvider; + final PackagesProvider locationPackagesProvider; + final PackagesProvider voiceInteractionPackagesProvider; + + synchronized (mService.mPackages) { + imePackagesProvider = mImePackagesProvider; + locationPackagesProvider = mLocationPackagesProvider; + voiceInteractionPackagesProvider = mVoiceInteractionPackagesProvider; + } + + String[] imePackageNames = (imePackagesProvider != null) + ? imePackagesProvider.getPackages(userId) : null; + String[] voiceInteractPackageNames = (voiceInteractionPackagesProvider != null) + ? voiceInteractionPackagesProvider.getPackages(userId) : null; + String[] locationPackageNames = (locationPackagesProvider != null) + ? locationPackagesProvider.getPackages(userId) : null; + + synchronized (mService.mPackages) { + // Installers + Intent installerIntent = new Intent(Intent.ACTION_INSTALL_PACKAGE); + installerIntent.addCategory(Intent.CATEGORY_DEFAULT); + installerIntent.setDataAndType(Uri.fromFile(new File("foo.apk")), + PACKAGE_MIME_TYPE); + List<PackageParser.Package> installerPackages = + getPrivilegedHandlerActivityPackagesLPr(installerIntent, userId); + final int installerCount = installerPackages.size(); + for (int i = 0; i < installerCount; i++) { + PackageParser.Package installPackage = installerPackages.get(i); + grantInstallPermissionsLPw(installPackage, INSTALLER_PERMISSIONS, userId); + } + + // Verifiers + Intent verifierIntent = new Intent(Intent.ACTION_PACKAGE_NEEDS_VERIFICATION); + verifierIntent.setType(PACKAGE_MIME_TYPE); + List<PackageParser.Package> verifierPackages = + getPrivilegedHandlerReceiverPackagesLPr(verifierIntent, userId); + final int verifierCount = verifierPackages.size(); + for (int i = 0; i < verifierCount; i++) { + PackageParser.Package verifierPackage = verifierPackages.get(i); + grantInstallPermissionsLPw(verifierPackage, VERIFIER_PERMISSIONS, userId); + } + + // SetupWizard + Intent setupIntent = new Intent(Intent.ACTION_MAIN); + setupIntent.addCategory(Intent.CATEGORY_HOME); + PackageParser.Package setupPackage = getDefaultSystemHandlerActvityPackageLPr( + setupIntent, userId); + if (setupPackage != null + && doesPackageSupportRuntimePermissions(setupPackage)) { + grantRuntimePermissionsLPw(setupPackage, PHONE_PERMISSIONS, userId); + grantRuntimePermissionsLPw(setupPackage, CONTACTS_PERMISSIONS, userId); + grantRuntimePermissionsLPw(setupPackage, SETTINGS_PERMISSIONS, userId); + } + + // Phone + Intent dialerIntent = new Intent(Intent.ACTION_DIAL); + PackageParser.Package dialerPackage = getDefaultSystemHandlerActvityPackageLPr( + dialerIntent, userId); + 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 = getDefaultSystemHandlerActvityPackageLPr( + cameraIntent, userId); + if (cameraPackage != null + && doesPackageSupportRuntimePermissions(cameraPackage)) { + grantRuntimePermissionsLPw(cameraPackage, CAMERA_PERMISSIONS, userId); + grantRuntimePermissionsLPw(cameraPackage, MICROPHONE_PERMISSIONS, userId); + } + + // Messaging + Intent messagingIntent = new Intent(Intent.ACTION_MAIN); + messagingIntent.addCategory(Intent.CATEGORY_APP_MESSAGING); + PackageParser.Package messagingPackage = getDefaultSystemHandlerActvityPackageLPr( + messagingIntent, userId); + if (messagingPackage != null + && doesPackageSupportRuntimePermissions(messagingPackage)) { + grantRuntimePermissionsLPw(messagingPackage, PHONE_PERMISSIONS, userId); + grantRuntimePermissionsLPw(messagingPackage, CONTACTS_PERMISSIONS, userId); + grantRuntimePermissionsLPw(messagingPackage, SMS_PERMISSIONS, userId); + } + + // Calendar + Intent calendarIntent = new Intent(Intent.ACTION_MAIN); + calendarIntent.addCategory(Intent.CATEGORY_APP_CALENDAR); + PackageParser.Package calendarPackage = getDefaultSystemHandlerActvityPackageLPr( + calendarIntent, userId); + if (calendarPackage != null + && doesPackageSupportRuntimePermissions(calendarPackage)) { + grantRuntimePermissionsLPw(calendarPackage, CALENDAR_PERMISSIONS, userId); + grantRuntimePermissionsLPw(calendarPackage, CONTACTS_PERMISSIONS, userId); + } + + // Contacts + Intent contactsIntent = new Intent(Intent.ACTION_MAIN); + contactsIntent.addCategory(Intent.CATEGORY_APP_CONTACTS); + PackageParser.Package contactsPackage = getDefaultSystemHandlerActvityPackageLPr( + contactsIntent, userId); + if (contactsPackage != null + && doesPackageSupportRuntimePermissions(contactsPackage)) { + grantRuntimePermissionsLPw(contactsPackage, CONTACTS_PERMISSIONS, userId); + grantRuntimePermissionsLPw(contactsPackage, PHONE_PERMISSIONS, userId); + } + + // Maps + Intent mapsIntent = new Intent(Intent.ACTION_MAIN); + mapsIntent.addCategory(Intent.CATEGORY_APP_MAPS); + PackageParser.Package mapsPackage = getDefaultSystemHandlerActvityPackageLPr( + mapsIntent, userId); + if (mapsPackage != null + && doesPackageSupportRuntimePermissions(mapsPackage)) { + grantRuntimePermissionsLPw(mapsPackage, LOCATION_PERMISSIONS, userId); + } + + // Email + Intent emailIntent = new Intent(Intent.ACTION_MAIN); + emailIntent.addCategory(Intent.CATEGORY_APP_EMAIL); + PackageParser.Package emailPackage = getDefaultSystemHandlerActvityPackageLPr( + emailIntent, userId); + if (emailPackage != null + && doesPackageSupportRuntimePermissions(emailPackage)) { + grantRuntimePermissionsLPw(emailPackage, CONTACTS_PERMISSIONS, userId); + } + + // Browser + Intent browserIntent = new Intent(Intent.ACTION_MAIN); + browserIntent.addCategory(Intent.CATEGORY_APP_BROWSER); + PackageParser.Package browserPackage = getDefaultSystemHandlerActvityPackageLPr( + browserIntent, userId); + if (browserPackage != null + && doesPackageSupportRuntimePermissions(browserPackage)) { + grantRuntimePermissionsLPw(browserPackage, LOCATION_PERMISSIONS, userId); + } + + // IME + if (imePackageNames != null) { + for (String imePackageName : imePackageNames) { + PackageParser.Package imePackage = getSystemPackageLPr(imePackageName); + if (imePackage != null + && doesPackageSupportRuntimePermissions(imePackage)) { + grantRuntimePermissionsLPw(imePackage, CONTACTS_PERMISSIONS, userId); + } + } + } + + // Voice interaction + if (voiceInteractPackageNames != null) { + for (String voiceInteractPackageName : voiceInteractPackageNames) { + PackageParser.Package voiceInteractPackage = getSystemPackageLPr( + voiceInteractPackageName); + if (voiceInteractPackage != null + && doesPackageSupportRuntimePermissions(voiceInteractPackage)) { + grantRuntimePermissionsLPw(voiceInteractPackage, + CONTACTS_PERMISSIONS, userId); + grantRuntimePermissionsLPw(voiceInteractPackage, + CALENDAR_PERMISSIONS, userId); + grantRuntimePermissionsLPw(voiceInteractPackage, + MICROPHONE_PERMISSIONS, userId); + grantRuntimePermissionsLPw(voiceInteractPackage, + PHONE_PERMISSIONS, userId); + grantRuntimePermissionsLPw(voiceInteractPackage, + SMS_PERMISSIONS, userId); + grantRuntimePermissionsLPw(voiceInteractPackage, + LOCATION_PERMISSIONS, userId); + } + } + } + + // Location + if (locationPackageNames != null) { + for (String packageName : locationPackageNames) { + PackageParser.Package locationPackage = getSystemPackageLPr(packageName); + if (locationPackage != null + && doesPackageSupportRuntimePermissions(locationPackage)) { + grantRuntimePermissionsLPw(locationPackage, CONTACTS_PERMISSIONS, userId); + grantRuntimePermissionsLPw(locationPackage, CALENDAR_PERMISSIONS, userId); + grantRuntimePermissionsLPw(locationPackage, MICROPHONE_PERMISSIONS, userId); + grantRuntimePermissionsLPw(locationPackage, PHONE_PERMISSIONS, userId); + grantRuntimePermissionsLPw(locationPackage, SMS_PERMISSIONS, userId); + grantRuntimePermissionsLPw(locationPackage, LOCATION_PERMISSIONS, userId); + grantRuntimePermissionsLPw(locationPackage, CAMERA_PERMISSIONS, userId); + grantRuntimePermissionsLPw(locationPackage, SENSORS_PERMISSIONS, userId); + grantRuntimePermissionsLPw(locationPackage, STORAGE_PERMISSIONS, userId); + } + } + } + } + } + + private List<PackageParser.Package> getPrivilegedHandlerReceiverPackagesLPr( + Intent intent, int userId) { + List<ResolveInfo> handlers = mService.queryIntentReceivers( + intent, intent.resolveTypeIfNeeded(mService.mContext.getContentResolver()), + 0, userId); + return getPrivilegedPackages(handlers); + } + + private List<PackageParser.Package> getPrivilegedHandlerActivityPackagesLPr( + Intent intent, int userId) { + List<ResolveInfo> handlers = mService.queryIntentActivities( + intent, intent.resolveTypeIfNeeded(mService.mContext.getContentResolver()), + 0, userId); + return getPrivilegedPackages(handlers); + } + + private List<PackageParser.Package> getPrivilegedPackages(List<ResolveInfo> resolveInfos) { + List<PackageParser.Package> handlerPackages = new ArrayList<>(); + final int handlerCount = resolveInfos.size(); + for (int i = 0; i < handlerCount; i++) { + ResolveInfo handler = resolveInfos.get(i); + PackageParser.Package handlerPackage = getPrivilegedPackageLPr( + handler.activityInfo.packageName); + if (handlerPackage != null) { + handlerPackages.add(handlerPackage); + } + } + return handlerPackages; + } + + private PackageParser.Package getDefaultSystemHandlerActvityPackageLPr( + Intent intent, int userId) { + List<ResolveInfo> handlers = mService.queryIntentActivities(intent, null, 0, userId); + final int handlerCount = handlers.size(); + for (int i = 0; i < handlerCount; i++) { + ResolveInfo handler = handlers.get(i); + // TODO: This is a temporary hack to figure out the setup app. + PackageParser.Package handlerPackage = getSystemPackageLPr( + handler.activityInfo.packageName); + if (handlerPackage != null) { + return handlerPackage; + } + } + return null; + } + + private PackageParser.Package getSystemPackageLPr(String packageName) { + PackageParser.Package pkg = mService.mPackages.get(packageName); + if (pkg != null && pkg.isSystemApp()) { + return !isSysComponentOrPersistentPrivApp(pkg) ? pkg : null; + } + return null; + } + + private PackageParser.Package getPrivilegedPackageLPr(String packageName) { + PackageParser.Package pkg = mService.mPackages.get(packageName); + if (pkg != null && pkg.applicationInfo.isPrivilegedApp()) { + return !isSysComponentOrPersistentPrivApp(pkg) ? pkg : null; + } + return null; + } + + private void grantRuntimePermissionsLPw(PackageParser.Package pkg, Set<String> permissions, + int userId) { + List<String> requestedPermissions = pkg.requestedPermissions; + + if (pkg.isUpdatedSystemApp()) { + PackageSetting sysPs = mService.mSettings.getDisabledSystemPkgLPr(pkg.packageName); + if (sysPs != null) { + requestedPermissions = sysPs.pkg.requestedPermissions; + } + } + + final int permissionCount = requestedPermissions.size(); + for (int i = 0; i < permissionCount; i++) { + String permission = requestedPermissions.get(i); + if (permissions.contains(permission)) { + final int flags = mService.getPermissionFlags(permission, pkg.packageName, userId); + + // If any flags are set to the permission, then it is either set in + // its current state by the system or device/profile owner or the user. + // In all these cases we do not want to clobber the current state. + if (flags == 0) { + mService.grantRuntimePermission(pkg.packageName, permission, userId); + if (DEBUG) { + Log.i(TAG, "Granted " + permission + " to default handler " + + pkg.packageName); + } + } + } + } + } + + private void grantInstallPermissionsLPw(PackageParser.Package pkg, Set<String> permissions, + int userId) { + List<String> requestedPermissions = pkg.requestedPermissions; + + if (pkg.isUpdatedSystemApp()) { + PackageSetting sysPs = mService.mSettings.getDisabledSystemPkgLPr(pkg.packageName); + if (sysPs != null) { + requestedPermissions = sysPs.pkg.requestedPermissions; + } + } + + final int permissionCount = requestedPermissions.size(); + for (int i = 0; i < permissionCount; i++) { + String permission = requestedPermissions.get(i); + if (permissions.contains(permission)) { + final int flags = mService.getPermissionFlags(permission, pkg.packageName, userId); + + // If any flags are set to the permission, then it is either set in + // its current state by the system or device/profile owner or the user. + // In all these cases we do not want to clobber the current state. + if (flags == 0) { + mService.grantInstallPermissionLPw(permission, pkg); + if (DEBUG) { + Log.i(TAG, "Granted install " + permission + " to " + pkg.packageName); + } + } + } + } + } + + private static boolean isSysComponentOrPersistentPrivApp(PackageParser.Package pkg) { + return UserHandle.getAppId(pkg.applicationInfo.uid) < FIRST_APPLICATION_UID + || ((pkg.applicationInfo.privateFlags + & ApplicationInfo.PRIVATE_FLAG_PRIVILEGED) != 0 + && (pkg.applicationInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0); + } + + private static boolean doesPackageSupportRuntimePermissions(PackageParser.Package pkg) { + return pkg.applicationInfo.targetSdkVersion > Build.VERSION_CODES.LOLLIPOP_MR1; + } +} diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java index 5b7dd70..91aec60 100644 --- a/services/core/java/com/android/server/pm/PackageManagerService.java +++ b/services/core/java/com/android/server/pm/PackageManagerService.java @@ -55,7 +55,6 @@ import static android.content.pm.PackageManager.MOVE_FAILED_INTERNAL_ERROR; import static android.content.pm.PackageManager.MOVE_FAILED_OPERATION_PENDING; import static android.content.pm.PackageManager.MOVE_FAILED_SYSTEM_PACKAGE; import static android.content.pm.PackageParser.isApkFile; -import static android.os.Process.FIRST_APPLICATION_UID; import static android.os.Process.PACKAGE_INFO_GID; import static android.os.Process.SYSTEM_UID; import static android.system.OsConstants.O_CREAT; @@ -111,6 +110,7 @@ import android.content.pm.PackageInfoLite; import android.content.pm.PackageInstaller; import android.content.pm.PackageManager; import android.content.pm.PackageManager.LegacyPackageDeleteObserver; +import android.content.pm.PackageManagerInternal; import android.content.pm.PackageParser; import android.content.pm.PackageParser.ActivityIntentInfo; import android.content.pm.PackageParser.PackageLite; @@ -281,6 +281,8 @@ public class PackageManagerService extends IPackageManager.Stub { private static final boolean DEBUG_DEXOPT = false; private static final boolean DEBUG_ABI_SELECTION = false; + static final boolean CLEAR_RUNTIME_PERMISSIONS_ON_UPGRADE = Build.IS_DEBUGGABLE; + private static final int RADIO_UID = Process.PHONE_UID; private static final int LOG_UID = Process.LOG_UID; private static final int NFC_UID = Process.NFC_UID; @@ -551,6 +553,9 @@ public class PackageManagerService extends IPackageManager.Stub { final SparseArray<IntentFilterVerificationState> mIntentFilterVerificationStates = new SparseArray<IntentFilterVerificationState>(); + final DefaultPermissionGrantPolicy mDefaultPermissionPolicy = + new DefaultPermissionGrantPolicy(this); + private interface IntentFilterVerifier<T extends IntentFilter> { boolean addOneIntentFilterVerification(int verifierId, int userId, int verificationId, T filter, String packageName); @@ -2194,6 +2199,9 @@ public class PackageManagerService extends IPackageManager.Stub { // are all flushed. Not really needed, but keeps things nice and // tidy. Runtime.getRuntime().gc(); + + // Expose private service for system components to use. + LocalServices.addService(PackageManagerInternal.class, new PackageManagerInternalImpl()); } @Override @@ -3150,7 +3158,7 @@ public class PackageManagerService extends IPackageManager.Stub { } @Override - public void grantRuntimePermission(String packageName, String name, int userId) { + public void grantRuntimePermission(String packageName, String name, final int userId) { if (!sUserManager.exists(userId)) { Log.e(TAG, "No such user:" + userId); return; @@ -3163,7 +3171,6 @@ public class PackageManagerService extends IPackageManager.Stub { enforceCrossUserPermission(Binder.getCallingUid(), userId, true, false, "grantRuntimePermission"); - boolean gidsChanged = false; final SettingBase sb; synchronized (mPackages) { @@ -3199,7 +3206,12 @@ public class PackageManagerService extends IPackageManager.Stub { } case PermissionsState.PERMISSION_OPERATION_SUCCESS_GIDS_CHANGED: { - gidsChanged = true; + mHandler.post(new Runnable() { + @Override + public void run() { + killSettingPackagesForUser(sb, userId, KILL_APP_REASON_GIDS_CHANGED); + } + }); } break; } @@ -3208,10 +3220,6 @@ public class PackageManagerService extends IPackageManager.Stub { // Not critical if that is lost - app has to request again. mSettings.writeRuntimePermissionsForUserLPr(userId, false); } - - if (gidsChanged) { - killSettingPackagesForUser(sb, userId, KILL_APP_REASON_GIDS_CHANGED); - } } @Override @@ -3318,15 +3326,14 @@ public class PackageManagerService extends IPackageManager.Stub { enforceCrossUserPermission(Binder.getCallingUid(), userId, true, false, "updatePermissionFlags"); - // Only the system can change policy flags. + // Only the system can change policy and system fixed flags. if (getCallingUid() != Process.SYSTEM_UID) { flagMask &= ~PackageManager.FLAG_PERMISSION_POLICY_FIXED; flagValues &= ~PackageManager.FLAG_PERMISSION_POLICY_FIXED; - } - // Only the package manager can change system flags. - flagMask &= ~PackageManager.FLAG_PERMISSION_SYSTEM_FIXED; - flagValues &= ~PackageManager.FLAG_PERMISSION_SYSTEM_FIXED; + flagMask &= ~PackageManager.FLAG_PERMISSION_SYSTEM_FIXED; + flagValues &= ~PackageManager.FLAG_PERMISSION_SYSTEM_FIXED; + } synchronized (mPackages) { final PackageParser.Package pkg = mPackages.get(packageName); @@ -3404,6 +3411,21 @@ public class PackageManagerService extends IPackageManager.Stub { return (flags & PackageManager.FLAG_PERMISSION_USER_SET) != 0; } + void grantInstallPermissionLPw(String permission, PackageParser.Package pkg) { + BasePermission bp = mSettings.mPermissions.get(permission); + if (bp == null) { + throw new SecurityException("Missing " + permission + " permission"); + } + + SettingBase sb = (SettingBase) pkg.mExtras; + PermissionsState permissionsState = sb.getPermissionsState(); + + if (permissionsState.grantInstallPermission(bp) != + PermissionsState.PERMISSION_OPERATION_FAILURE) { + scheduleWriteSettingsLocked(); + } + } + @Override public void addOnPermissionsChangeListener(IOnPermissionsChangeListener listener) { mContext.enforceCallingOrSelfPermission( @@ -7748,7 +7770,6 @@ public class PackageManagerService extends IPackageManager.Stub { final int[] currentUserIds = UserManagerService.getInstance().getUserIds(); - int[] upgradeUserIds = EMPTY_INT_ARRAY; int[] changedRuntimePermissionUserIds = EMPTY_INT_ARRAY; boolean changedInstallPermission = false; @@ -7805,32 +7826,11 @@ public class PackageManagerService extends IPackageManager.Stub { if (pkg.applicationInfo.targetSdkVersion <= Build.VERSION_CODES.LOLLIPOP_MR1) { // For legacy apps dangerous permissions are install time ones. grant = GRANT_INSTALL_LEGACY; - } else if (ps.isSystem()) { - final int[] updatedUserIds = ps.getPermissionsUpdatedForUserIds(); - if (origPermissions.hasInstallPermission(bp.name)) { - // If a system app had an install permission, then the app was - // upgraded and we grant the permissions as runtime to all users. - grant = GRANT_UPGRADE; - upgradeUserIds = currentUserIds; - } else if (!Arrays.equals(updatedUserIds, currentUserIds)) { - // If users changed since the last permissions update for a - // system app, we grant the permission as runtime to the new users. - grant = GRANT_UPGRADE; - upgradeUserIds = currentUserIds; - for (int userId : updatedUserIds) { - upgradeUserIds = ArrayUtils.removeInt(upgradeUserIds, userId); - } - } else { - // Otherwise, we grant the permission as runtime if the app - // already had it, i.e. we preserve runtime permissions. - grant = GRANT_RUNTIME; - } } else if (origPermissions.hasInstallPermission(bp.name)) { // For legacy apps that became modern, install becomes runtime. grant = GRANT_UPGRADE; - upgradeUserIds = currentUserIds; - } else if (replace) { - // For upgraded modern apps keep runtime permissions unchanged. + } else { + // For modern apps keep runtime permissions unchanged. grant = GRANT_RUNTIME; } } break; @@ -7865,7 +7865,7 @@ public class PackageManagerService extends IPackageManager.Stub { switch (grant) { case GRANT_INSTALL: { // Revoke this as runtime permission to handle the case of - // a runtime permssion being downgraded to an install one. + // a runtime permission being downgraded to an install one. for (int userId : UserManagerService.getInstance().getUserIds()) { if (origPermissions.getRuntimePermissionState( bp.name, userId) != null) { @@ -7896,26 +7896,20 @@ public class PackageManagerService extends IPackageManager.Stub { case GRANT_RUNTIME: { // Grant previously granted runtime permissions. for (int userId : UserManagerService.getInstance().getUserIds()) { + PermissionState permissionState = origPermissions + .getRuntimePermissionState(bp.name, userId); + final int flags = permissionState != null + ? permissionState.getFlags() : 0; if (origPermissions.hasRuntimePermission(bp.name, userId)) { - PermissionState permissionState = origPermissions - .getRuntimePermissionState(bp.name, userId); - final int flags = permissionState.getFlags(); if (permissionsState.grantRuntimePermission(bp, userId) == PermissionsState.PERMISSION_OPERATION_FAILURE) { // If we cannot put the permission as it was, we have to write. changedRuntimePermissionUserIds = ArrayUtils.appendInt( changedRuntimePermissionUserIds, userId); - } else { - // System components not only get the permissions but - // they are also fixed, so nothing can change that. - final int newFlags = !isSystemComponentOrPersistentPrivApp(pkg) - ? flags - : flags | PackageManager.FLAG_PERMISSION_SYSTEM_FIXED; - // Propagate the permission flags. - permissionsState.updatePermissionFlags(bp, userId, - newFlags, newFlags); } } + // Propagate the permission flags. + permissionsState.updatePermissionFlags(bp, userId, flags, flags); } } break; @@ -7925,25 +7919,23 @@ public class PackageManagerService extends IPackageManager.Stub { .getInstallPermissionState(bp.name); final int flags = permissionState != null ? permissionState.getFlags() : 0; - origPermissions.revokeInstallPermission(bp); - // We will be transferring the permission flags, so clear them. - origPermissions.updatePermissionFlags(bp, UserHandle.USER_ALL, - PackageManager.MASK_PERMISSION_FLAGS, 0); + if (origPermissions.revokeInstallPermission(bp) + != PermissionsState.PERMISSION_OPERATION_FAILURE) { + // We will be transferring the permission flags, so clear them. + origPermissions.updatePermissionFlags(bp, UserHandle.USER_ALL, + PackageManager.MASK_PERMISSION_FLAGS, 0); + changedInstallPermission = true; + } // If the permission is not to be promoted to runtime we ignore it and // also its other flags as they are not applicable to install permissions. if ((flags & PackageManager.FLAG_PERMISSION_REVOKE_ON_UPGRADE) == 0) { - for (int userId : upgradeUserIds) { + for (int userId : currentUserIds) { if (permissionsState.grantRuntimePermission(bp, userId) != PermissionsState.PERMISSION_OPERATION_FAILURE) { - // System components not only get the permissions but - // they are also fixed so nothing can change that. - final int newFlags = !isSystemComponentOrPersistentPrivApp(pkg) - ? flags - : flags | PackageManager.FLAG_PERMISSION_SYSTEM_FIXED; // Transfer the permission flags. permissionsState.updatePermissionFlags(bp, userId, - newFlags, newFlags); + flags, flags); // If we granted the permission, we have to write. changedRuntimePermissionUserIds = ArrayUtils.appendInt( changedRuntimePermissionUserIds, userId); @@ -7995,8 +7987,6 @@ public class PackageManagerService extends IPackageManager.Stub { ps.installPermissionsFixed = true; } - ps.setPermissionsUpdatedForUserIds(currentUserIds); - // Persist the runtime permissions state for users with changes. for (int userId : changedRuntimePermissionUserIds) { mSettings.writeRuntimePermissionsForUserLPr(userId, true); @@ -11875,13 +11865,6 @@ public class PackageManagerService extends IPackageManager.Stub { } } - private boolean isSystemComponentOrPersistentPrivApp(PackageParser.Package pkg) { - return UserHandle.getAppId(pkg.applicationInfo.uid) < FIRST_APPLICATION_UID - || ((pkg.applicationInfo.privateFlags - & ApplicationInfo.PRIVATE_FLAG_PRIVILEGED) != 0 - && (pkg.applicationInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0); - } - private static boolean isMultiArch(PackageSetting ps) { return (ps.pkgFlags & ApplicationInfo.FLAG_MULTIARCH) != 0; } @@ -13674,6 +13657,14 @@ public class PackageManagerService extends IPackageManager.Stub { } sUserManager.systemReady(); + // If we upgraded grant all default permissions before kicking off. + if (isFirstBoot()) { + updatePermissionsLPw(null, null, UPDATE_PERMISSIONS_ALL); + for (int userId : UserManagerService.getInstance().getUserIds()) { + mDefaultPermissionPolicy.grantDefaultPermissions(userId); + } + } + // Kick off any messages waiting for system ready if (mPostSystemReadyMessages != null) { for (Message msg : mPostSystemReadyMessages) { @@ -15061,9 +15052,16 @@ public class PackageManagerService extends IPackageManager.Stub { } } - void newUserCreatedLILPw(int userHandle) { - // Adding a user requires updating runtime permissions for system apps. - updatePermissionsLPw(null, null, UPDATE_PERMISSIONS_ALL); + void newUserCreatedLILPw(final int userHandle) { + // We cannot grant the default permissions with a lock held as + // we query providers from other components for default handlers + // such as enabled IMEs, etc. + mHandler.post(new Runnable() { + @Override + public void run() { + mDefaultPermissionPolicy.grantDefaultPermissions(userHandle); + } + }); } @Override @@ -15415,4 +15413,27 @@ public class PackageManagerService extends IPackageManager.Stub { } } } + + private class PackageManagerInternalImpl extends PackageManagerInternal { + @Override + public void setLocationPackagesProvider(PackagesProvider provider) { + synchronized (mPackages) { + mDefaultPermissionPolicy.setLocationPackagesProviderLPw(provider); + } + } + + @Override + public void setImePackagesProvider(PackagesProvider provider) { + synchronized (mPackages) { + mDefaultPermissionPolicy.setImePackagesProviderLPr(provider); + } + } + + @Override + public void setVoiceInteractionPackagesProvider(PackagesProvider provider) { + synchronized (mPackages) { + mDefaultPermissionPolicy.setVoiceInteractionPackagesProviderLPw(provider); + } + } + } } diff --git a/services/core/java/com/android/server/pm/PackageSettingBase.java b/services/core/java/com/android/server/pm/PackageSettingBase.java index f62c00c..6f46f69 100644 --- a/services/core/java/com/android/server/pm/PackageSettingBase.java +++ b/services/core/java/com/android/server/pm/PackageSettingBase.java @@ -24,7 +24,6 @@ import android.content.pm.IntentFilterVerificationInfo; import android.content.pm.PackageManager; import android.content.pm.PackageUserState; import android.os.storage.VolumeInfo; -import android.text.TextUtils; import android.util.ArraySet; import android.util.SparseArray; @@ -223,7 +222,6 @@ abstract class PackageSettingBase extends SettingBase { * Make a shallow copy of this package settings. */ public void copyFrom(PackageSettingBase base) { - setPermissionsUpdatedForUserIds(base.getPermissionsUpdatedForUserIds()); mPermissionsState.copyFrom(base.mPermissionsState); primaryCpuAbiString = base.primaryCpuAbiString; secondaryCpuAbiString = base.secondaryCpuAbiString; diff --git a/services/core/java/com/android/server/pm/SettingBase.java b/services/core/java/com/android/server/pm/SettingBase.java index c35258a..5cf92a9 100644 --- a/services/core/java/com/android/server/pm/SettingBase.java +++ b/services/core/java/com/android/server/pm/SettingBase.java @@ -18,16 +18,11 @@ package com.android.server.pm; import android.content.pm.ApplicationInfo; -import java.util.Arrays; - abstract class SettingBase { - private static final int[] USERS_NONE = new int[0]; - int pkgFlags; int pkgPrivateFlags; protected final PermissionsState mPermissionsState; - private int[] mPermissionsUpdatedForUserIds = USERS_NONE; SettingBase(int pkgFlags, int pkgPrivateFlags) { setFlags(pkgFlags); @@ -39,29 +34,12 @@ abstract class SettingBase { pkgFlags = base.pkgFlags; pkgPrivateFlags = base.pkgPrivateFlags; mPermissionsState = new PermissionsState(base.mPermissionsState); - setPermissionsUpdatedForUserIds(base.mPermissionsUpdatedForUserIds); } public PermissionsState getPermissionsState() { return mPermissionsState; } - public int[] getPermissionsUpdatedForUserIds() { - return mPermissionsUpdatedForUserIds; - } - - public void setPermissionsUpdatedForUserIds(int[] userIds) { - if (Arrays.equals(mPermissionsUpdatedForUserIds, userIds)) { - return; - } - - if (userIds == USERS_NONE) { - mPermissionsUpdatedForUserIds = userIds; - } else { - mPermissionsUpdatedForUserIds = Arrays.copyOf(userIds, userIds.length); - } - } - void setFlags(int pkgFlags) { this.pkgFlags = pkgFlags & (ApplicationInfo.FLAG_SYSTEM diff --git a/services/core/java/com/android/server/pm/Settings.java b/services/core/java/com/android/server/pm/Settings.java index cd50946..c43bd60 100644 --- a/services/core/java/com/android/server/pm/Settings.java +++ b/services/core/java/com/android/server/pm/Settings.java @@ -1139,17 +1139,6 @@ final class Settings { return new File(userDir, RUNTIME_PERMISSIONS_FILE_NAME); } - boolean isFirstRuntimePermissionsBoot() { - return !getUserRuntimePermissionsFile(UserHandle.USER_OWNER).exists(); - } - - void deleteRuntimePermissionsFiles() { - for (int userId : UserManagerService.getInstance().getUserIds()) { - File file = getUserRuntimePermissionsFile(userId); - file.delete(); - } - } - private File getUserPackagesStateBackupFile(int userId) { return new File(Environment.getUserSystemDirectory(userId), "package-restrictions-backup.xml"); @@ -2466,6 +2455,22 @@ final class Settings { } catch (NumberFormatException e) { } mFingerprint = parser.getAttributeValue(null, "fingerprint"); + + // If the build is setup to drop runtime permissions + // on update drop the files before loading them. + if (PackageManagerService.CLEAR_RUNTIME_PERMISSIONS_ON_UPGRADE) { + if (!Build.FINGERPRINT.equals(mFingerprint)) { + if (users == null) { + mRuntimePermissionsPersistence.deleteUserRuntimePermissionsFile( + UserHandle.USER_OWNER); + } else { + for (UserInfo user : users) { + mRuntimePermissionsPersistence.deleteUserRuntimePermissionsFile( + user.id); + } + } + } + } } else if (tagName.equals("database-version")) { mInternalDatabaseVersion = mExternalDatabaseVersion = 0; try { @@ -2554,15 +2559,21 @@ final class Settings { } else { if (users == null) { readPackageRestrictionsLPr(0); - mRuntimePermissionsPersistence.readStateForUserSyncLPr(UserHandle.USER_OWNER); } else { for (UserInfo user : users) { readPackageRestrictionsLPr(user.id); - mRuntimePermissionsPersistence.readStateForUserSyncLPr(user.id); } } } + if (users == null) { + mRuntimePermissionsPersistence.readStateForUserSyncLPr(UserHandle.USER_OWNER); + } else { + for (UserInfo user : users) { + mRuntimePermissionsPersistence.readStateForUserSyncLPr(user.id); + } + } + /* * Make sure all the updated system packages have their shared users * associated with them. @@ -3056,18 +3067,6 @@ final class Settings { } } - // We keep track for which users we granted permissions to be able - // to grant runtime permissions to system apps for newly appeared - // users or newly appeared system apps. If we supported runtime - // permissions during the previous boot, then we already granted - // permissions for all device users. In such a case we set the users - // for which we granted permissions to avoid clobbering of runtime - // permissions we granted to system apps but the user revoked later. - if (!isFirstRuntimePermissionsBoot()) { - final int[] userIds = UserManagerService.getInstance().getUserIds(); - ps.setPermissionsUpdatedForUserIds(userIds); - } - mDisabledSysPackages.put(name, ps); } @@ -3364,18 +3363,6 @@ final class Settings { XmlUtils.skipCurrentTag(parser); } } - - // We keep track for which users we granted permissions to be able - // to grant runtime permissions to system apps for newly appeared - // users or newly appeared system apps. If we supported runtime - // permissions during the previous boot, then we already granted - // permissions for all device users. In such a case we set the users - // for which we granted permissions to avoid clobbering of runtime - // permissions we granted to system apps but the user revoked later. - if (!isFirstRuntimePermissionsBoot()) { - final int[] userIds = UserManagerService.getInstance().getUserIds(); - packageSetting.setPermissionsUpdatedForUserIds(userIds); - } } else { XmlUtils.skipCurrentTag(parser); } @@ -3493,18 +3480,6 @@ final class Settings { XmlUtils.skipCurrentTag(parser); } } - - // We keep track for which users we granted permissions to be able - // to grant runtime permissions to system apps for newly appeared - // users or newly appeared system apps. If we supported runtime - // permissions during the previous boot, then we already granted - // permissions for all device users. In such a case we set the users - // for which we granted permissions to avoid clobbering of runtime - // permissions we granted to system apps but the user revoked later. - if (!isFirstRuntimePermissionsBoot()) { - final int[] userIds = UserManagerService.getInstance().getUserIds(); - su.setPermissionsUpdatedForUserIds(userIds); - } } else { XmlUtils.skipCurrentTag(parser); } @@ -4397,6 +4372,10 @@ final class Settings { } } + public void deleteUserRuntimePermissionsFile(int userId) { + getUserRuntimePermissionsFile(userId).delete(); + } + public void readStateForUserSyncLPr(int userId) { File permissionsFile = getUserRuntimePermissionsFile(userId); if (!permissionsFile.exists()) { @@ -4489,22 +4468,12 @@ final class Settings { ? Integer.parseInt(flagsStr, 16) : 0; if (granted) { - if (permissionsState.grantRuntimePermission(bp, userId) == - PermissionsState.PERMISSION_OPERATION_FAILURE) { - Slog.w(PackageManagerService.TAG, "Duplicate permission:" + name); - } else { - permissionsState.updatePermissionFlags(bp, userId, + permissionsState.grantRuntimePermission(bp, userId); + permissionsState.updatePermissionFlags(bp, userId, PackageManager.MASK_PERMISSION_FLAGS, flags); - - } } else { - if (permissionsState.revokeRuntimePermission(bp, userId) == - PermissionsState.PERMISSION_OPERATION_FAILURE) { - Slog.w(PackageManagerService.TAG, "Duplicate permission:" + name); - } else { - permissionsState.updatePermissionFlags(bp, userId, - PackageManager.MASK_PERMISSION_FLAGS, flags); - } + permissionsState.updatePermissionFlags(bp, userId, + PackageManager.MASK_PERMISSION_FLAGS, flags); } } break; diff --git a/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerService.java b/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerService.java index fafe44a..b68abab 100644 --- a/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerService.java +++ b/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerService.java @@ -26,6 +26,7 @@ import android.content.Intent; import android.content.pm.ApplicationInfo; import android.content.pm.IPackageManager; import android.content.pm.PackageManager; +import android.content.pm.PackageManagerInternal; import android.content.pm.ResolveInfo; import android.content.pm.ServiceInfo; import android.content.res.Resources; @@ -57,6 +58,7 @@ import com.android.internal.app.IVoiceInteractionSessionShowCallback; import com.android.internal.app.IVoiceInteractor; import com.android.internal.content.PackageMonitor; import com.android.internal.os.BackgroundThread; +import com.android.server.LocalServices; import com.android.server.SystemService; import com.android.server.UiThread; @@ -83,6 +85,21 @@ public class VoiceInteractionManagerService extends SystemService { mDbHelper = new DatabaseHelper(context); mSoundTriggerHelper = new SoundTriggerHelper(context); mServiceStub = new VoiceInteractionManagerServiceStub(); + + PackageManagerInternal packageManagerInternal = LocalServices.getService( + PackageManagerInternal.class); + packageManagerInternal.setVoiceInteractionPackagesProvider( + new PackageManagerInternal.PackagesProvider() { + @Override + public String[] getPackages(int userId) { + mServiceStub.initForUser(userId); + ComponentName interactor = mServiceStub.getCurInteractor(userId); + if (interactor != null) { + return new String[] {interactor.getPackageName()}; + } + return null; + } + }); } @Override |