diff options
Diffstat (limited to 'core/java')
| -rw-r--r-- | core/java/android/app/backup/BackupAgent.java | 18 | ||||
| -rw-r--r-- | core/java/android/app/usage/UsageStatsManagerInternal.java | 7 | ||||
| -rw-r--r-- | core/java/android/content/pm/PermissionInfo.java | 7 | ||||
| -rw-r--r-- | core/java/android/net/ConnectivityManager.java | 5 | ||||
| -rw-r--r-- | core/java/android/net/NetworkScorerAppManager.java | 16 | ||||
| -rw-r--r-- | core/java/android/os/IDeviceIdleController.aidl | 4 | ||||
| -rw-r--r-- | core/java/android/provider/Settings.java | 141 | ||||
| -rw-r--r-- | core/java/android/util/SparseIntArray.java | 8 | ||||
| -rw-r--r-- | core/java/android/webkit/WebViewFactory.java | 6 |
9 files changed, 179 insertions, 33 deletions
diff --git a/core/java/android/app/backup/BackupAgent.java b/core/java/android/app/backup/BackupAgent.java index 6fca0de..689283c 100644 --- a/core/java/android/app/backup/BackupAgent.java +++ b/core/java/android/app/backup/BackupAgent.java @@ -605,6 +605,13 @@ public abstract class BackupAgent extends ContextWrapper { public void onRestoreFile(ParcelFileDescriptor data, long size, File destination, int type, long mode, long mtime) throws IOException { + + final boolean accept = isFileEligibleForRestore(destination); + // If we don't accept the file, consume the bytes from the pipe anyway. + FullBackup.restoreFile(data, size, type, mode, mtime, accept ? destination : null); + } + + private boolean isFileEligibleForRestore(File destination) throws IOException { FullBackup.BackupScheme bs = FullBackup.getBackupScheme(this); if (!bs.isFullBackupContentEnabled()) { if (Log.isLoggable(FullBackup.TAG_XML_PARSER, Log.VERBOSE)) { @@ -612,8 +619,9 @@ public abstract class BackupAgent extends ContextWrapper { "onRestoreFile \"" + destination.getCanonicalPath() + "\" : fullBackupContent not enabled for " + getPackageName()); } - return; + return false; } + Map<String, Set<String>> includes = null; ArraySet<String> excludes = null; final String destinationCanonicalPath = destination.getCanonicalPath(); @@ -627,7 +635,7 @@ public abstract class BackupAgent extends ContextWrapper { + "\" : Exception trying to parse fullBackupContent xml file!" + " Aborting onRestoreFile.", e); } - return; + return false; } if (excludes != null && @@ -637,7 +645,7 @@ public abstract class BackupAgent extends ContextWrapper { "onRestoreFile: \"" + destinationCanonicalPath + "\": listed in" + " excludes; skipping."); } - return; + return false; } if (includes != null && !includes.isEmpty()) { @@ -657,10 +665,10 @@ public abstract class BackupAgent extends ContextWrapper { + destinationCanonicalPath + "\" but it isn't specified" + " in the included files; skipping."); } - return; + return false; } } - FullBackup.restoreFile(data, size, type, mode, mtime, destination); + return true; } /** diff --git a/core/java/android/app/usage/UsageStatsManagerInternal.java b/core/java/android/app/usage/UsageStatsManagerInternal.java index 9113426..948ea1e 100644 --- a/core/java/android/app/usage/UsageStatsManagerInternal.java +++ b/core/java/android/app/usage/UsageStatsManagerInternal.java @@ -77,6 +77,13 @@ public abstract class UsageStatsManagerInternal { public abstract boolean isAppIdle(String packageName, int userId); /** + * Returns all of the uids for a given user where all packages associating with that uid + * are in the app idle state -- there are no associated apps that are not idle. This means + * all of the returned uids can be safely considered app idle. + */ + public abstract int[] getIdleUidsForUser(int userId); + + /** * @return True if currently app idle parole mode is on. This means all idle apps are allow to * run for a short period of time. */ diff --git a/core/java/android/content/pm/PermissionInfo.java b/core/java/android/content/pm/PermissionInfo.java index d514513..9da2ba9 100644 --- a/core/java/android/content/pm/PermissionInfo.java +++ b/core/java/android/content/pm/PermissionInfo.java @@ -145,6 +145,13 @@ public class PermissionInfo extends PackageItemInfo implements Parcelable { public static final int FLAG_COSTS_MONEY = 1<<0; /** + * Flag for {@link #flags}, corresponding to <code>hidden</code> + * value of {@link android.R.attr#permissionFlags}. + * @hide + */ + public static final int FLAG_HIDDEN = 1<<1; + + /** * Flag for {@link #flags}, indicating that this permission has been * installed into the system's globally defined permissions. */ diff --git a/core/java/android/net/ConnectivityManager.java b/core/java/android/net/ConnectivityManager.java index 605acb0..ff6dd32 100644 --- a/core/java/android/net/ConnectivityManager.java +++ b/core/java/android/net/ConnectivityManager.java @@ -1414,8 +1414,9 @@ public class ConnectivityManager { context.enforceCallingOrSelfPermission( android.Manifest.permission.CONNECTIVITY_INTERNAL, "ConnectivityService"); } else { - context.enforceCallingOrSelfPermission( - android.Manifest.permission.CHANGE_NETWORK_STATE, "ConnectivityService"); + int uid = Binder.getCallingUid(); + Settings.checkAndNoteChangeNetworkStateOperation(context, uid, Settings + .getPackageNameForUid(context, uid), true); } } diff --git a/core/java/android/net/NetworkScorerAppManager.java b/core/java/android/net/NetworkScorerAppManager.java index 46f7194..29daf35 100644 --- a/core/java/android/net/NetworkScorerAppManager.java +++ b/core/java/android/net/NetworkScorerAppManager.java @@ -23,6 +23,7 @@ import android.app.AppOpsManager; import android.content.Context; import android.content.Intent; import android.content.pm.ActivityInfo; +import android.content.pm.ApplicationInfo; import android.content.pm.PackageManager; import android.content.pm.ResolveInfo; import android.os.UserHandle; @@ -54,6 +55,9 @@ public final class NetworkScorerAppManager { /** Package name of this scorer app. */ public final String mPackageName; + /** UID of the scorer app. */ + public final int mPackageUid; + /** Name of this scorer app for display. */ public final CharSequence mScorerName; @@ -64,10 +68,11 @@ public final class NetworkScorerAppManager { */ public final String mConfigurationActivityClassName; - public NetworkScorerAppData(String packageName, CharSequence scorerName, + public NetworkScorerAppData(String packageName, int packageUid, CharSequence scorerName, @Nullable String configurationActivityClassName) { mScorerName = scorerName; mPackageName = packageName; + mPackageUid = packageUid; mConfigurationActivityClassName = configurationActivityClassName; } } @@ -125,7 +130,8 @@ public final class NetworkScorerAppManager { // NOTE: loadLabel will attempt to load the receiver's label and fall back to the app // label if none is present. scorers.add(new NetworkScorerAppData(receiverInfo.packageName, - receiverInfo.loadLabel(pm), configurationActivityClassName)); + receiverInfo.applicationInfo.uid, receiverInfo.loadLabel(pm), + configurationActivityClassName)); } return scorers; @@ -187,13 +193,9 @@ public final class NetworkScorerAppManager { if (defaultApp == null) { return false; } - AppOpsManager appOpsMgr = (AppOpsManager) context.getSystemService(Context.APP_OPS_SERVICE); - try { - appOpsMgr.checkPackage(callingUid, defaultApp.mPackageName); - } catch (SecurityException e) { + if (callingUid != defaultApp.mPackageUid) { return false; } - // To be extra safe, ensure the caller holds the SCORE_NETWORKS permission. It always // should, since it couldn't become the active scorer otherwise, but this can't hurt. return context.checkCallingPermission(Manifest.permission.SCORE_NETWORKS) == diff --git a/core/java/android/os/IDeviceIdleController.aidl b/core/java/android/os/IDeviceIdleController.aidl index d3eec1e..f55883a 100644 --- a/core/java/android/os/IDeviceIdleController.aidl +++ b/core/java/android/os/IDeviceIdleController.aidl @@ -22,10 +22,14 @@ import android.os.UserHandle; interface IDeviceIdleController { void addPowerSaveWhitelistApp(String name); void removePowerSaveWhitelistApp(String name); + String[] getSystemPowerWhitelistExceptIdle(); String[] getSystemPowerWhitelist(); + String[] getFullPowerWhitelistExceptIdle(); String[] getFullPowerWhitelist(); + int[] getAppIdWhitelistExceptIdle(); int[] getAppIdWhitelist(); int[] getAppIdTempWhitelist(); + boolean isPowerSaveWhitelistExceptIdleApp(String name); boolean isPowerSaveWhitelistApp(String name); void addPowerSaveTempWhitelistApp(String name, long duration, int userId, String reason); long addPowerSaveTempWhitelistAppForMms(String name, int userId, String reason); diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java index bb09b05..fe95864 100644 --- a/core/java/android/provider/Settings.java +++ b/core/java/android/provider/Settings.java @@ -616,20 +616,46 @@ public final class Settings { /** * Activity Action: Show screen for controlling which apps can ignore battery optimizations. * <p> - * Input: Optionally, the Intent's data URI specifies the application package name - * to be shown, with the "package" scheme. That is "package:com.my.app". + * Input: Nothing. * <p> * Output: Nothing. * <p> * You can use {@link android.os.PowerManager#isIgnoringBatteryOptimizations * PowerManager.isIgnoringBatteryOptimizations()} to determine if an application is - * already ignoring optimizations. + * already ignoring optimizations. You can use + * {@link #ACTION_REQUEST_IGNORE_BATTERY_OPTIMIZATIONS} to ask the user to put you + * on this list. */ @SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION) public static final String ACTION_IGNORE_BATTERY_OPTIMIZATION_SETTINGS = "android.settings.IGNORE_BATTERY_OPTIMIZATION_SETTINGS"; /** + * Activity Action: Ask the user to allow an to ignore battery optimizations (that is, + * put them on the whitelist of apps shown by + * {@link #ACTION_IGNORE_BATTERY_OPTIMIZATION_SETTINGS}). For an app to use this, it also + * must hold the {@link android.Manifest.permission#REQUEST_IGNORE_BATTERY_OPTIMIZATIONS} + * permission. + * <p><b>Note:</b> most applications should <em>not</em> use this; there are many facilities + * provided by the platform for applications to operate correctly in the various power + * saving mode. This is only for unusual applications that need to deeply control their own + * execution, at the potential expense of the user's battery life. Note that these applications + * greatly run the risk of showing to the user has how power consumers on their device.</p> + * <p> + * Input: The Intent's data URI must specify the application package name + * to be shown, with the "package" scheme. That is "package:com.my.app". + * <p> + * Output: Nothing. + * <p> + * You can use {@link android.os.PowerManager#isIgnoringBatteryOptimizations + * PowerManager.isIgnoringBatteryOptimizations()} to determine if an application is + * already ignoring optimizations. + */ + @SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION) + public static final String ACTION_REQUEST_IGNORE_BATTERY_OPTIMIZATIONS = + "android.settings.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS"; + + /** * @hide * Activity Action: Show the "app ops" settings screen. * <p> @@ -1408,6 +1434,25 @@ public final class Settings { } /** + * An app can use this method to check if it is currently allowed to change the network + * state. In order to be allowed to do so, an app must first declare either the + * {@link android.Manifest.permission#CHANGE_NETWORK_STATE} or + * {@link android.Manifest.permission#WRITE_SETTINGS} permission in its manifest. If it + * is currently disallowed, it can prompt the user to grant it this capability through a + * management UI by sending an Intent with action + * {@link android.provider.Settings#ACTION_MANAGE_WRITE_SETTINGS}. + * + * @param context A context + * @return true if the calling app can change the state of network, false otherwise. + * @hide + */ + public static boolean canChangeNetworkState(Context context) { + int uid = Binder.getCallingUid(); + return Settings.isCallingPackageAllowedToChangeNetworkState(context, uid, Settings + .getPackageNameForUid(context, uid), false); + } + + /** * System settings, containing miscellaneous system preferences. This * table holds simple name/value pairs. There are convenience * functions for accessing individual settings entries. @@ -8252,6 +8297,17 @@ public final class Settings { return "android-" + Long.toHexString(androidId); } + private static final String[] PM_WRITE_SETTINGS = { + android.Manifest.permission.WRITE_SETTINGS + }; + private static final String[] PM_CHANGE_NETWORK_STATE = { + android.Manifest.permission.CHANGE_NETWORK_STATE, + android.Manifest.permission.WRITE_SETTINGS + }; + private static final String[] PM_SYSTEM_ALERT_WINDOW = { + android.Manifest.permission.SYSTEM_ALERT_WINDOW + }; + /** * Performs a strict and comprehensive check of whether a calling package is allowed to * write/modify system settings, as the condition differs for pre-M, M+, and @@ -8263,14 +8319,15 @@ public final class Settings { String callingPackage, boolean throwException) { return isCallingPackageAllowedToPerformAppOpsProtectedOperation(context, uid, callingPackage, throwException, AppOpsManager.OP_WRITE_SETTINGS, - android.Manifest.permission.WRITE_SETTINGS, false); + PM_WRITE_SETTINGS, false); } /** * Performs a strict and comprehensive check of whether a calling package is allowed to * write/modify system settings, as the condition differs for pre-M, M+, and * privileged/preinstalled apps. If the provided uid does not match the - * callingPackage, a negative result will be returned. + * callingPackage, a negative result will be returned. The caller is expected to have + * either WRITE_SETTINGS or CHANGE_NETWORK_STATE permission declared. * * Note: if the check is successful, the operation of this app will be updated to the * current time. @@ -8280,7 +8337,40 @@ public final class Settings { String callingPackage, boolean throwException) { return isCallingPackageAllowedToPerformAppOpsProtectedOperation(context, uid, callingPackage, throwException, AppOpsManager.OP_WRITE_SETTINGS, - android.Manifest.permission.WRITE_SETTINGS, true); + PM_WRITE_SETTINGS, true); + } + + /** + * Performs a strict and comprehensive check of whether a calling package is allowed to + * change the state of network, as the condition differs for pre-M, M+, and + * privileged/preinstalled apps. If the provided uid does not match the + * callingPackage, a negative result will be returned. The caller is expected to have + * either of CHANGE_NETWORK_STATE or WRITE_SETTINGS permission declared. + * @hide + */ + public static boolean isCallingPackageAllowedToChangeNetworkState(Context context, int uid, + String callingPackage, boolean throwException) { + return isCallingPackageAllowedToPerformAppOpsProtectedOperation(context, uid, + callingPackage, throwException, AppOpsManager.OP_WRITE_SETTINGS, + PM_CHANGE_NETWORK_STATE, false); + } + + /** + * Performs a strict and comprehensive check of whether a calling package is allowed to + * change the state of network, as the condition differs for pre-M, M+, and + * privileged/preinstalled apps. If the provided uid does not match the + * callingPackage, a negative result will be returned. The caller is expected to have + * either CHANGE_NETWORK_STATE or WRITE_SETTINGS permission declared. + * + * Note: if the check is successful, the operation of this app will be updated to the + * current time. + * @hide + */ + public static boolean checkAndNoteChangeNetworkStateOperation(Context context, int uid, + String callingPackage, boolean throwException) { + return isCallingPackageAllowedToPerformAppOpsProtectedOperation(context, uid, + callingPackage, throwException, AppOpsManager.OP_WRITE_SETTINGS, + PM_CHANGE_NETWORK_STATE, true); } /** @@ -8294,7 +8384,7 @@ public final class Settings { String callingPackage, boolean throwException) { return isCallingPackageAllowedToPerformAppOpsProtectedOperation(context, uid, callingPackage, throwException, AppOpsManager.OP_SYSTEM_ALERT_WINDOW, - android.Manifest.permission.SYSTEM_ALERT_WINDOW, false); + PM_SYSTEM_ALERT_WINDOW, false); } /** @@ -8311,7 +8401,7 @@ public final class Settings { callingPackage, boolean throwException) { return isCallingPackageAllowedToPerformAppOpsProtectedOperation(context, uid, callingPackage, throwException, AppOpsManager.OP_SYSTEM_ALERT_WINDOW, - android.Manifest.permission.SYSTEM_ALERT_WINDOW, true); + PM_SYSTEM_ALERT_WINDOW, true); } /** @@ -8321,8 +8411,8 @@ public final class Settings { * @hide */ public static boolean isCallingPackageAllowedToPerformAppOpsProtectedOperation(Context context, - int uid, String callingPackage, boolean throwException, int appOpsOpCode, String - permissionName, boolean makeNote) { + int uid, String callingPackage, boolean throwException, int appOpsOpCode, String[] + permissions, boolean makeNote) { if (callingPackage == null) { return false; } @@ -8338,20 +8428,41 @@ public final class Settings { switch (mode) { case AppOpsManager.MODE_ALLOWED: return true; + case AppOpsManager.MODE_DEFAULT: // this is the default operating mode after an app's installation - if(context.checkCallingOrSelfPermission(permissionName) == PackageManager - .PERMISSION_GRANTED) { - return true; + // In this case we will check all associated static permission to see + // if it is granted during install time. + for (String permission : permissions) { + if (context.checkCallingOrSelfPermission(permission) == PackageManager + .PERMISSION_GRANTED) { + // if either of the permissions are granted, we will allow it + return true; + } } + default: // this is for all other cases trickled down here... if (!throwException) { return false; } } - throw new SecurityException(callingPackage + " was not granted " - + permissionName + " permission"); + + // prepare string to throw SecurityException + StringBuilder exceptionMessage = new StringBuilder(); + exceptionMessage.append(callingPackage); + exceptionMessage.append(" was not granted "); + if (permissions.length > 1) { + exceptionMessage.append(" either of these permissions: "); + } else { + exceptionMessage.append(" this permission: "); + } + for (int i = 0; i < permissions.length; i++) { + exceptionMessage.append(permissions[i]); + exceptionMessage.append((i == permissions.length - 1) ? "." : ", "); + } + + throw new SecurityException(exceptionMessage.toString()); } /** diff --git a/core/java/android/util/SparseIntArray.java b/core/java/android/util/SparseIntArray.java index 2b85a21..e5c729d 100644 --- a/core/java/android/util/SparseIntArray.java +++ b/core/java/android/util/SparseIntArray.java @@ -184,6 +184,14 @@ public class SparseIntArray implements Cloneable { } /** + * Directly set the value at a particular index. + * @hide + */ + public void setValueAt(int index, int value) { + mValues[index] = value; + } + + /** * Returns the index for which {@link #keyAt} would return the * specified key, or a negative number if the specified * key is not mapped. diff --git a/core/java/android/webkit/WebViewFactory.java b/core/java/android/webkit/WebViewFactory.java index 3b9aca8..584deff 100644 --- a/core/java/android/webkit/WebViewFactory.java +++ b/core/java/android/webkit/WebViewFactory.java @@ -314,8 +314,7 @@ public final class WebViewFactory { if (path.contains("!/")) { String[] split = TextUtils.split(path, "!/"); if (split.length == 2) { - try { - ZipFile z = new ZipFile(split[0]); + try (ZipFile z = new ZipFile(split[0])) { ZipEntry e = z.getEntry(split[1]); if (e != null && e.getMethod() == ZipEntry.STORED) { newVmSize = Math.max(newVmSize, e.getSize()); @@ -355,8 +354,7 @@ public final class WebViewFactory { String[] abiList, String nativeLibFileName) { // Search the APK for a native library conforming to a listed ABI. - try { - ZipFile z = new ZipFile(apkPath); + try (ZipFile z = new ZipFile(apkPath)) { for (String abi : abiList) { final String entry = "lib/" + abi + "/" + nativeLibFileName; ZipEntry e = z.getEntry(entry); |
