summaryrefslogtreecommitdiff
path: root/telephony/common
diff options
context:
space:
mode:
Diffstat (limited to 'telephony/common')
-rw-r--r--telephony/common/android/telephony/LocationAccessPolicy.java43
-rw-r--r--telephony/common/com/android/internal/telephony/CarrierAppUtils.java360
-rw-r--r--telephony/common/com/android/internal/telephony/GsmAlphabet.java2
-rw-r--r--telephony/common/com/android/internal/telephony/SmsApplication.java34
-rw-r--r--telephony/common/com/android/internal/telephony/TelephonyPermissions.java98
-rw-r--r--telephony/common/com/android/internal/telephony/util/TelephonyUtils.java10
6 files changed, 285 insertions, 262 deletions
diff --git a/telephony/common/android/telephony/LocationAccessPolicy.java b/telephony/common/android/telephony/LocationAccessPolicy.java
index 892e55942d3f..1985f7810873 100644
--- a/telephony/common/android/telephony/LocationAccessPolicy.java
+++ b/telephony/common/android/telephony/LocationAccessPolicy.java
@@ -24,20 +24,16 @@ import android.app.ActivityManager;
import android.app.AppOpsManager;
import android.content.Context;
import android.content.pm.PackageManager;
-import android.content.pm.UserInfo;
import android.location.LocationManager;
import android.os.Binder;
import android.os.Build;
import android.os.Process;
import android.os.UserHandle;
-import android.os.UserManager;
import android.util.Log;
import android.widget.Toast;
import com.android.internal.telephony.util.TelephonyUtils;
-import java.util.List;
-
/**
* Helper for performing location access checks.
* @hide
@@ -111,6 +107,9 @@ public final class LocationAccessPolicy {
return this;
}
+ /**
+ * Mandatory parameter, used for performing permission checks.
+ */
public Builder setCallingUid(int callingUid) {
mCallingUid = callingUid;
return this;
@@ -195,6 +194,17 @@ public final class LocationAccessPolicy {
}
}
+ private static String getAppOpsString(String manifestPermission) {
+ switch (manifestPermission) {
+ case Manifest.permission.ACCESS_FINE_LOCATION:
+ return AppOpsManager.OPSTR_FINE_LOCATION;
+ case Manifest.permission.ACCESS_COARSE_LOCATION:
+ return AppOpsManager.OPSTR_COARSE_LOCATION;
+ default:
+ return null;
+ }
+ }
+
private static LocationPermissionResult checkAppLocationPermissionHelper(Context context,
LocationPermissionQuery query, String permissionToCheck) {
String locationTypeForLog =
@@ -208,8 +218,8 @@ public final class LocationAccessPolicy {
if (hasManifestPermission) {
// Only check the app op if the app has the permission.
int appOpMode = context.getSystemService(AppOpsManager.class)
- .noteOpNoThrow(AppOpsManager.permissionToOpCode(permissionToCheck),
- query.callingUid, query.callingPackage);
+ .noteOpNoThrow(getAppOpsString(permissionToCheck), query.callingUid,
+ query.callingPackage, query.callingFeatureId, null);
if (appOpMode == AppOpsManager.MODE_ALLOWED) {
// If the app did everything right, return without logging.
return LocationPermissionResult.ALLOWED;
@@ -295,7 +305,7 @@ public final class LocationAccessPolicy {
}
private static boolean checkSystemLocationAccess(@NonNull Context context, int uid, int pid) {
- if (!isLocationModeEnabled(context, UserHandle.getUserId(uid))) {
+ if (!isLocationModeEnabled(context, UserHandle.getUserHandleForUid(uid).getIdentifier())) {
if (DBG) Log.w(TAG, "Location disabled, failed, (" + uid + ")");
return false;
}
@@ -322,20 +332,17 @@ public final class LocationAccessPolicy {
private static boolean isCurrentProfile(@NonNull Context context, int uid) {
long token = Binder.clearCallingIdentity();
try {
- final int currentUser = ActivityManager.getCurrentUser();
- final int callingUserId = UserHandle.getUserId(uid);
- if (callingUserId == currentUser) {
+ if (UserHandle.getUserHandleForUid(uid).getIdentifier()
+ == ActivityManager.getCurrentUser()) {
return true;
+ }
+ ActivityManager activityManager = context.getSystemService(ActivityManager.class);
+ if (activityManager != null) {
+ return activityManager.isProfileForeground(
+ UserHandle.getUserHandleForUid(ActivityManager.getCurrentUser()));
} else {
- List<UserInfo> userProfiles = context.getSystemService(
- UserManager.class).getProfiles(currentUser);
- for (UserInfo user : userProfiles) {
- if (user.id == callingUserId) {
- return true;
- }
- }
+ return false;
}
- return false;
} finally {
Binder.restoreCallingIdentity(token);
}
diff --git a/telephony/common/com/android/internal/telephony/CarrierAppUtils.java b/telephony/common/com/android/internal/telephony/CarrierAppUtils.java
index 4af19b5489ca..e57b03098758 100644
--- a/telephony/common/com/android/internal/telephony/CarrierAppUtils.java
+++ b/telephony/common/com/android/internal/telephony/CarrierAppUtils.java
@@ -20,25 +20,23 @@ import android.annotation.Nullable;
import android.content.ContentResolver;
import android.content.Context;
import android.content.pm.ApplicationInfo;
-import android.content.pm.IPackageManager;
import android.content.pm.PackageManager;
-import android.content.res.Resources;
-import android.os.RemoteException;
+import android.os.Build;
+import android.os.CarrierAssociatedAppEntry;
+import android.os.SystemConfigManager;
import android.os.UserHandle;
+import android.permission.PermissionManager;
import android.provider.Settings;
import android.telephony.TelephonyManager;
import android.util.ArrayMap;
-import android.util.ArraySet;
import android.util.Log;
-import com.android.internal.R;
import com.android.internal.annotations.VisibleForTesting;
-import com.android.internal.telephony.util.ArrayUtils;
-import com.android.server.SystemConfig;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
+import java.util.Set;
/**
* Utilities for handling carrier applications.
@@ -55,19 +53,19 @@ public final class CarrierAppUtils {
* Handle preinstalled carrier apps which should be disabled until a matching SIM is inserted.
*
* Evaluates the list of applications in
- * {@link SystemConfig#getDisabledUntilUsedPreinstalledCarrierApps()}. We want to disable each
- * such application which is present on the system image until the user inserts a SIM which
- * causes that application to gain carrier privilege (indicating a "match"), without interfering
- * with the user if they opt to enable/disable the app explicitly.
+ * {@link SystemConfigManager#getDisabledUntilUsedPreinstalledCarrierApps()}. We want to disable
+ * each such application which is present on the system image until the user inserts a SIM
+ * which causes that application to gain carrier privilege (indicating a "match"), without
+ * interfering with the user if they opt to enable/disable the app explicitly.
*
* So, for each such app, we either disable until used IFF the app is not carrier privileged AND
* in the default state (e.g. not explicitly DISABLED/DISABLED_BY_USER/ENABLED), or we enable if
* the app is carrier privileged and in either the default state or DISABLED_UNTIL_USED.
*
* In addition, there is a list of carrier-associated applications in
- * {@link SystemConfig#getDisabledUntilUsedPreinstalledCarrierAssociatedApps}. Each app in this
- * list is associated with a carrier app. When the given carrier app is enabled/disabled per the
- * above, the associated applications are enabled/disabled to match.
+ * {@link SystemConfigManager#getDisabledUntilUsedPreinstalledCarrierAssociatedApps}. Each app
+ * in this list is associated with a carrier app. When the given carrier app is enabled/disabled
+ * per the above, the associated applications are enabled/disabled to match.
*
* When enabling a carrier app we also grant it default permissions.
*
@@ -76,25 +74,24 @@ public final class CarrierAppUtils {
* privileged apps may have changed.
*/
public static synchronized void disableCarrierAppsUntilPrivileged(String callingPackage,
- IPackageManager packageManager, TelephonyManager telephonyManager,
- int userId, Context context) {
+ TelephonyManager telephonyManager, int userId, Context context) {
if (DEBUG) {
Log.d(TAG, "disableCarrierAppsUntilPrivileged");
}
- SystemConfig config = SystemConfig.getInstance();
- ArraySet<String> systemCarrierAppsDisabledUntilUsed =
+ SystemConfigManager config = context.getSystemService(SystemConfigManager.class);
+ Set<String> systemCarrierAppsDisabledUntilUsed =
config.getDisabledUntilUsedPreinstalledCarrierApps();
- ArrayMap<String, List<String>> systemCarrierAssociatedAppsDisabledUntilUsed =
- config.getDisabledUntilUsedPreinstalledCarrierAssociatedApps();
+ Map<String, List<CarrierAssociatedAppEntry>> systemCarrierAssociatedAppsDisabledUntilUsed =
+ config.getDisabledUntilUsedPreinstalledCarrierAssociatedAppEntries();
ContentResolver contentResolver = getContentResolverForUser(context, userId);
- disableCarrierAppsUntilPrivileged(callingPackage, packageManager, telephonyManager,
- contentResolver, userId, systemCarrierAppsDisabledUntilUsed,
- systemCarrierAssociatedAppsDisabledUntilUsed);
+ disableCarrierAppsUntilPrivileged(callingPackage, telephonyManager, contentResolver,
+ userId, systemCarrierAppsDisabledUntilUsed,
+ systemCarrierAssociatedAppsDisabledUntilUsed, context);
}
/**
- * Like {@link #disableCarrierAppsUntilPrivileged(String, IPackageManager, TelephonyManager,
- * ContentResolver, int)}, but assumes that no carrier apps have carrier privileges.
+ * Like {@link #disableCarrierAppsUntilPrivileged(String, TelephonyManager, int, Context)},
+ * but assumes that no carrier apps have carrier privileges.
*
* This prevents a potential race condition on first boot - since the app's default state is
* enabled, we will initially disable it when the telephony stack is first initialized as it has
@@ -104,21 +101,20 @@ public final class CarrierAppUtils {
* Manager can kill it, and this can lead to crashes as the app is in an unexpected state.
*/
public static synchronized void disableCarrierAppsUntilPrivileged(String callingPackage,
- IPackageManager packageManager, int userId, Context context) {
+ int userId, Context context) {
if (DEBUG) {
Log.d(TAG, "disableCarrierAppsUntilPrivileged");
}
- SystemConfig config = SystemConfig.getInstance();
- ArraySet<String> systemCarrierAppsDisabledUntilUsed =
+ SystemConfigManager config = context.getSystemService(SystemConfigManager.class);
+ Set<String> systemCarrierAppsDisabledUntilUsed =
config.getDisabledUntilUsedPreinstalledCarrierApps();
-
- ArrayMap<String, List<String>> systemCarrierAssociatedAppsDisabledUntilUsed =
- config.getDisabledUntilUsedPreinstalledCarrierAssociatedApps();
+ Map<String, List<CarrierAssociatedAppEntry>> systemCarrierAssociatedAppsDisabledUntilUsed =
+ config.getDisabledUntilUsedPreinstalledCarrierAssociatedAppEntries();
ContentResolver contentResolver = getContentResolverForUser(context, userId);
- disableCarrierAppsUntilPrivileged(callingPackage, packageManager,
- null /* telephonyManager */, contentResolver, userId,
- systemCarrierAppsDisabledUntilUsed, systemCarrierAssociatedAppsDisabledUntilUsed);
+ disableCarrierAppsUntilPrivileged(callingPackage, null /* telephonyManager */,
+ contentResolver, userId, systemCarrierAppsDisabledUntilUsed,
+ systemCarrierAssociatedAppsDisabledUntilUsed, context);
}
private static ContentResolver getContentResolverForUser(Context context, int userId) {
@@ -142,49 +138,51 @@ public final class CarrierAppUtils {
// Must be public b/c framework unit tests can't access package-private methods.
@VisibleForTesting
public static void disableCarrierAppsUntilPrivileged(String callingPackage,
- IPackageManager packageManager, @Nullable TelephonyManager telephonyManager,
- ContentResolver contentResolver, int userId,
- ArraySet<String> systemCarrierAppsDisabledUntilUsed,
- ArrayMap<String, List<String>> systemCarrierAssociatedAppsDisabledUntilUsed) {
+ @Nullable TelephonyManager telephonyManager, ContentResolver contentResolver,
+ int userId, Set<String> systemCarrierAppsDisabledUntilUsed,
+ Map<String, List<CarrierAssociatedAppEntry>>
+ systemCarrierAssociatedAppsDisabledUntilUsed, Context context) {
+ PackageManager packageManager = context.getPackageManager();
+ PermissionManager permissionManager =
+ (PermissionManager) context.getSystemService(Context.PERMISSION_SERVICE);
List<ApplicationInfo> candidates = getDefaultCarrierAppCandidatesHelper(
- packageManager, userId, systemCarrierAppsDisabledUntilUsed);
+ userId, systemCarrierAppsDisabledUntilUsed, context);
if (candidates == null || candidates.isEmpty()) {
return;
}
- Map<String, List<ApplicationInfo>> associatedApps = getDefaultCarrierAssociatedAppsHelper(
- packageManager,
- userId,
- systemCarrierAssociatedAppsDisabledUntilUsed);
+ Map<String, List<AssociatedAppInfo>> associatedApps = getDefaultCarrierAssociatedAppsHelper(
+ userId, systemCarrierAssociatedAppsDisabledUntilUsed, context);
List<String> enabledCarrierPackages = new ArrayList<>();
- boolean hasRunOnce = Settings.Secure.getInt(contentResolver,
- Settings.Secure.CARRIER_APPS_HANDLED, 0) == 1;
+ int carrierAppsHandledSdk =
+ Settings.Secure.getInt(contentResolver, Settings.Secure.CARRIER_APPS_HANDLED, 0);
+ if (DEBUG) {
+ Log.i(TAG, "Last execution SDK: " + carrierAppsHandledSdk);
+ }
+ boolean hasRunEver = carrierAppsHandledSdk != 0; // SDKs < R used to just set 1 here
+ boolean hasRunForSdk = carrierAppsHandledSdk == Build.VERSION.SDK_INT;
try {
for (ApplicationInfo ai : candidates) {
String packageName = ai.packageName;
- String[] restrictedCarrierApps = Resources.getSystem().getStringArray(
- R.array.config_restrictedPreinstalledCarrierApps);
boolean hasPrivileges = telephonyManager != null
&& telephonyManager.checkCarrierPrivilegesForPackageAnyPhone(packageName)
- == TelephonyManager.CARRIER_PRIVILEGE_STATUS_HAS_ACCESS
- && !ArrayUtils.contains(restrictedCarrierApps, packageName);
+ == TelephonyManager.CARRIER_PRIVILEGE_STATUS_HAS_ACCESS;
// add hiddenUntilInstalled flag for carrier apps and associated apps
- packageManager.setSystemAppHiddenUntilInstalled(packageName, true);
- List<ApplicationInfo> associatedAppList = associatedApps.get(packageName);
+ packageManager.setSystemAppState(
+ packageName, PackageManager.SYSTEM_APP_STATE_HIDDEN_UNTIL_INSTALLED_HIDDEN);
+ List<AssociatedAppInfo> associatedAppList = associatedApps.get(packageName);
if (associatedAppList != null) {
- for (ApplicationInfo associatedApp : associatedAppList) {
- packageManager.setSystemAppHiddenUntilInstalled(
- associatedApp.packageName,
- true
- );
+ for (AssociatedAppInfo associatedApp : associatedAppList) {
+ packageManager.setSystemAppState(associatedApp.appInfo.packageName,
+ PackageManager.SYSTEM_APP_STATE_HIDDEN_UNTIL_INSTALLED_HIDDEN);
}
}
- int enabledSetting = packageManager.getApplicationEnabledSetting(packageName,
- userId);
+ int enabledSetting = context.createContextAsUser(UserHandle.of(userId), 0)
+ .getPackageManager().getApplicationEnabledSetting(packageName);
if (hasPrivileges) {
// Only update enabled state for the app on /system. Once it has been
// updated we shouldn't touch it.
@@ -193,44 +191,55 @@ public final class CarrierAppUtils {
|| enabledSetting
== PackageManager.COMPONENT_ENABLED_STATE_DISABLED_UNTIL_USED
|| (ai.flags & ApplicationInfo.FLAG_INSTALLED) == 0) {
- Log.i(TAG, "Update state(" + packageName + "): ENABLED for user "
+ Log.i(TAG, "Update state (" + packageName + "): ENABLED for user "
+ userId);
- packageManager.setSystemAppInstallState(
- packageName,
- true /*installed*/,
- userId);
- packageManager.setApplicationEnabledSetting(
- packageName,
- PackageManager.COMPONENT_ENABLED_STATE_ENABLED,
- PackageManager.DONT_KILL_APP,
- userId,
- callingPackage);
+ context.createContextAsUser(UserHandle.of(userId), 0)
+ .getPackageManager()
+ .setSystemAppState(
+ packageName, PackageManager.SYSTEM_APP_STATE_INSTALLED);
+ context.createPackageContextAsUser(callingPackage, 0, UserHandle.of(userId))
+ .getPackageManager()
+ .setApplicationEnabledSetting(
+ packageName,
+ PackageManager.COMPONENT_ENABLED_STATE_ENABLED,
+ PackageManager.DONT_KILL_APP);
}
// Also enable any associated apps for this carrier app.
if (associatedAppList != null) {
- for (ApplicationInfo associatedApp : associatedAppList) {
- int associatedAppEnabledSetting =
- packageManager.getApplicationEnabledSetting(
- associatedApp.packageName, userId);
+ for (AssociatedAppInfo associatedApp : associatedAppList) {
+ int associatedAppEnabledSetting = context
+ .createContextAsUser(UserHandle.of(userId), 0)
+ .getPackageManager()
+ .getApplicationEnabledSetting(
+ associatedApp.appInfo.packageName);
+ boolean associatedAppInstalled = (associatedApp.appInfo.flags
+ & ApplicationInfo.FLAG_INSTALLED) != 0;
+ if (DEBUG) {
+ Log.i(TAG, "(hasPrivileges) associated app "
+ + associatedApp.appInfo.packageName + ", enabled = "
+ + associatedAppEnabledSetting + ", installed = "
+ + associatedAppInstalled);
+ }
if (associatedAppEnabledSetting
== PackageManager.COMPONENT_ENABLED_STATE_DEFAULT
|| associatedAppEnabledSetting
== PackageManager.COMPONENT_ENABLED_STATE_DISABLED_UNTIL_USED
- || (associatedApp.flags
- & ApplicationInfo.FLAG_INSTALLED) == 0) {
- Log.i(TAG, "Update associated state(" + associatedApp.packageName
- + "): ENABLED for user " + userId);
- packageManager.setSystemAppInstallState(
- associatedApp.packageName,
- true /*installed*/,
- userId);
- packageManager.setApplicationEnabledSetting(
- associatedApp.packageName,
- PackageManager.COMPONENT_ENABLED_STATE_ENABLED,
- PackageManager.DONT_KILL_APP,
- userId,
- callingPackage);
+ || !associatedAppInstalled) {
+ Log.i(TAG, "Update associated state ("
+ + associatedApp.appInfo.packageName + "): ENABLED for user "
+ + userId);
+ context.createContextAsUser(UserHandle.of(userId), 0)
+ .getPackageManager()
+ .setSystemAppState(associatedApp.appInfo.packageName,
+ PackageManager.SYSTEM_APP_STATE_INSTALLED);
+ context.createPackageContextAsUser(
+ callingPackage, 0, UserHandle.of(userId))
+ .getPackageManager()
+ .setApplicationEnabledSetting(
+ associatedApp.appInfo.packageName,
+ PackageManager.COMPONENT_ENABLED_STATE_ENABLED,
+ PackageManager.DONT_KILL_APP);
}
}
}
@@ -243,44 +252,64 @@ public final class CarrierAppUtils {
if (!isUpdatedSystemApp(ai) && enabledSetting
== PackageManager.COMPONENT_ENABLED_STATE_DEFAULT
&& (ai.flags & ApplicationInfo.FLAG_INSTALLED) != 0) {
- Log.i(TAG, "Update state(" + packageName
+ Log.i(TAG, "Update state (" + packageName
+ "): DISABLED_UNTIL_USED for user " + userId);
- packageManager.setSystemAppInstallState(
- packageName,
- false /*installed*/,
- userId);
+ context.createContextAsUser(UserHandle.of(userId), 0)
+ .getPackageManager()
+ .setSystemAppState(
+ packageName, PackageManager.SYSTEM_APP_STATE_UNINSTALLED);
}
- // Also disable any associated apps for this carrier app if this is the first
- // run. We avoid doing this a second time because it is brittle to rely on the
- // distinction between "default" and "enabled".
- if (!hasRunOnce) {
- if (associatedAppList != null) {
- for (ApplicationInfo associatedApp : associatedAppList) {
- int associatedAppEnabledSetting =
- packageManager.getApplicationEnabledSetting(
- associatedApp.packageName, userId);
- if (associatedAppEnabledSetting
- == PackageManager.COMPONENT_ENABLED_STATE_DEFAULT
- && (associatedApp.flags
- & ApplicationInfo.FLAG_INSTALLED) != 0) {
- Log.i(TAG,
- "Update associated state(" + associatedApp.packageName
- + "): DISABLED_UNTIL_USED for user " + userId);
- packageManager.setSystemAppInstallState(
- associatedApp.packageName,
- false /*installed*/,
- userId);
- }
+ // Associated apps are more brittle, because we can't rely on the distinction
+ // between "default" and "enabled". To account for this, we have two cases:
+ // 1. We've never run before, so we're fine to disable all associated apps.
+ // 2. We've run before, but not on this SDK version, so we will only operate on
+ // apps with addedInSdk in the range (lastHandledSdk, currentSdk].
+ // Otherwise, don't touch the associated apps.
+ if (associatedAppList != null) {
+ for (AssociatedAppInfo associatedApp : associatedAppList) {
+ boolean allowDisable = !hasRunEver || (!hasRunForSdk
+ && associatedApp.addedInSdk
+ != CarrierAssociatedAppEntry.SDK_UNSPECIFIED
+ && associatedApp.addedInSdk > carrierAppsHandledSdk
+ && associatedApp.addedInSdk <= Build.VERSION.SDK_INT);
+ int associatedAppEnabledSetting = context
+ .createContextAsUser(UserHandle.of(userId), 0)
+ .getPackageManager()
+ .getApplicationEnabledSetting(
+ associatedApp.appInfo.packageName);
+ boolean associatedAppInstalled = (associatedApp.appInfo.flags
+ & ApplicationInfo.FLAG_INSTALLED) != 0;
+ if (DEBUG) {
+ Log.i(TAG, "(!hasPrivileges) associated app "
+ + associatedApp.appInfo.packageName + ", allowDisable = "
+ + allowDisable + ", addedInSdk = "
+ + associatedApp.addedInSdk + ", enabled = "
+ + associatedAppEnabledSetting + ", installed = "
+ + associatedAppInstalled);
+ }
+ if (allowDisable
+ && associatedAppEnabledSetting
+ == PackageManager.COMPONENT_ENABLED_STATE_DEFAULT
+ && associatedAppInstalled) {
+ Log.i(TAG,
+ "Update associated state ("
+ + associatedApp.appInfo.packageName
+ + "): DISABLED_UNTIL_USED for user " + userId);
+ context.createContextAsUser(UserHandle.of(userId), 0)
+ .getPackageManager()
+ .setSystemAppState(associatedApp.appInfo.packageName,
+ PackageManager.SYSTEM_APP_STATE_UNINSTALLED);
}
}
}
}
}
- // Mark the execution so we do not disable apps again.
- if (!hasRunOnce) {
- Settings.Secure.putInt(contentResolver, Settings.Secure.CARRIER_APPS_HANDLED, 1);
+ // Mark the execution so we do not disable apps again on this SDK version.
+ if (!hasRunEver || !hasRunForSdk) {
+ Settings.Secure.putInt(contentResolver, Settings.Secure.CARRIER_APPS_HANDLED,
+ Build.VERSION.SDK_INT);
}
if (!enabledCarrierPackages.isEmpty()) {
@@ -288,9 +317,10 @@ public final class CarrierAppUtils {
// apps.
String[] packageNames = new String[enabledCarrierPackages.size()];
enabledCarrierPackages.toArray(packageNames);
- packageManager.grantDefaultPermissionsToEnabledCarrierApps(packageNames, userId);
+ permissionManager.grantDefaultPermissionsToEnabledCarrierApps(packageNames,
+ UserHandle.of(userId), Runnable::run, isSuccess -> { });
}
- } catch (RemoteException e) {
+ } catch (PackageManager.NameNotFoundException e) {
Log.w(TAG, "Could not reach PackageManager", e);
}
}
@@ -299,13 +329,13 @@ public final class CarrierAppUtils {
* Returns the list of "default" carrier apps.
*
* This is the subset of apps returned by
- * {@link #getDefaultCarrierAppCandidates(IPackageManager, int)} which currently have carrier
+ * {@link #getDefaultCarrierAppCandidates(int, Context)} which currently have carrier
* privileges per the SIM(s) inserted in the device.
*/
- public static List<ApplicationInfo> getDefaultCarrierApps(IPackageManager packageManager,
- TelephonyManager telephonyManager, int userId) {
+ public static List<ApplicationInfo> getDefaultCarrierApps(
+ TelephonyManager telephonyManager, int userId, Context context) {
// Get all system apps from the default list.
- List<ApplicationInfo> candidates = getDefaultCarrierAppCandidates(packageManager, userId);
+ List<ApplicationInfo> candidates = getDefaultCarrierAppCandidates(userId, context);
if (candidates == null || candidates.isEmpty()) {
return null;
}
@@ -331,39 +361,33 @@ public final class CarrierAppUtils {
* Returns the list of "default" carrier app candidates.
*
* These are the apps subject to the hiding/showing logic in
- * {@link CarrierAppUtils#disableCarrierAppsUntilPrivileged(String, IPackageManager,
- * TelephonyManager, ContentResolver, int)}, as well as the apps which should have default
+ * {@link CarrierAppUtils#disableCarrierAppsUntilPrivileged(String, TelephonyManager, int,
+ * Context)}, as well as the apps which should have default
* permissions granted, when a matching SIM is inserted.
*
* Whether or not the app is actually considered a default app depends on whether the app has
* carrier privileges as determined by the SIMs in the device.
*/
public static List<ApplicationInfo> getDefaultCarrierAppCandidates(
- IPackageManager packageManager, int userId) {
- ArraySet<String> systemCarrierAppsDisabledUntilUsed =
- SystemConfig.getInstance().getDisabledUntilUsedPreinstalledCarrierApps();
- return getDefaultCarrierAppCandidatesHelper(packageManager, userId,
- systemCarrierAppsDisabledUntilUsed);
+ int userId, Context context) {
+ Set<String> systemCarrierAppsDisabledUntilUsed =
+ context.getSystemService(SystemConfigManager.class)
+ .getDisabledUntilUsedPreinstalledCarrierApps();
+ return getDefaultCarrierAppCandidatesHelper(userId, systemCarrierAppsDisabledUntilUsed,
+ context);
}
private static List<ApplicationInfo> getDefaultCarrierAppCandidatesHelper(
- IPackageManager packageManager,
- int userId,
- ArraySet<String> systemCarrierAppsDisabledUntilUsed) {
- if (systemCarrierAppsDisabledUntilUsed == null) {
- return null;
- }
-
- int size = systemCarrierAppsDisabledUntilUsed.size();
- if (size == 0) {
+ int userId, Set<String> systemCarrierAppsDisabledUntilUsed, Context context) {
+ if (systemCarrierAppsDisabledUntilUsed == null
+ || systemCarrierAppsDisabledUntilUsed.isEmpty()) {
return null;
}
- List<ApplicationInfo> apps = new ArrayList<>(size);
- for (int i = 0; i < size; i++) {
- String packageName = systemCarrierAppsDisabledUntilUsed.valueAt(i);
+ List<ApplicationInfo> apps = new ArrayList<>(systemCarrierAppsDisabledUntilUsed.size());
+ for (String packageName : systemCarrierAppsDisabledUntilUsed) {
ApplicationInfo ai =
- getApplicationInfoIfSystemApp(packageManager, userId, packageName);
+ getApplicationInfoIfSystemApp(userId, packageName, context);
if (ai != null) {
apps.add(ai);
}
@@ -371,29 +395,28 @@ public final class CarrierAppUtils {
return apps;
}
- private static Map<String, List<ApplicationInfo>> getDefaultCarrierAssociatedAppsHelper(
- IPackageManager packageManager,
- int userId,
- ArrayMap<String, List<String>> systemCarrierAssociatedAppsDisabledUntilUsed) {
+ private static Map<String, List<AssociatedAppInfo>> getDefaultCarrierAssociatedAppsHelper(
+ int userId, Map<String, List<CarrierAssociatedAppEntry>>
+ systemCarrierAssociatedAppsDisabledUntilUsed, Context context) {
int size = systemCarrierAssociatedAppsDisabledUntilUsed.size();
- Map<String, List<ApplicationInfo>> associatedApps = new ArrayMap<>(size);
- for (int i = 0; i < size; i++) {
- String carrierAppPackage = systemCarrierAssociatedAppsDisabledUntilUsed.keyAt(i);
- List<String> associatedAppPackages =
- systemCarrierAssociatedAppsDisabledUntilUsed.valueAt(i);
+ Map<String, List<AssociatedAppInfo>> associatedApps = new ArrayMap<>(size);
+ for (Map.Entry<String, List<CarrierAssociatedAppEntry>> entry
+ : systemCarrierAssociatedAppsDisabledUntilUsed.entrySet()) {
+ String carrierAppPackage = entry.getKey();
+ List<CarrierAssociatedAppEntry> associatedAppPackages = entry.getValue();
for (int j = 0; j < associatedAppPackages.size(); j++) {
+ CarrierAssociatedAppEntry associatedApp = associatedAppPackages.get(j);
ApplicationInfo ai =
- getApplicationInfoIfSystemApp(
- packageManager, userId, associatedAppPackages.get(j));
+ getApplicationInfoIfSystemApp(userId, associatedApp.packageName, context);
// Only update enabled state for the app on /system. Once it has been updated we
// shouldn't touch it.
if (ai != null && !isUpdatedSystemApp(ai)) {
- List<ApplicationInfo> appList = associatedApps.get(carrierAppPackage);
+ List<AssociatedAppInfo> appList = associatedApps.get(carrierAppPackage);
if (appList == null) {
appList = new ArrayList<>();
associatedApps.put(carrierAppPackage, appList);
}
- appList.add(ai);
+ appList.add(new AssociatedAppInfo(ai, associatedApp.addedInSdk));
}
}
}
@@ -402,20 +425,31 @@ public final class CarrierAppUtils {
@Nullable
private static ApplicationInfo getApplicationInfoIfSystemApp(
- IPackageManager packageManager,
- int userId,
- String packageName) {
+ int userId, String packageName, Context context) {
try {
- ApplicationInfo ai = packageManager.getApplicationInfo(packageName,
- PackageManager.MATCH_DISABLED_UNTIL_USED_COMPONENTS
- | PackageManager.MATCH_HIDDEN_UNTIL_INSTALLED_COMPONENTS
- | PackageManager.MATCH_SYSTEM_ONLY, userId);
+ ApplicationInfo ai = context.createContextAsUser(UserHandle.of(userId), 0)
+ .getPackageManager()
+ .getApplicationInfo(packageName,
+ PackageManager.MATCH_DISABLED_UNTIL_USED_COMPONENTS
+ | PackageManager.MATCH_HIDDEN_UNTIL_INSTALLED_COMPONENTS
+ | PackageManager.MATCH_SYSTEM_ONLY);
if (ai != null) {
return ai;
}
- } catch (RemoteException e) {
+ } catch (PackageManager.NameNotFoundException e) {
Log.w(TAG, "Could not reach PackageManager", e);
}
return null;
}
+
+ private static final class AssociatedAppInfo {
+ public final ApplicationInfo appInfo;
+ // Might be CarrierAssociatedAppEntry.SDK_UNSPECIFIED.
+ public final int addedInSdk;
+
+ AssociatedAppInfo(ApplicationInfo appInfo, int addedInSdk) {
+ this.appInfo = appInfo;
+ this.addedInSdk = addedInSdk;
+ }
+ }
}
diff --git a/telephony/common/com/android/internal/telephony/GsmAlphabet.java b/telephony/common/com/android/internal/telephony/GsmAlphabet.java
index 60cd40094950..5c53f7e5a4d0 100644
--- a/telephony/common/com/android/internal/telephony/GsmAlphabet.java
+++ b/telephony/common/com/android/internal/telephony/GsmAlphabet.java
@@ -40,6 +40,8 @@ import java.util.List;
public class GsmAlphabet {
private static final String TAG = "GSM";
+ private GsmAlphabet() { }
+
/**
* This escapes extended characters, and when present indicates that the
* following character should be looked up in the "extended" table.
diff --git a/telephony/common/com/android/internal/telephony/SmsApplication.java b/telephony/common/com/android/internal/telephony/SmsApplication.java
index d69282579b77..b35b3236afc6 100644
--- a/telephony/common/com/android/internal/telephony/SmsApplication.java
+++ b/telephony/common/com/android/internal/telephony/SmsApplication.java
@@ -35,13 +35,11 @@ import android.content.pm.ServiceInfo;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Binder;
-import android.os.Debug;
import android.os.Process;
import android.os.UserHandle;
import android.provider.Telephony;
import android.provider.Telephony.Sms.Intents;
import android.telephony.PackageChangeReceiver;
-import android.util.Log;
import android.telephony.TelephonyManager;
import android.util.Log;
@@ -57,7 +55,6 @@ import java.util.concurrent.TimeoutException;
import java.util.function.Consumer;
import java.util.stream.Collectors;
-
/**
* Class for managing the primary application that we will deliver SMS/MMS messages to
*
@@ -197,13 +194,13 @@ public final class SmsApplication {
final int callingUid = Binder.getCallingUid();
if (DEBUG_MULTIUSER) {
Log.i(LOG_TAG, "getIncomingUserHandle caller=" + callingUid + ", myuid="
- + android.os.Process.myUid() + "\n\t" + Debug.getCallers(4));
+ + android.os.Process.myUid());
}
if (UserHandle.getAppId(callingUid)
< android.os.Process.FIRST_APPLICATION_UID) {
return contextUserId;
} else {
- return UserHandle.getUserId(callingUid);
+ return UserHandle.getUserHandleForUid(callingUid).getIdentifier();
}
}
@@ -429,9 +426,6 @@ public final class SmsApplication {
final SmsApplicationData smsApplicationData = receivers.get(packageName);
if (smsApplicationData != null) {
if (!smsApplicationData.isComplete()) {
- Log.w(LOG_TAG, "Package " + packageName
- + " lacks required manifest declarations to be a default sms app: "
- + smsApplicationData);
receivers.remove(packageName);
}
}
@@ -675,9 +669,21 @@ public final class SmsApplication {
}
/**
+ * Broadcast action:
+ * Same as {@link Intent#ACTION_DEFAULT_SMS_PACKAGE_CHANGED} but it's implicit (e.g. sent to
+ * all apps) and requires
+ * {@link #PERMISSION_MONITOR_DEFAULT_SMS_PACKAGE} to receive.
+ */
+ public static final String ACTION_DEFAULT_SMS_PACKAGE_CHANGED_INTERNAL =
+ "android.provider.action.DEFAULT_SMS_PACKAGE_CHANGED_INTERNAL";
+
+ public static final String PERMISSION_MONITOR_DEFAULT_SMS_PACKAGE =
+ "android.permission.MONITOR_DEFAULT_SMS_PACKAGE";
+
+ /**
* Sends broadcasts on sms app change:
* {@link Intent#ACTION_DEFAULT_SMS_PACKAGE_CHANGED}
- * {@link Intents.ACTION_DEFAULT_SMS_PACKAGE_CHANGED_INTERNAL}
+ * {@link #ACTION_DEFAULT_SMS_PACKAGE_CHANGED_INTERNAL}
*/
public static void broadcastSmsAppChange(Context context,
UserHandle userHandle, @Nullable String oldPackage, @Nullable String newPackage) {
@@ -727,11 +733,11 @@ public final class SmsApplication {
}
// Send an implicit broadcast for the system server.
- // (or anyone with MONITOR_DEFAULT_SMS_PACKAGE, really.)
+ // (or anyone with PERMISSION_MONITOR_DEFAULT_SMS_PACKAGE, really.)
final Intent intent =
- new Intent(Intents.ACTION_DEFAULT_SMS_PACKAGE_CHANGED_INTERNAL);
+ new Intent(ACTION_DEFAULT_SMS_PACKAGE_CHANGED_INTERNAL);
context.sendBroadcastAsUser(intent, userHandle,
- permission.MONITOR_DEFAULT_SMS_PACKAGE);
+ PERMISSION_MONITOR_DEFAULT_SMS_PACKAGE);
}
/**
@@ -816,10 +822,10 @@ public final class SmsApplication {
// This should never happen in prod -- unit tests will put the receiver into a
// unusual state where the pending result is null, which produces a NPE when calling
// getSendingUserId. Just pretend like it's the system user for testing.
- userId = UserHandle.USER_SYSTEM;
+ userId = UserHandle.SYSTEM.getIdentifier();
}
Context userContext = mContext;
- if (userId != UserHandle.USER_SYSTEM) {
+ if (userId != UserHandle.SYSTEM.getIdentifier()) {
try {
userContext = mContext.createPackageContextAsUser(mContext.getPackageName(), 0,
UserHandle.of(userId));
diff --git a/telephony/common/com/android/internal/telephony/TelephonyPermissions.java b/telephony/common/com/android/internal/telephony/TelephonyPermissions.java
index 0f53fe65463f..0c463949b14a 100644
--- a/telephony/common/com/android/internal/telephony/TelephonyPermissions.java
+++ b/telephony/common/com/android/internal/telephony/TelephonyPermissions.java
@@ -20,7 +20,6 @@ import static android.content.pm.PackageManager.PERMISSION_GRANTED;
import android.Manifest;
import android.annotation.Nullable;
import android.app.AppOpsManager;
-import android.app.admin.DevicePolicyManager;
import android.content.Context;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
@@ -28,10 +27,10 @@ import android.os.Binder;
import android.os.Build;
import android.os.Process;
import android.os.UserHandle;
+import android.permission.PermissionManager;
import android.telephony.SubscriptionManager;
import android.telephony.TelephonyManager;
import android.util.Log;
-import android.util.StatsLog;
import com.android.internal.annotations.VisibleForTesting;
@@ -157,8 +156,8 @@ public final class TelephonyPermissions {
// We have READ_PHONE_STATE permission, so return true as long as the AppOps bit hasn't been
// revoked.
AppOpsManager appOps = (AppOpsManager) context.getSystemService(Context.APP_OPS_SERVICE);
- return appOps.noteOp(AppOpsManager.OPSTR_READ_PHONE_STATE, uid, callingPackage)
- == AppOpsManager.MODE_ALLOWED;
+ return appOps.noteOp(AppOpsManager.OPSTR_READ_PHONE_STATE, uid, callingPackage,
+ callingFeatureId, null) == AppOpsManager.MODE_ALLOWED;
}
/**
@@ -210,8 +209,8 @@ public final class TelephonyPermissions {
// We have READ_PHONE_STATE permission, so return true as long as the AppOps bit hasn't been
// revoked.
AppOpsManager appOps = (AppOpsManager) context.getSystemService(Context.APP_OPS_SERVICE);
- return appOps.noteOp(AppOpsManager.OPSTR_READ_PHONE_STATE, uid, callingPackage) ==
- AppOpsManager.MODE_ALLOWED;
+ return appOps.noteOp(AppOpsManager.OPSTR_READ_PHONE_STATE, uid, callingPackage,
+ callingFeatureId, null) == AppOpsManager.MODE_ALLOWED;
}
/**
@@ -306,16 +305,6 @@ public final class TelephonyPermissions {
String message, boolean allowCarrierPrivilegeOnAnySub) {
int uid = Binder.getCallingUid();
int pid = Binder.getCallingPid();
- // Allow system and root access to the device identifiers.
- final int appId = UserHandle.getAppId(uid);
- if (appId == Process.SYSTEM_UID || appId == Process.ROOT_UID) {
- return true;
- }
- // Allow access to packages that have the READ_PRIVILEGED_PHONE_STATE permission.
- if (context.checkPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE, pid,
- uid) == PackageManager.PERMISSION_GRANTED) {
- return true;
- }
// If the calling package has carrier privileges for specified sub, then allow access.
if (checkCarrierPrivilegeForSubId(context, subId)) return true;
@@ -326,30 +315,13 @@ public final class TelephonyPermissions {
return true;
}
- // if the calling package is not null then perform the DevicePolicyManager device /
- // profile owner and Appop checks.
- if (callingPackage != null) {
- // Allow access to an app that has been granted the READ_DEVICE_IDENTIFIERS app op.
- long token = Binder.clearCallingIdentity();
- AppOpsManager appOpsManager = (AppOpsManager) context.getSystemService(
- Context.APP_OPS_SERVICE);
- try {
- if (appOpsManager.noteOpNoThrow(AppOpsManager.OPSTR_READ_DEVICE_IDENTIFIERS, uid,
- callingPackage) == AppOpsManager.MODE_ALLOWED) {
- return true;
- }
- } finally {
- Binder.restoreCallingIdentity(token);
- }
- // Allow access to a device / profile owner app.
- DevicePolicyManager devicePolicyManager =
- (DevicePolicyManager) context.getSystemService(
- Context.DEVICE_POLICY_SERVICE);
- if (devicePolicyManager != null && devicePolicyManager.checkDeviceIdentifierAccess(
- callingPackage, pid, uid)) {
- return true;
- }
+ PermissionManager permissionManager = (PermissionManager) context.getSystemService(
+ Context.PERMISSION_SERVICE);
+ if (permissionManager.checkDeviceIdentifierAccess(callingPackage, message, callingFeatureId,
+ pid, uid) == PackageManager.PERMISSION_GRANTED) {
+ return true;
}
+
return reportAccessDeniedToReadIdentifiers(context, subId, pid, uid, callingPackage,
message);
}
@@ -366,16 +338,10 @@ public final class TelephonyPermissions {
*/
private static boolean reportAccessDeniedToReadIdentifiers(Context context, int subId, int pid,
int uid, String callingPackage, String message) {
- boolean isPreinstalled = false;
ApplicationInfo callingPackageInfo = null;
try {
callingPackageInfo = context.getPackageManager().getApplicationInfoAsUser(
callingPackage, 0, UserHandle.getUserHandleForUid(uid));
- if (callingPackageInfo != null) {
- if (callingPackageInfo.isSystemApp()) {
- isPreinstalled = true;
- }
- }
} catch (PackageManager.NameNotFoundException e) {
// If the application info for the calling package could not be found then assume the
// calling app is a non-preinstalled app to detect any issues with the check
@@ -395,11 +361,11 @@ public final class TelephonyPermissions {
invokedMethods = sReportedDeviceIDPackages.get(callingPackage);
}
invokedMethods.add(message);
- StatsLog.write(StatsLog.DEVICE_IDENTIFIER_ACCESS_DENIED, callingPackage, message,
- isPreinstalled, false);
+ TelephonyCommonStatsLog.write(TelephonyCommonStatsLog.DEVICE_IDENTIFIER_ACCESS_DENIED,
+ callingPackage, message, /* isPreinstalled= */ false, false);
}
- Log.w(LOG_TAG, "reportAccessDeniedToReadIdentifiers:" + callingPackage + ":" + message
- + ":isPreinstalled=" + isPreinstalled);
+ Log.w(LOG_TAG, "reportAccessDeniedToReadIdentifiers:" + callingPackage + ":" + message + ":"
+ + subId);
// if the target SDK is pre-Q then check if the calling package would have previously
// had access to device identifiers.
if (callingPackageInfo != null && (
@@ -440,8 +406,8 @@ public final class TelephonyPermissions {
// We have READ_CALL_LOG permission, so return true as long as the AppOps bit hasn't been
// revoked.
AppOpsManager appOps = (AppOpsManager) context.getSystemService(Context.APP_OPS_SERVICE);
- return appOps.noteOp(AppOpsManager.OPSTR_READ_CALL_LOG, uid, callingPackage) ==
- AppOpsManager.MODE_ALLOWED;
+ return appOps.noteOp(AppOpsManager.OPSTR_READ_CALL_LOG, uid, callingPackage,
+ callingPackageName, null) == AppOpsManager.MODE_ALLOWED;
}
/**
@@ -470,16 +436,6 @@ public final class TelephonyPermissions {
public static boolean checkReadPhoneNumber(
Context context, int subId, int pid, int uid,
String callingPackage, @Nullable String callingFeatureId, String message) {
- // Default SMS app can always read it.
- AppOpsManager appOps = (AppOpsManager) context.getSystemService(Context.APP_OPS_SERVICE);
- if (appOps.noteOp(AppOpsManager.OPSTR_WRITE_SMS, uid, callingPackage) ==
- AppOpsManager.MODE_ALLOWED) {
- return true;
- }
-
- // NOTE(b/73308711): If an app has one of the following AppOps bits explicitly revoked, they
- // will be denied access, even if they have another permission and AppOps bit if needed.
-
// First, check if the SDK version is below R
boolean preR = false;
try {
@@ -514,21 +470,29 @@ public final class TelephonyPermissions {
}
}
+ // Default SMS app can always read it.
+ AppOpsManager appOps = (AppOpsManager) context.getSystemService(Context.APP_OPS_SERVICE);
+ if (appOps.noteOp(AppOpsManager.OPSTR_WRITE_SMS, uid, callingPackage, callingFeatureId,
+ null) == AppOpsManager.MODE_ALLOWED) {
+ return true;
+ }
// Can be read with READ_SMS too.
try {
context.enforcePermission(android.Manifest.permission.READ_SMS, pid, uid, message);
- return appOps.noteOp(AppOpsManager.OPSTR_READ_SMS, uid, callingPackage)
- == AppOpsManager.MODE_ALLOWED;
-
+ if (appOps.noteOp(AppOpsManager.OPSTR_READ_SMS, uid, callingPackage,
+ callingFeatureId, null) == AppOpsManager.MODE_ALLOWED) {
+ return true;
+ }
} catch (SecurityException readSmsSecurityException) {
}
// Can be read with READ_PHONE_NUMBERS too.
try {
context.enforcePermission(android.Manifest.permission.READ_PHONE_NUMBERS, pid, uid,
message);
- return appOps.noteOp(AppOpsManager.OPSTR_READ_PHONE_NUMBERS, uid, callingPackage)
- == AppOpsManager.MODE_ALLOWED;
-
+ if (appOps.noteOp(AppOpsManager.OPSTR_READ_PHONE_NUMBERS, uid, callingPackage,
+ callingFeatureId, null) == AppOpsManager.MODE_ALLOWED) {
+ return true;
+ }
} catch (SecurityException readPhoneNumberSecurityException) {
}
diff --git a/telephony/common/com/android/internal/telephony/util/TelephonyUtils.java b/telephony/common/com/android/internal/telephony/util/TelephonyUtils.java
index ec1c6c90905a..682697469af9 100644
--- a/telephony/common/com/android/internal/telephony/util/TelephonyUtils.java
+++ b/telephony/common/com/android/internal/telephony/util/TelephonyUtils.java
@@ -30,6 +30,8 @@ import android.os.SystemProperties;
import java.io.PrintWriter;
import java.util.Collections;
import java.util.List;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
import java.util.function.Supplier;
/**
@@ -144,4 +146,12 @@ public final class TelephonyUtils {
}
return ret;
}
+
+ /** Wait for latch to trigger */
+ public static void waitUntilReady(CountDownLatch latch, long timeoutMs) {
+ try {
+ latch.await(timeoutMs, TimeUnit.MILLISECONDS);
+ } catch (InterruptedException ignored) {
+ }
+ }
}