diff options
author | Jeff Davidson <jpd@google.com> | 2015-06-22 16:54:34 -0700 |
---|---|---|
committer | Jeff Davidson <jpd@google.com> | 2015-06-23 09:55:23 -0700 |
commit | 2a880312086147577e1e814bda6985fa97fb343b (patch) | |
tree | 58cbe4c66daf8ec1da048e9af62043ded63fd274 | |
parent | 0b50e56c070878211d9003e072128716bee445ba (diff) | |
download | frameworks_base-2a880312086147577e1e814bda6985fa97fb343b.zip frameworks_base-2a880312086147577e1e814bda6985fa97fb343b.tar.gz frameworks_base-2a880312086147577e1e814bda6985fa97fb343b.tar.bz2 |
Default permissions for carrier apps.
Grant permissions in the PHONE and LOCATION buckets to default carrier
apps as defined by the telephony stack. Provide a system API to grant
default permissions for carrier apps, as the set of apps may change
when a new SIM is inserted.
Since the phone process is separate from the system process, we need
to allow for binder calls to these APIs.
Also fix a log tag that is too long (android.util.Log drops messages
silently if the tag is > 23 characters).
Bug: 21696731
Change-Id: I98ca0c49c69f621f835ba57c1fd0505f2cec0d0d
-rw-r--r-- | Android.mk | 1 | ||||
-rw-r--r-- | core/java/android/content/pm/IPackageManager.aidl | 20 | ||||
-rw-r--r-- | core/java/android/content/pm/IPackagesProvider.aidl | 22 | ||||
-rwxr-xr-x | core/res/res/values/config.xml | 4 | ||||
-rw-r--r-- | services/core/java/com/android/server/pm/DefaultPermissionGrantPolicy.java | 23 | ||||
-rw-r--r-- | services/core/java/com/android/server/pm/PackageManagerService.java | 98 |
6 files changed, 135 insertions, 33 deletions
@@ -142,6 +142,7 @@ LOCAL_SRC_FILES += \ core/java/android/content/pm/IPackageManager.aidl \ core/java/android/content/pm/IPackageMoveObserver.aidl \ core/java/android/content/pm/IPackageStatsObserver.aidl \ + core/java/android/content/pm/IPackagesProvider.aidl \ core/java/android/content/pm/IOnPermissionsChangeListener.aidl \ core/java/android/database/IContentObserver.aidl \ core/java/android/hardware/ICameraService.aidl \ diff --git a/core/java/android/content/pm/IPackageManager.aidl b/core/java/android/content/pm/IPackageManager.aidl index 0c07bc3..dbbfce8 100644 --- a/core/java/android/content/pm/IPackageManager.aidl +++ b/core/java/android/content/pm/IPackageManager.aidl @@ -31,6 +31,7 @@ import android.content.pm.IPackageDeleteObserver2; import android.content.pm.IPackageDataObserver; import android.content.pm.IPackageMoveObserver; import android.content.pm.IPackageStatsObserver; +import android.content.pm.IPackagesProvider; import android.content.pm.IOnPermissionsChangeListener; import android.content.pm.IntentFilterVerificationInfo; import android.content.pm.InstrumentationInfo; @@ -299,18 +300,18 @@ interface IPackageManager { * As per {@link android.content.pm.PackageManager#getComponentEnabledSetting}. */ int getComponentEnabledSetting(in ComponentName componentName, int userId); - + /** * As per {@link android.content.pm.PackageManager#setApplicationEnabledSetting}. */ void setApplicationEnabledSetting(in String packageName, in int newState, int flags, int userId, String callingPackage); - + /** * As per {@link android.content.pm.PackageManager#getApplicationEnabledSetting}. */ int getApplicationEnabledSetting(in String packageName, int userId); - + /** * Set whether the given package should be considered stopped, making * it not visible to implicit intents that filter out stopped packages. @@ -363,7 +364,7 @@ interface IPackageManager { */ void freeStorage(in String volumeUuid, in long freeStorageSize, in IntentSender pi); - + /** * Delete all the cache files in an applications cache directory * @param packageName The package name of the application whose cache @@ -371,7 +372,7 @@ interface IPackageManager { * @param observer a callback used to notify when the deletion is finished. */ void deleteApplicationCacheFiles(in String packageName, IPackageDataObserver observer); - + /** * Clear the user data directory of an application. * @param packageName The package name of the application whose cache @@ -379,7 +380,7 @@ interface IPackageManager { * @param observer a callback used to notify when the operation is completed. */ void clearApplicationUserData(in String packageName, IPackageDataObserver observer, int userId); - + /** * Get package statistics including the code, data and cache size for * an already installed package @@ -389,7 +390,7 @@ interface IPackageManager { * retrieval of information is complete. */ void getPackageSizeInfo(in String packageName, int userHandle, IPackageStatsObserver observer); - + /** * Get a list of shared libraries that are available on the * system. @@ -403,7 +404,7 @@ interface IPackageManager { FeatureInfo[] getSystemAvailableFeatures(); boolean hasSystemFeature(String name); - + void enterSafeMode(); boolean isSafeMode(); void systemReady(); @@ -494,4 +495,7 @@ interface IPackageManager { void addOnPermissionsChangeListener(in IOnPermissionsChangeListener listener); void removeOnPermissionsChangeListener(in IOnPermissionsChangeListener listener); + + void grantDefaultPermissions(int userId); + void setCarrierAppPackagesProvider(in IPackagesProvider provider); } diff --git a/core/java/android/content/pm/IPackagesProvider.aidl b/core/java/android/content/pm/IPackagesProvider.aidl new file mode 100644 index 0000000..7d76c88 --- /dev/null +++ b/core/java/android/content/pm/IPackagesProvider.aidl @@ -0,0 +1,22 @@ +/* + * 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; + +/** {@hide} */ +interface IPackagesProvider { + String[] getPackages(int userId); +} diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml index 9ac1fdd..ea0c9d0 100755 --- a/core/res/res/values/config.xml +++ b/core/res/res/values/config.xml @@ -1848,7 +1848,9 @@ 2. Pre-installed 3. In the default state (enabled but not explicitly) And SubscriptionInfoUpdater undoes this and marks the app enabled when a SIM is inserted - that marks the app as carrier privileged. --> + that marks the app as carrier privileged. It also grants the app default permissions + for Phone and Location. As such, apps MUST only ever be added to this list if they + obtain user consent to access their location through other means. --> <string-array name="config_disabledUntilUsedPreinstalledCarrierApps" translatable="false" /> <!-- The list of classes that should be added to the notification ranking pipline. diff --git a/services/core/java/com/android/server/pm/DefaultPermissionGrantPolicy.java b/services/core/java/com/android/server/pm/DefaultPermissionGrantPolicy.java index fe3103b..b168e92 100644 --- a/services/core/java/com/android/server/pm/DefaultPermissionGrantPolicy.java +++ b/services/core/java/com/android/server/pm/DefaultPermissionGrantPolicy.java @@ -45,7 +45,7 @@ import static android.os.Process.FIRST_APPLICATION_UID; * have phone related permission by default. */ final class DefaultPermissionGrantPolicy { - private static final String TAG = "DefaultPermissionGrantPolicy"; + private static final String TAG = "DefaultPermGrantPolicy"; // must be <= 23 chars private static final boolean DEBUG = false; private static final String PACKAGE_MIME_TYPE = "application/vnd.android.package-archive"; @@ -133,6 +133,7 @@ final class DefaultPermissionGrantPolicy { private PackagesProvider mImePackagesProvider; private PackagesProvider mLocationPackagesProvider; private PackagesProvider mVoiceInteractionPackagesProvider; + private PackagesProvider mCarrierAppPackagesProvider; public DefaultPermissionGrantPolicy(PackageManagerService service) { mService = service; @@ -150,6 +151,10 @@ final class DefaultPermissionGrantPolicy { mVoiceInteractionPackagesProvider = provider; } + public void setCarrierAppPackagesProviderLPw(PackagesProvider provider) { + mCarrierAppPackagesProvider = provider; + } + public void grantDefaultPermissions(int userId) { grantPermissionsToSysComponentsAndPrivApps(userId); grantDefaultSystemHandlerPermissions(userId); @@ -193,11 +198,13 @@ final class DefaultPermissionGrantPolicy { final PackagesProvider imePackagesProvider; final PackagesProvider locationPackagesProvider; final PackagesProvider voiceInteractionPackagesProvider; + final PackagesProvider carrierAppPackagesProvider; synchronized (mService.mPackages) { imePackagesProvider = mImePackagesProvider; locationPackagesProvider = mLocationPackagesProvider; voiceInteractionPackagesProvider = mVoiceInteractionPackagesProvider; + carrierAppPackagesProvider = mCarrierAppPackagesProvider; } String[] imePackageNames = (imePackagesProvider != null) @@ -206,6 +213,8 @@ final class DefaultPermissionGrantPolicy { ? voiceInteractionPackagesProvider.getPackages(userId) : null; String[] locationPackageNames = (locationPackagesProvider != null) ? locationPackagesProvider.getPackages(userId) : null; + String[] carrierAppPackageNames = (carrierAppPackagesProvider != null) + ? carrierAppPackagesProvider.getPackages(userId) : null; synchronized (mService.mPackages) { // Installers @@ -382,6 +391,18 @@ final class DefaultPermissionGrantPolicy { } } } + + // Carrier apps + if (carrierAppPackageNames != null) { + for (String packageName : carrierAppPackageNames) { + PackageParser.Package carrierPackage = getSystemPackageLPr(packageName); + if (carrierPackage != null + && doesPackageSupportRuntimePermissions(carrierPackage)) { + grantRuntimePermissionsLPw(carrierPackage, PHONE_PERMISSIONS, userId); + grantRuntimePermissionsLPw(carrierPackage, LOCATION_PERMISSIONS, userId); + } + } + } } } diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java index d7abad0..73c4962 100644 --- a/services/core/java/com/android/server/pm/PackageManagerService.java +++ b/services/core/java/com/android/server/pm/PackageManagerService.java @@ -100,6 +100,7 @@ import android.content.pm.IPackageInstaller; import android.content.pm.IPackageManager; import android.content.pm.IPackageMoveObserver; import android.content.pm.IPackageStatsObserver; +import android.content.pm.IPackagesProvider; import android.content.pm.InstrumentationInfo; import android.content.pm.IntentFilterVerificationInfo; import android.content.pm.KeySet; @@ -253,14 +254,14 @@ import java.util.concurrent.atomic.AtomicLong; /** * Keep track of all those .apks everywhere. - * + * * This is very central to the platform's security; please run the unit * tests whenever making modifications here: - * + * mmm frameworks/base/tests/AndroidTests adb install -r -f out/target/product/passion/data/app/AndroidTests.apk adb shell am instrument -w -e class com.android.unit_tests.PackageManagerTests com.android.unit_tests/android.test.InstrumentationTestRunner - * + * * {@hide} */ public class PackageManagerService extends IPackageManager.Stub { @@ -508,7 +509,7 @@ public class PackageManagerService extends IPackageManager.Stub { // Packages whose data we have transfered into another package, thus // should no longer exist. final ArraySet<String> mTransferedPackages = new ArraySet<String>(); - + // Broadcast actions that are only available to the system. final ArraySet<String> mProtectedBroadcasts = new ArraySet<String>(); @@ -1072,7 +1073,7 @@ public class PackageManagerService extends IPackageManager.Stub { Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND); } } - + void doHandleMessage(Message msg) { switch (msg.what) { case INIT_COPY: { @@ -2485,7 +2486,7 @@ public class PackageManagerService extends IPackageManager.Stub { } return out; } - + @Override public String[] canonicalToCurrentPackageNames(String[] names) { String[] out = new String[names.length]; @@ -2555,7 +2556,7 @@ public class PackageManagerService extends IPackageManager.Stub { pi.protectionLevel = bp.protectionLevel; return pi; } - + @Override public PermissionInfo getPermissionInfo(String name, int flags) { // reader @@ -3035,7 +3036,7 @@ public class PackageManagerService extends IPackageManager.Stub { } return s1.equals(s2); } - + static boolean comparePermissionInfos(PermissionInfo pi1, PermissionInfo pi2) { if (pi1.icon != pi2.icon) return false; if (pi1.logo != pi2.logo) return false; @@ -4155,7 +4156,7 @@ public class PackageManagerService extends IPackageManager.Stub { ComponentName comp = intent.getComponent(); if (comp == null) { if (intent.getSelector() != null) { - intent = intent.getSelector(); + intent = intent.getSelector(); comp = intent.getComponent(); } } @@ -4710,7 +4711,7 @@ public class PackageManagerService extends IPackageManager.Stub { ComponentName comp = intent.getComponent(); if (comp == null) { if (intent.getSelector() != null) { - intent = intent.getSelector(); + intent = intent.getSelector(); comp = intent.getComponent(); } } @@ -4761,7 +4762,7 @@ public class PackageManagerService extends IPackageManager.Stub { ComponentName comp = intent.getComponent(); if (comp == null) { if (intent.getSelector() != null) { - intent = intent.getSelector(); + intent = intent.getSelector(); comp = intent.getComponent(); } } @@ -6188,7 +6189,7 @@ public class PackageManagerService extends IPackageManager.Stub { + "): packages=" + suid.packages); } } - + // Check if we are renaming from an original package name. PackageSetting origPackage = null; String realName = null; @@ -6208,7 +6209,7 @@ public class PackageManagerService extends IPackageManager.Stub { // it is not already done. pkg.setPackageName(renamed); } - + } else { for (int i=pkg.mOriginalPackages.size()-1; i>=0; i--) { if ((origPackage = mSettings.peekPackageLPr( @@ -6238,7 +6239,7 @@ public class PackageManagerService extends IPackageManager.Stub { } } } - + if (mTransferedPackages.contains(pkg.packageName)) { Slog.w(TAG, "Package " + pkg.packageName + " was transferred to another, but its .apk remains"); @@ -6263,24 +6264,24 @@ public class PackageManagerService extends IPackageManager.Stub { // looking up the package under its new name, so getPackageLP // can take care of fiddling things correctly. pkg.setPackageName(origPackage.name); - + // File a report about this. String msg = "New package " + pkgSetting.realName + " renamed to replace old package " + pkgSetting.name; reportSettingsProblem(Log.WARN, msg); - + // Make a note of it. mTransferedPackages.add(origPackage.name); - + // No longer need to retain this. pkgSetting.origPackage = null; } - + if (realName != null) { // Make a note of it. mTransferedPackages.add(pkg.packageName); } - + if (mSettings.isDisabledSystemPackageLPr(pkg.packageName)) { pkg.applicationInfo.flags |= ApplicationInfo.FLAG_UPDATED_SYSTEM_APP; } @@ -6396,7 +6397,7 @@ public class PackageManagerService extends IPackageManager.Stub { } final String pkgName = pkg.packageName; - + final long scanFileTime = scanFile.lastModified(); final boolean forceDex = (scanFlags & SCAN_FORCE_DEX) != 0; pkg.applicationInfo.processName = fixProcessName( @@ -8316,7 +8317,7 @@ public class PackageManagerService extends IPackageManager.Stub { PackageParser.ActivityIntentInfo info) { return packageName.equals(info.activity.owner.packageName); } - + @Override protected ResolveInfo newResult(PackageParser.ActivityIntentInfo info, int match, int userId) { @@ -8539,7 +8540,7 @@ public class PackageManagerService extends IPackageManager.Stub { PackageParser.ServiceIntentInfo info) { return packageName.equals(info.service.owner.packageName); } - + @Override protected ResolveInfo newResult(PackageParser.ServiceIntentInfo filter, int match, int userId) { @@ -13943,7 +13944,7 @@ public class PackageManagerService extends IPackageManager.Stub { boolean checkin = false; String packageName = null; - + int opti = 0; while (opti < args.length) { String opt = args[opti]; @@ -15589,4 +15590,55 @@ public class PackageManagerService extends IPackageManager.Stub { } } } + + @Override + public void grantDefaultPermissions(final int userId) { + enforceSystemOrPhoneCaller("grantDefaultPermissions"); + long token = Binder.clearCallingIdentity(); + try { + // 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(userId); + } + }); + } finally { + Binder.restoreCallingIdentity(token); + } + } + + @Override + public void setCarrierAppPackagesProvider(final IPackagesProvider provider) { + enforceSystemOrPhoneCaller("setCarrierAppPackagesProvider"); + long token = Binder.clearCallingIdentity(); + try { + PackageManagerInternal.PackagesProvider wrapper = + new PackageManagerInternal.PackagesProvider() { + @Override + public String[] getPackages(int userId) { + try { + return provider.getPackages(userId); + } catch (RemoteException e) { + return null; + } + } + }; + synchronized (mPackages) { + mDefaultPermissionPolicy.setCarrierAppPackagesProviderLPw(wrapper); + } + } finally { + Binder.restoreCallingIdentity(token); + } + } + + private static void enforceSystemOrPhoneCaller(String tag) { + int callingUid = Binder.getCallingUid(); + if (callingUid != Process.PHONE_UID && callingUid != Process.SYSTEM_UID) { + throw new SecurityException( + "Cannot call " + tag + " from UID " + callingUid); + } + } } |