summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--cmds/pm/src/com/android/commands/pm/Pm.java25
-rw-r--r--core/java/android/content/pm/IPackageManager.aidl2
-rw-r--r--core/java/android/hardware/camera2/CaptureRequest.java17
-rw-r--r--core/java/android/hardware/camera2/CaptureResult.java17
-rw-r--r--core/java/android/service/notification/NotificationListenerService.java4
-rw-r--r--core/java/android/view/View.java12
-rw-r--r--core/java/android/view/ViewGroup.java6
-rw-r--r--core/res/AndroidManifest.xml4
-rw-r--r--libs/hwui/Outline.h6
-rw-r--r--libs/hwui/RenderProperties.h2
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java3
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/policy/SecurityControllerImpl.java19
-rw-r--r--services/core/java/com/android/server/pm/DefaultPermissionGrantPolicy.java37
-rw-r--r--services/core/java/com/android/server/pm/PackageManagerService.java43
-rw-r--r--services/core/java/com/android/server/pm/PermissionsState.java18
-rw-r--r--services/core/java/com/android/server/pm/Settings.java98
16 files changed, 255 insertions, 58 deletions
diff --git a/cmds/pm/src/com/android/commands/pm/Pm.java b/cmds/pm/src/com/android/commands/pm/Pm.java
index 2be44bc..ce83caa 100644
--- a/cmds/pm/src/com/android/commands/pm/Pm.java
+++ b/cmds/pm/src/com/android/commands/pm/Pm.java
@@ -204,6 +204,10 @@ public final class Pm {
return runGrantRevokePermission(false);
}
+ if ("reset-permissions".equals(op)) {
+ return runResetPermissions();
+ }
+
if ("set-permission-enforced".equals(op)) {
return runSetPermissionEnforced();
}
@@ -1636,6 +1640,24 @@ public final class Pm {
}
}
+ private int runResetPermissions() {
+ try {
+ mPm.resetRuntimePermissions();
+ return 0;
+ } catch (RemoteException e) {
+ System.err.println(e.toString());
+ System.err.println(PM_NOT_RUNNING_ERR);
+ return 1;
+ } catch (IllegalArgumentException e) {
+ System.err.println("Bad argument: " + e.toString());
+ showUsage();
+ return 1;
+ } catch (SecurityException e) {
+ System.err.println("Operation not allowed: " + e.toString());
+ return 1;
+ }
+ }
+
private int runSetPermissionEnforced() {
final String permission = nextArg();
if (permission == null) {
@@ -1911,6 +1933,7 @@ public final class Pm {
System.err.println(" pm unhide [--user USER_ID] PACKAGE_OR_COMPONENT");
System.err.println(" pm grant [--user USER_ID] PACKAGE PERMISSION");
System.err.println(" pm revoke [--user USER_ID] PACKAGE PERMISSION");
+ System.err.println(" pm reset-permissions");
System.err.println(" pm set-install-location [0/auto] [1/internal] [2/external]");
System.err.println(" pm get-install-location");
System.err.println(" pm set-permission-enforced PERMISSION [true|false]");
@@ -1988,6 +2011,8 @@ public final class Pm {
System.err.println(" manifest, be runtime permissions (protection level dangerous),");
System.err.println(" and the app targeting SDK greater than Lollipop MR1.");
System.err.println("");
+ System.err.println("pm reset-permissions: revert all runtime permissions to their default state.");
+ System.err.println("");
System.err.println("pm get-install-location: returns the current install location.");
System.err.println(" 0 [auto]: Let system decide the best location");
System.err.println(" 1 [internal]: Install on internal device storage");
diff --git a/core/java/android/content/pm/IPackageManager.aidl b/core/java/android/content/pm/IPackageManager.aidl
index c9853df..cea6e99 100644
--- a/core/java/android/content/pm/IPackageManager.aidl
+++ b/core/java/android/content/pm/IPackageManager.aidl
@@ -102,6 +102,8 @@ interface IPackageManager {
void revokeRuntimePermission(String packageName, String permissionName, int userId);
+ void resetRuntimePermissions();
+
int getPermissionFlags(String permissionName, String packageName, int userId);
void updatePermissionFlags(String permissionName, String packageName, int flagMask,
diff --git a/core/java/android/hardware/camera2/CaptureRequest.java b/core/java/android/hardware/camera2/CaptureRequest.java
index 75289f7..33cc962 100644
--- a/core/java/android/hardware/camera2/CaptureRequest.java
+++ b/core/java/android/hardware/camera2/CaptureRequest.java
@@ -1062,6 +1062,15 @@ public final class CaptureRequest extends CameraMetadata<CaptureRequest.Key<?>>
* capturing a high-resolution JPEG image will automatically trigger a
* precapture sequence before the high-resolution capture, including
* potentially firing a pre-capture flash.</p>
+ * <p>Using the precapture trigger and the auto-focus trigger {@link CaptureRequest#CONTROL_AF_TRIGGER android.control.afTrigger}
+ * simultaneously is allowed. However, since these triggers often require cooperation between
+ * the auto-focus and auto-exposure routines (for example, the may need to be enabled for a
+ * focus sweep), the camera device may delay acting on a later trigger until the previous
+ * trigger has been fully handled. This may lead to longer intervals between the trigger and
+ * changes to {@link CaptureResult#CONTROL_AE_STATE android.control.aeState} indicating the start of the precapture sequence, for
+ * example.</p>
+ * <p>If both the precapture and the auto-focus trigger are activated on the same request, then
+ * the camera device will complete them in the optimal order for that device.</p>
* <p><b>Possible values:</b>
* <ul>
* <li>{@link #CONTROL_AE_PRECAPTURE_TRIGGER_IDLE IDLE}</li>
@@ -1075,6 +1084,7 @@ public final class CaptureRequest extends CameraMetadata<CaptureRequest.Key<?>>
*
* @see CaptureRequest#CONTROL_AE_LOCK
* @see CaptureResult#CONTROL_AE_STATE
+ * @see CaptureRequest#CONTROL_AF_TRIGGER
* @see CaptureRequest#CONTROL_CAPTURE_INTENT
* @see CameraCharacteristics#INFO_SUPPORTED_HARDWARE_LEVEL
* @see #CONTROL_AE_PRECAPTURE_TRIGGER_IDLE
@@ -1179,6 +1189,12 @@ public final class CaptureRequest extends CameraMetadata<CaptureRequest.Key<?>>
* START for multiple captures in a row means restarting the AF operation over
* and over again.</p>
* <p>See {@link CaptureResult#CONTROL_AF_STATE android.control.afState} for what the trigger means for each AF mode.</p>
+ * <p>Using the autofocus trigger and the precapture trigger {@link CaptureRequest#CONTROL_AE_PRECAPTURE_TRIGGER android.control.aePrecaptureTrigger}
+ * simultaneously is allowed. However, since these triggers often require cooperation between
+ * the auto-focus and auto-exposure routines (for example, the may need to be enabled for a
+ * focus sweep), the camera device may delay acting on a later trigger until the previous
+ * trigger has been fully handled. This may lead to longer intervals between the trigger and
+ * changes to {@link CaptureResult#CONTROL_AF_STATE android.control.afState}, for example.</p>
* <p><b>Possible values:</b>
* <ul>
* <li>{@link #CONTROL_AF_TRIGGER_IDLE IDLE}</li>
@@ -1187,6 +1203,7 @@ public final class CaptureRequest extends CameraMetadata<CaptureRequest.Key<?>>
* </ul></p>
* <p>This key is available on all devices.</p>
*
+ * @see CaptureRequest#CONTROL_AE_PRECAPTURE_TRIGGER
* @see CaptureResult#CONTROL_AF_STATE
* @see #CONTROL_AF_TRIGGER_IDLE
* @see #CONTROL_AF_TRIGGER_START
diff --git a/core/java/android/hardware/camera2/CaptureResult.java b/core/java/android/hardware/camera2/CaptureResult.java
index 1d31109..9dee045 100644
--- a/core/java/android/hardware/camera2/CaptureResult.java
+++ b/core/java/android/hardware/camera2/CaptureResult.java
@@ -779,6 +779,15 @@ public class CaptureResult extends CameraMetadata<CaptureResult.Key<?>> {
* capturing a high-resolution JPEG image will automatically trigger a
* precapture sequence before the high-resolution capture, including
* potentially firing a pre-capture flash.</p>
+ * <p>Using the precapture trigger and the auto-focus trigger {@link CaptureRequest#CONTROL_AF_TRIGGER android.control.afTrigger}
+ * simultaneously is allowed. However, since these triggers often require cooperation between
+ * the auto-focus and auto-exposure routines (for example, the may need to be enabled for a
+ * focus sweep), the camera device may delay acting on a later trigger until the previous
+ * trigger has been fully handled. This may lead to longer intervals between the trigger and
+ * changes to {@link CaptureResult#CONTROL_AE_STATE android.control.aeState} indicating the start of the precapture sequence, for
+ * example.</p>
+ * <p>If both the precapture and the auto-focus trigger are activated on the same request, then
+ * the camera device will complete them in the optimal order for that device.</p>
* <p><b>Possible values:</b>
* <ul>
* <li>{@link #CONTROL_AE_PRECAPTURE_TRIGGER_IDLE IDLE}</li>
@@ -792,6 +801,7 @@ public class CaptureResult extends CameraMetadata<CaptureResult.Key<?>> {
*
* @see CaptureRequest#CONTROL_AE_LOCK
* @see CaptureResult#CONTROL_AE_STATE
+ * @see CaptureRequest#CONTROL_AF_TRIGGER
* @see CaptureRequest#CONTROL_CAPTURE_INTENT
* @see CameraCharacteristics#INFO_SUPPORTED_HARDWARE_LEVEL
* @see #CONTROL_AE_PRECAPTURE_TRIGGER_IDLE
@@ -1139,6 +1149,12 @@ public class CaptureResult extends CameraMetadata<CaptureResult.Key<?>> {
* START for multiple captures in a row means restarting the AF operation over
* and over again.</p>
* <p>See {@link CaptureResult#CONTROL_AF_STATE android.control.afState} for what the trigger means for each AF mode.</p>
+ * <p>Using the autofocus trigger and the precapture trigger {@link CaptureRequest#CONTROL_AE_PRECAPTURE_TRIGGER android.control.aePrecaptureTrigger}
+ * simultaneously is allowed. However, since these triggers often require cooperation between
+ * the auto-focus and auto-exposure routines (for example, the may need to be enabled for a
+ * focus sweep), the camera device may delay acting on a later trigger until the previous
+ * trigger has been fully handled. This may lead to longer intervals between the trigger and
+ * changes to {@link CaptureResult#CONTROL_AF_STATE android.control.afState}, for example.</p>
* <p><b>Possible values:</b>
* <ul>
* <li>{@link #CONTROL_AF_TRIGGER_IDLE IDLE}</li>
@@ -1147,6 +1163,7 @@ public class CaptureResult extends CameraMetadata<CaptureResult.Key<?>> {
* </ul></p>
* <p>This key is available on all devices.</p>
*
+ * @see CaptureRequest#CONTROL_AE_PRECAPTURE_TRIGGER
* @see CaptureResult#CONTROL_AF_STATE
* @see #CONTROL_AF_TRIGGER_IDLE
* @see #CONTROL_AF_TRIGGER_START
diff --git a/core/java/android/service/notification/NotificationListenerService.java b/core/java/android/service/notification/NotificationListenerService.java
index 0309d24..d424546 100644
--- a/core/java/android/service/notification/NotificationListenerService.java
+++ b/core/java/android/service/notification/NotificationListenerService.java
@@ -369,7 +369,9 @@ public abstract class NotificationListenerService extends Service {
/**
* Inform the notification manager that these notifications have been viewed by the
- * user.
+ * user. This should only be called when there is sufficient confidence that the user is
+ * looking at the notifications, such as when the notifications appear on the screen due to
+ * an explicit user interaction.
* @param keys Notifications to mark as seen.
*/
public final void setNotificationsShown(String[] keys) {
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index b3def33..23da6d2 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -8701,14 +8701,14 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
}
/**
- * Adds the children of a given View for accessibility. Since some Views are
- * not important for accessibility the children for accessibility are not
- * necessarily direct children of the view, rather they are the first level of
- * descendants important for accessibility.
+ * Adds the children of this View relevant for accessibility to the given list
+ * as output. Since some Views are not important for accessibility the added
+ * child views are not necessarily direct children of this view, rather they are
+ * the first level of descendants important for accessibility.
*
- * @param children The list of children for accessibility.
+ * @param outChildren The output list that will receive children for accessibility.
*/
- public void addChildrenForAccessibility(ArrayList<View> children) {
+ public void addChildrenForAccessibility(ArrayList<View> outChildren) {
}
diff --git a/core/java/android/view/ViewGroup.java b/core/java/android/view/ViewGroup.java
index 2e2ba88..b53d93c 100644
--- a/core/java/android/view/ViewGroup.java
+++ b/core/java/android/view/ViewGroup.java
@@ -1919,7 +1919,7 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager
}
@Override
- public void addChildrenForAccessibility(ArrayList<View> childrenForAccessibility) {
+ public void addChildrenForAccessibility(ArrayList<View> outChildren) {
if (getAccessibilityNodeProvider() != null) {
return;
}
@@ -1930,9 +1930,9 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager
View child = children.getChildAt(i);
if ((child.mViewFlags & VISIBILITY_MASK) == VISIBLE) {
if (child.includeForAccessibility()) {
- childrenForAccessibility.add(child);
+ outChildren.add(child);
} else {
- child.addChildrenForAccessibility(childrenForAccessibility);
+ child.addChildrenForAccessibility(outChildren);
}
}
}
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index 2cbfae2..bada791 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -1034,11 +1034,11 @@
android:priority="1000" />
<!-- Allows access to the list of accounts in the Accounts Service.
- <p>Protection level: dangerous
+ <p>Protection level: normal
-->
<permission android:name="android.permission.GET_ACCOUNTS"
android:permissionGroup="android.permission-group.CONTACTS"
- android:protectionLevel="dangerous"
+ android:protectionLevel="normal"
android:description="@string/permdesc_getAccounts"
android:label="@string/permlab_getAccounts" />
diff --git a/libs/hwui/Outline.h b/libs/hwui/Outline.h
index 5e9b213..c98932c 100644
--- a/libs/hwui/Outline.h
+++ b/libs/hwui/Outline.h
@@ -19,6 +19,7 @@
#include <SkPath.h>
#include "Rect.h"
+#include "utils/MathUtils.h"
namespace android {
namespace uirenderer {
@@ -85,6 +86,11 @@ public:
return mShouldClip && (mType == kOutlineType_RoundRect);
}
+ bool willRoundRectClip() const {
+ // only round rect outlines can be used for clipping
+ return willClip() && MathUtils::isPositive(mRadius);
+ }
+
bool getAsRoundRect(Rect* outRect, float* outRadius) const {
if (mType == kOutlineType_RoundRect) {
outRect->set(mBounds);
diff --git a/libs/hwui/RenderProperties.h b/libs/hwui/RenderProperties.h
index 81cf2df..11abd70 100644
--- a/libs/hwui/RenderProperties.h
+++ b/libs/hwui/RenderProperties.h
@@ -169,7 +169,7 @@ public:
bool functorsNeedLayer = ancestorDictatesFunctorsNeedLayer
// Round rect clipping forces layer for functors
- || CC_UNLIKELY(getOutline().willClip())
+ || CC_UNLIKELY(getOutline().willRoundRectClip())
|| CC_UNLIKELY(getRevealClip().willClip())
// Complex matrices forces layer, due to stencil clipping
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
index 860a6b7..3678cf1 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
@@ -2931,6 +2931,9 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode,
if (mZenModeController != null) {
mZenModeController.setUserId(mCurrentUserId);
}
+ if (mSecurityController != null) {
+ mSecurityController.onUserSwitched(mCurrentUserId);
+ }
}
private void resetUserSetupObserver() {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/SecurityControllerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/SecurityControllerImpl.java
index 962000a..b505d9d 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/SecurityControllerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/SecurityControllerImpl.java
@@ -64,6 +64,7 @@ public class SecurityControllerImpl implements SecurityController {
private SparseArray<VpnConfig> mCurrentVpns = new SparseArray<>();
private int mCurrentUserId;
+ private int mVpnUserId;
public SecurityControllerImpl(Context context) {
mContext = context;
@@ -78,7 +79,7 @@ public class SecurityControllerImpl implements SecurityController {
// TODO: re-register network callback on user change.
mConnectivityManager.registerNetworkCallback(REQUEST, mNetworkCallback);
- mCurrentUserId = ActivityManager.getCurrentUser();
+ onUserSwitched(ActivityManager.getCurrentUser());
}
public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
@@ -123,9 +124,9 @@ public class SecurityControllerImpl implements SecurityController {
@Override
public String getPrimaryVpnName() {
- VpnConfig cfg = mCurrentVpns.get(mCurrentUserId);
+ VpnConfig cfg = mCurrentVpns.get(mVpnUserId);
if (cfg != null) {
- return getNameForVpnConfig(cfg, new UserHandle(mCurrentUserId));
+ return getNameForVpnConfig(cfg, new UserHandle(mVpnUserId));
} else {
return null;
}
@@ -133,8 +134,8 @@ public class SecurityControllerImpl implements SecurityController {
@Override
public String getProfileVpnName() {
- for (UserInfo profile : mUserManager.getProfiles(mCurrentUserId)) {
- if (profile.id == mCurrentUserId) {
+ for (UserInfo profile : mUserManager.getProfiles(mVpnUserId)) {
+ if (profile.id == mVpnUserId) {
continue;
}
VpnConfig cfg = mCurrentVpns.get(profile.id);
@@ -147,7 +148,7 @@ public class SecurityControllerImpl implements SecurityController {
@Override
public boolean isVpnEnabled() {
- for (UserInfo profile : mUserManager.getProfiles(mCurrentUserId)) {
+ for (UserInfo profile : mUserManager.getProfiles(mVpnUserId)) {
if (mCurrentVpns.get(profile.id) != null) {
return true;
}
@@ -172,6 +173,12 @@ public class SecurityControllerImpl implements SecurityController {
@Override
public void onUserSwitched(int newUserId) {
mCurrentUserId = newUserId;
+ if (mUserManager.getUserInfo(newUserId).isRestricted()) {
+ // VPN for a restricted profile is routed through its owner user
+ mVpnUserId = UserHandle.USER_OWNER;
+ } else {
+ mVpnUserId = mCurrentUserId;
+ }
fireCallbacks();
}
diff --git a/services/core/java/com/android/server/pm/DefaultPermissionGrantPolicy.java b/services/core/java/com/android/server/pm/DefaultPermissionGrantPolicy.java
index 3ea384c..b9993b1 100644
--- a/services/core/java/com/android/server/pm/DefaultPermissionGrantPolicy.java
+++ b/services/core/java/com/android/server/pm/DefaultPermissionGrantPolicy.java
@@ -17,11 +17,13 @@
package com.android.server.pm;
import android.Manifest;
+import android.app.DownloadManager;
import android.content.Intent;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
import android.content.pm.PackageManagerInternal.PackagesProvider;
import android.content.pm.PackageParser;
+import android.content.pm.ProviderInfo;
import android.content.pm.ResolveInfo;
import android.net.Uri;
import android.os.Build;
@@ -228,6 +230,7 @@ final class DefaultPermissionGrantPolicy {
for (int i = 0; i < installerCount; i++) {
PackageParser.Package installPackage = installerPackages.get(i);
grantInstallPermissionsLPw(installPackage, INSTALLER_PERMISSIONS, userId);
+ grantRuntimePermissionsLPw(installPackage, STORAGE_PERMISSIONS, userId);
}
// Verifiers
@@ -239,6 +242,7 @@ final class DefaultPermissionGrantPolicy {
for (int i = 0; i < verifierCount; i++) {
PackageParser.Package verifierPackage = verifierPackages.get(i);
grantInstallPermissionsLPw(verifierPackage, VERIFIER_PERMISSIONS, userId);
+ grantRuntimePermissionsLPw(verifierPackage, STORAGE_PERMISSIONS, userId);
}
// SetupWizard
@@ -273,6 +277,30 @@ final class DefaultPermissionGrantPolicy {
&& doesPackageSupportRuntimePermissions(cameraPackage)) {
grantRuntimePermissionsLPw(cameraPackage, CAMERA_PERMISSIONS, userId);
grantRuntimePermissionsLPw(cameraPackage, MICROPHONE_PERMISSIONS, userId);
+ grantRuntimePermissionsLPw(cameraPackage, STORAGE_PERMISSIONS, userId);
+ }
+
+ // Media provider
+ PackageParser.Package mediaStorePackage = getDefaultProviderAuthorityPackageLPr(
+ MediaStore.AUTHORITY, userId);
+ if (mediaStorePackage != null) {
+ grantRuntimePermissionsLPw(mediaStorePackage, STORAGE_PERMISSIONS, userId);
+ }
+
+ // Downloads provider
+ PackageParser.Package downloadsPackage = getDefaultProviderAuthorityPackageLPr(
+ "downloads", userId);
+ if (downloadsPackage != null) {
+ grantRuntimePermissionsLPw(downloadsPackage, STORAGE_PERMISSIONS, userId);
+ }
+
+ // Downloads UI
+ Intent downloadsUiIntent = new Intent(DownloadManager.ACTION_VIEW_DOWNLOADS);
+ PackageParser.Package downloadsUiPackage = getDefaultSystemHandlerActvityPackageLPr(
+ downloadsUiIntent, userId);
+ if (downloadsUiPackage != null
+ && doesPackageSupportRuntimePermissions(downloadsUiPackage)) {
+ grantRuntimePermissionsLPw(downloadsUiPackage, STORAGE_PERMISSIONS, userId);
}
// Messaging
@@ -452,6 +480,15 @@ final class DefaultPermissionGrantPolicy {
return null;
}
+ private PackageParser.Package getDefaultProviderAuthorityPackageLPr(
+ String authority, int userId) {
+ ProviderInfo provider = mService.resolveContentProvider(authority, 0, userId);
+ if (provider != null) {
+ return getSystemPackageLPr(provider.packageName);
+ }
+ return null;
+ }
+
private PackageParser.Package getSystemPackageLPr(String packageName) {
PackageParser.Package pkg = mService.mPackages.get(packageName);
if (pkg != null && pkg.isSystemApp()) {
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
index 40ff3f4..1fd68b8 100644
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -3340,6 +3340,27 @@ public class PackageManagerService extends IPackageManager.Stub {
}
@Override
+ public void resetRuntimePermissions() {
+ mContext.enforceCallingOrSelfPermission(
+ android.Manifest.permission.GRANT_REVOKE_PERMISSIONS,
+ "revokeRuntimePermission");
+
+ int callingUid = Binder.getCallingUid();
+ if (callingUid != Process.SYSTEM_UID && callingUid != 0) {
+ mContext.enforceCallingOrSelfPermission(
+ android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
+ "resetRuntimePermissions");
+ }
+
+ synchronized (mPackages) {
+ updatePermissionsLPw(null, null, UPDATE_PERMISSIONS_ALL);
+ for (int userId : UserManagerService.getInstance().getUserIds()) {
+ mDefaultPermissionPolicy.grantDefaultPermissions(userId);
+ }
+ }
+ }
+
+ @Override
public int getPermissionFlags(String name, String packageName, int userId) {
if (!sUserManager.exists(userId)) {
return 0;
@@ -14190,6 +14211,7 @@ public class PackageManagerService extends IPackageManager.Stub {
boolean checkin = false;
String packageName = null;
+ ArraySet<String> permissionNames = null;
int opti = 0;
while (opti < args.length) {
@@ -14213,6 +14235,7 @@ public class PackageManagerService extends IPackageManager.Stub {
pw.println(" k[eysets]: print known keysets");
pw.println(" r[esolvers]: dump intent resolvers");
pw.println(" perm[issions]: dump permissions");
+ pw.println(" permission [name ...]: dump declaration and use of given permission");
pw.println(" pref[erred]: print preferred package settings");
pw.println(" preferred-xml [--full]: print preferred package settings as xml");
pw.println(" prov[iders]: dump content providers");
@@ -14254,6 +14277,18 @@ public class PackageManagerService extends IPackageManager.Stub {
dumpState.setDump(DumpState.DUMP_RESOLVERS);
} else if ("perm".equals(cmd) || "permissions".equals(cmd)) {
dumpState.setDump(DumpState.DUMP_PERMISSIONS);
+ } else if ("permission".equals(cmd)) {
+ if (opti >= args.length) {
+ pw.println("Error: permission requires permission name");
+ return;
+ }
+ permissionNames = new ArraySet<>();
+ while (opti < args.length) {
+ permissionNames.add(args[opti]);
+ opti++;
+ }
+ dumpState.setDump(DumpState.DUMP_PERMISSIONS
+ | DumpState.DUMP_PACKAGES | DumpState.DUMP_SHARED_USERS);
} else if ("pref".equals(cmd) || "preferred".equals(cmd)) {
dumpState.setDump(DumpState.DUMP_PREFERRED);
} else if ("preferred-xml".equals(cmd)) {
@@ -14536,8 +14571,8 @@ public class PackageManagerService extends IPackageManager.Stub {
}
if (!checkin && dumpState.isDumping(DumpState.DUMP_PERMISSIONS)) {
- mSettings.dumpPermissionsLPr(pw, packageName, dumpState);
- if (packageName == null) {
+ mSettings.dumpPermissionsLPr(pw, packageName, permissionNames, dumpState);
+ if (packageName == null && permissionNames == null) {
for (int iperm=0; iperm<mAppOpPermissionPackages.size(); iperm++) {
if (iperm == 0) {
if (dumpState.onTitlePrinted())
@@ -14597,11 +14632,11 @@ public class PackageManagerService extends IPackageManager.Stub {
}
if (dumpState.isDumping(DumpState.DUMP_PACKAGES)) {
- mSettings.dumpPackagesLPr(pw, packageName, dumpState, checkin);
+ mSettings.dumpPackagesLPr(pw, packageName, permissionNames, dumpState, checkin);
}
if (dumpState.isDumping(DumpState.DUMP_SHARED_USERS)) {
- mSettings.dumpSharedUsersLPr(pw, packageName, dumpState, checkin);
+ mSettings.dumpSharedUsersLPr(pw, packageName, permissionNames, dumpState, checkin);
}
if (!checkin && dumpState.isDumping(DumpState.DUMP_INSTALLS) && packageName == null) {
diff --git a/services/core/java/com/android/server/pm/PermissionsState.java b/services/core/java/com/android/server/pm/PermissionsState.java
index 04beafd..57ef284 100644
--- a/services/core/java/com/android/server/pm/PermissionsState.java
+++ b/services/core/java/com/android/server/pm/PermissionsState.java
@@ -219,6 +219,22 @@ public final class PermissionsState {
}
/**
+ * Returns whether the state has any known request for the given permission name,
+ * whether or not it has been granted.
+ */
+ public boolean hasRequestedPermission(ArraySet<String> names) {
+ if (mPermissions == null) {
+ return false;
+ }
+ for (int i=names.size()-1; i>=0; i--) {
+ if (mPermissions.get(names.valueAt(i)) != null) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ /**
* Gets all permissions for a given device user id regardless if they
* are install time or runtime permissions.
*
@@ -446,7 +462,7 @@ public final class PermissionsState {
}
}
- return permissionStates;
+ return permissionStates;
}
private int grantPermission(BasePermission permission, int userId) {
diff --git a/services/core/java/com/android/server/pm/Settings.java b/services/core/java/com/android/server/pm/Settings.java
index dcd7799..c547749 100644
--- a/services/core/java/com/android/server/pm/Settings.java
+++ b/services/core/java/com/android/server/pm/Settings.java
@@ -3881,8 +3881,9 @@ final class Settings {
ApplicationInfo.PRIVATE_FLAG_CANT_SAVE_STATE, "CANT_SAVE_STATE",
};
- void dumpPackageLPr(PrintWriter pw, String prefix, String checkinTag, PackageSetting ps,
- SimpleDateFormat sdf, Date date, List<UserInfo> users) {
+ void dumpPackageLPr(PrintWriter pw, String prefix, String checkinTag,
+ ArraySet<String> permissionNames, PackageSetting ps, SimpleDateFormat sdf,
+ Date date, List<UserInfo> users) {
if (checkinTag != null) {
pw.print(checkinTag);
pw.print(",");
@@ -3953,10 +3954,13 @@ final class Settings {
}
pw.print(prefix); pw.print(" pkg="); pw.println(ps.pkg);
pw.print(prefix); pw.print(" codePath="); pw.println(ps.codePathString);
- pw.print(prefix); pw.print(" resourcePath="); pw.println(ps.resourcePathString);
- pw.print(prefix); pw.print(" legacyNativeLibraryDir="); pw.println(ps.legacyNativeLibraryPathString);
- pw.print(prefix); pw.print(" primaryCpuAbi="); pw.println(ps.primaryCpuAbiString);
- pw.print(prefix); pw.print(" secondaryCpuAbi="); pw.println(ps.secondaryCpuAbiString);
+ if (permissionNames == null) {
+ pw.print(prefix); pw.print(" resourcePath="); pw.println(ps.resourcePathString);
+ pw.print(prefix); pw.print(" legacyNativeLibraryDir=");
+ pw.println(ps.legacyNativeLibraryPathString);
+ pw.print(prefix); pw.print(" primaryCpuAbi="); pw.println(ps.primaryCpuAbiString);
+ pw.print(prefix); pw.print(" secondaryCpuAbi="); pw.println(ps.secondaryCpuAbiString);
+ }
pw.print(prefix); pw.print(" versionCode="); pw.print(ps.versionCode);
if (ps.pkg != null) {
pw.print(" targetSdk="); pw.print(ps.pkg.applicationInfo.targetSdkVersion);
@@ -3969,8 +3973,10 @@ final class Settings {
pw.println(ps.pkg.applicationInfo.toString());
pw.print(prefix); pw.print(" flags="); printFlags(pw, ps.pkg.applicationInfo.flags,
FLAG_DUMP_SPEC); pw.println();
- pw.print(prefix); pw.print(" priavateFlags="); printFlags(pw,
- ps.pkg.applicationInfo.privateFlags, PRIVATE_FLAG_DUMP_SPEC); pw.println();
+ if (ps.pkg.applicationInfo.privateFlags != 0) {
+ pw.print(prefix); pw.print(" privateFlags="); printFlags(pw,
+ ps.pkg.applicationInfo.privateFlags, PRIVATE_FLAG_DUMP_SPEC); pw.println();
+ }
pw.print(prefix); pw.print(" dataDir="); pw.println(ps.pkg.applicationInfo.dataDir);
pw.print(prefix); pw.print(" supportsScreens=[");
boolean first = true;
@@ -4063,9 +4069,9 @@ final class Settings {
pw.print(prefix); pw.print(" pkgFlags="); printFlags(pw, ps.pkgFlags, FLAG_DUMP_SPEC);
pw.println();
- if (ps.sharedUser == null) {
+ if (ps.sharedUser == null || permissionNames != null) {
PermissionsState permissionsState = ps.getPermissionsState();
- dumpInstallPermissionsLPr(pw, prefix + " ", permissionsState);
+ dumpInstallPermissionsLPr(pw, prefix + " ", permissionNames, permissionsState);
}
for (UserInfo user : users) {
@@ -4089,28 +4095,31 @@ final class Settings {
if (ps.sharedUser == null) {
PermissionsState permissionsState = ps.getPermissionsState();
dumpGidsLPr(pw, prefix + " ", permissionsState.computeGids(user.id));
- dumpRuntimePermissionsLPr(pw, prefix + " ", permissionsState
+ dumpRuntimePermissionsLPr(pw, prefix + " ", permissionNames, permissionsState
.getRuntimePermissionStates(user.id));
}
- ArraySet<String> cmp = ps.getDisabledComponents(user.id);
- if (cmp != null && cmp.size() > 0) {
- pw.print(prefix); pw.println(" disabledComponents:");
- for (String s : cmp) {
- pw.print(prefix); pw.print(" "); pw.println(s);
+ if (permissionNames == null) {
+ ArraySet<String> cmp = ps.getDisabledComponents(user.id);
+ if (cmp != null && cmp.size() > 0) {
+ pw.print(prefix); pw.println(" disabledComponents:");
+ for (String s : cmp) {
+ pw.print(prefix); pw.print(" "); pw.println(s);
+ }
}
- }
- cmp = ps.getEnabledComponents(user.id);
- if (cmp != null && cmp.size() > 0) {
- pw.print(prefix); pw.println(" enabledComponents:");
- for (String s : cmp) {
- pw.print(prefix); pw.print(" "); pw.println(s);
+ cmp = ps.getEnabledComponents(user.id);
+ if (cmp != null && cmp.size() > 0) {
+ pw.print(prefix); pw.println(" enabledComponents:");
+ for (String s : cmp) {
+ pw.print(prefix); pw.print(" "); pw.println(s);
+ }
}
}
}
}
- void dumpPackagesLPr(PrintWriter pw, String packageName, DumpState dumpState, boolean checkin) {
+ void dumpPackagesLPr(PrintWriter pw, String packageName, ArraySet<String> permissionNames,
+ DumpState dumpState, boolean checkin) {
final SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
final Date date = new Date();
boolean printedSomething = false;
@@ -4120,6 +4129,10 @@ final class Settings {
&& !packageName.equals(ps.name)) {
continue;
}
+ if (permissionNames != null
+ && !ps.getPermissionsState().hasRequestedPermission(permissionNames)) {
+ continue;
+ }
if (!checkin && packageName != null) {
dumpState.setSharedUser(ps.sharedUser);
@@ -4131,11 +4144,11 @@ final class Settings {
pw.println("Packages:");
printedSomething = true;
}
- dumpPackageLPr(pw, " ", checkin ? "pkg" : null, ps, sdf, date, users);
+ dumpPackageLPr(pw, " ", checkin ? "pkg" : null, permissionNames, ps, sdf, date, users);
}
printedSomething = false;
- if (!checkin && mRenamedPackages.size() > 0) {
+ if (!checkin && mRenamedPackages.size() > 0 && permissionNames == null) {
for (final Map.Entry<String, String> e : mRenamedPackages.entrySet()) {
if (packageName != null && !packageName.equals(e.getKey())
&& !packageName.equals(e.getValue())) {
@@ -4159,7 +4172,7 @@ final class Settings {
}
printedSomething = false;
- if (mDisabledSysPackages.size() > 0) {
+ if (mDisabledSysPackages.size() > 0 && permissionNames == null) {
for (final PackageSetting ps : mDisabledSysPackages.values()) {
if (packageName != null && !packageName.equals(ps.realName)
&& !packageName.equals(ps.name)) {
@@ -4171,17 +4184,22 @@ final class Settings {
pw.println("Hidden system packages:");
printedSomething = true;
}
- dumpPackageLPr(pw, " ", checkin ? "dis" : null, ps, sdf, date, users);
+ dumpPackageLPr(pw, " ", checkin ? "dis" : null, permissionNames, ps, sdf, date,
+ users);
}
}
}
- void dumpPermissionsLPr(PrintWriter pw, String packageName, DumpState dumpState) {
+ void dumpPermissionsLPr(PrintWriter pw, String packageName, ArraySet<String> permissionNames,
+ DumpState dumpState) {
boolean printedSomething = false;
for (BasePermission p : mPermissions.values()) {
if (packageName != null && !packageName.equals(p.sourcePackage)) {
continue;
}
+ if (permissionNames != null && !permissionNames.contains(p.name)) {
+ continue;
+ }
if (!printedSomething) {
if (dumpState.onTitlePrinted())
pw.println();
@@ -4211,13 +4229,17 @@ final class Settings {
}
}
- void dumpSharedUsersLPr(PrintWriter pw, String packageName, DumpState dumpState,
- boolean checkin) {
+ void dumpSharedUsersLPr(PrintWriter pw, String packageName, ArraySet<String> permissionNames,
+ DumpState dumpState, boolean checkin) {
boolean printedSomething = false;
for (SharedUserSetting su : mSharedUsers.values()) {
if (packageName != null && su != dumpState.getSharedUser()) {
continue;
}
+ if (permissionNames != null
+ && !su.getPermissionsState().hasRequestedPermission(permissionNames)) {
+ continue;
+ }
if (!checkin) {
if (!printedSomething) {
if (dumpState.onTitlePrinted())
@@ -4235,7 +4257,7 @@ final class Settings {
pw.print(prefix); pw.print("userId="); pw.println(su.userId);
PermissionsState permissionsState = su.getPermissionsState();
- dumpInstallPermissionsLPr(pw, prefix, permissionsState);
+ dumpInstallPermissionsLPr(pw, prefix, permissionNames, permissionsState);
for (int userId : UserManagerService.getInstance().getUserIds()) {
final int[] gids = permissionsState.computeGids(userId);
@@ -4244,7 +4266,7 @@ final class Settings {
if (!ArrayUtils.isEmpty(gids) || !permissions.isEmpty()) {
pw.print(prefix); pw.print("User "); pw.print(userId); pw.println(": ");
dumpGidsLPr(pw, prefix + " ", gids);
- dumpRuntimePermissionsLPr(pw, prefix + " ", permissions);
+ dumpRuntimePermissionsLPr(pw, prefix + " ", permissionNames, permissions);
}
}
} else {
@@ -4289,11 +4311,15 @@ final class Settings {
}
}
- void dumpRuntimePermissionsLPr(PrintWriter pw, String prefix,
+ void dumpRuntimePermissionsLPr(PrintWriter pw, String prefix, ArraySet<String> permissionNames,
List<PermissionState> permissionStates) {
if (!permissionStates.isEmpty()) {
pw.print(prefix); pw.println("runtime permissions:");
for (PermissionState permissionState : permissionStates) {
+ if (permissionNames != null
+ && !permissionNames.contains(permissionState.getName())) {
+ continue;
+ }
pw.print(prefix); pw.print(" "); pw.print(permissionState.getName());
pw.print(", granted="); pw.print(permissionState.isGranted());
pw.print(", flags=0x"); pw.println(Integer.toHexString(
@@ -4302,12 +4328,16 @@ final class Settings {
}
}
- void dumpInstallPermissionsLPr(PrintWriter pw, String prefix,
+ void dumpInstallPermissionsLPr(PrintWriter pw, String prefix, ArraySet<String> permissionNames,
PermissionsState permissionsState) {
List<PermissionState> permissionStates = permissionsState.getInstallPermissionStates();
if (!permissionStates.isEmpty()) {
pw.print(prefix); pw.println("install permissions:");
for (PermissionState permissionState : permissionStates) {
+ if (permissionNames != null
+ && !permissionNames.contains(permissionState.getName())) {
+ continue;
+ }
pw.print(prefix); pw.print(" "); pw.print(permissionState.getName());
pw.print(", granted="); pw.print(permissionState.isGranted());
pw.print(", flags=0x"); pw.println(Integer.toHexString(