summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJeff Davidson <jpd@google.com>2015-06-22 16:54:34 -0700
committerJeff Davidson <jpd@google.com>2015-06-23 09:55:23 -0700
commit2a880312086147577e1e814bda6985fa97fb343b (patch)
tree58cbe4c66daf8ec1da048e9af62043ded63fd274
parent0b50e56c070878211d9003e072128716bee445ba (diff)
downloadframeworks_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.mk1
-rw-r--r--core/java/android/content/pm/IPackageManager.aidl20
-rw-r--r--core/java/android/content/pm/IPackagesProvider.aidl22
-rwxr-xr-xcore/res/res/values/config.xml4
-rw-r--r--services/core/java/com/android/server/pm/DefaultPermissionGrantPolicy.java23
-rw-r--r--services/core/java/com/android/server/pm/PackageManagerService.java98
6 files changed, 135 insertions, 33 deletions
diff --git a/Android.mk b/Android.mk
index e96a932..a02b326 100644
--- a/Android.mk
+++ b/Android.mk
@@ -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);
+ }
+ }
}