Merge "Use a framework resource to name a factory-default browser app" into mnc-dev
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 @@
             return runGrantRevokePermission(false);
         }
 
+        if ("reset-permissions".equals(op)) {
+            return runResetPermissions();
+        }
+
         if ("set-permission-enforced".equals(op)) {
             return runSetPermissionEnforced();
         }
@@ -1636,6 +1640,24 @@
         }
     }
 
+    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 @@
         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 @@
         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 @@
 
     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/fingerprint/IFingerprintService.aidl b/core/java/android/hardware/fingerprint/IFingerprintService.aidl
index 0484806..f596c93 100644
--- a/core/java/android/hardware/fingerprint/IFingerprintService.aidl
+++ b/core/java/android/hardware/fingerprint/IFingerprintService.aidl
@@ -26,7 +26,7 @@
  */
 interface IFingerprintService {
     // Authenticate the given sessionId with a fingerprint
-    void authenticate(IBinder token, long sessionId, int groupId,
+    void authenticate(IBinder token, long sessionId, int userId,
             IFingerprintServiceReceiver receiver, int flags, String opPackageName);
 
     // Cancel authentication for the given sessionId
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 @@
 
     /**
      * 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 @@
     }
 
     /**
-     * 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 @@
     }
 
     @Override
-    public void addChildrenForAccessibility(ArrayList<View> childrenForAccessibility) {
+    public void addChildrenForAccessibility(ArrayList<View> outChildren) {
         if (getAccessibilityNodeProvider() != null) {
             return;
         }
@@ -1930,9 +1930,9 @@
                 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/core/tests/coretests/apks/install_jni_lib_open_from_apk/Android.mk b/core/tests/coretests/apks/install_jni_lib_open_from_apk/Android.mk
index 6ee6ffa..6b3b55e 100644
--- a/core/tests/coretests/apks/install_jni_lib_open_from_apk/Android.mk
+++ b/core/tests/coretests/apks/install_jni_lib_open_from_apk/Android.mk
@@ -5,6 +5,4 @@
 
 LOCAL_PACKAGE_NAME := install_jni_lib_open_from_apk
 
-LOCAL_PAGE_ALIGN_JNI_SHARED_LIBRARIES := true
-
 include $(FrameworkCoreTests_BUILD_PACKAGE)
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 @@
         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 @@
         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 @@
         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 @@
 
     private SparseArray<VpnConfig> mCurrentVpns = new SparseArray<>();
     private int mCurrentUserId;
+    private int mVpnUserId;
 
     public SecurityControllerImpl(Context context) {
         mContext = context;
@@ -78,7 +79,7 @@
 
         // 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 @@
 
     @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 @@
 
     @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 @@
 
     @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 @@
     @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/fingerprint/FingerprintService.java b/services/core/java/com/android/server/fingerprint/FingerprintService.java
index c52a1c1..9ee3bc2 100644
--- a/services/core/java/com/android/server/fingerprint/FingerprintService.java
+++ b/services/core/java/com/android/server/fingerprint/FingerprintService.java
@@ -30,9 +30,11 @@
 import android.os.IRemoteCallback;
 import android.os.Looper;
 import android.os.MessageQueue;
+import android.os.PowerManager;
 import android.os.RemoteException;
 import android.os.SELinux;
 import android.os.ServiceManager;
+import android.os.SystemClock;
 import android.os.UserHandle;
 import android.util.Slog;
 
@@ -70,6 +72,7 @@
     private static final int MSG_USER_SWITCHING = 10;
     private static final int ENROLLMENT_TIMEOUT_MS = 60 * 1000; // 1 minute
 
+    private boolean mIsKeyguard; // true if the authentication client is keyguard
     private ClientMonitor mAuthClient = null;
     private ClientMonitor mEnrollClient = null;
     private ClientMonitor mRemoveClient = null;
@@ -78,6 +81,7 @@
     private static final long MS_PER_SEC = 1000;
     private static final long FAIL_LOCKOUT_TIMEOUT_MS = 30*1000;
     private static final int MAX_FAILED_ATTEMPTS = 5;
+    private static final int FINGERPRINT_ACQUIRED_GOOD = 0;
 
     Handler mHandler = new Handler() {
         public void handleMessage(android.os.Message msg) {
@@ -97,6 +101,7 @@
     private long mHalDeviceId;
     private int mFailedAttempts;
     private IFingerprintDaemon mDaemon;
+    private PowerManager mPowerManager;
 
     private final Runnable mLockoutReset = new Runnable() {
         @Override
@@ -109,6 +114,7 @@
         super(context);
         mContext = context;
         mAppOps = context.getSystemService(AppOpsManager.class);
+        mPowerManager = (PowerManager) mContext.getSystemService(Context.POWER_SERVICE);
     }
 
     @Override
@@ -191,7 +197,11 @@
                 removeClient(mAuthClient);
             }
         }
+    }
 
+    private void userActivity() {
+        long now = SystemClock.uptimeMillis();
+        mPowerManager.userActivity(now, PowerManager.USER_ACTIVITY_EVENT_TOUCH, 0);
     }
 
     void handleUserSwitching(int userId) {
@@ -498,9 +508,10 @@
          */
         private boolean sendAuthenticated(int fpId, int groupId) {
             boolean result = false;
+            boolean authenticated = fpId != 0;
             if (receiver != null) {
                 try {
-                    if (fpId == 0) {
+                    if (!authenticated) {
                         receiver.onAuthenticationFailed(mHalDeviceId);
                     } else {
                         Fingerprint fp = !restricted ?
@@ -522,6 +533,11 @@
                 result |= true; // we have a valid fingerprint
                 mLockoutReset.run();
             }
+            // For fingerprint devices that support touch-to-wake, this will ensure the device
+            // wakes up and turns the screen on when fingerprint is authenticated.
+            if (mIsKeyguard && authenticated) {
+                mPowerManager.wakeUp(SystemClock.uptimeMillis());
+            }
             return result;
         }
 
@@ -537,6 +553,12 @@
                 Slog.w(TAG, "Failed to invoke sendAcquired:", e);
                 return true; // client failed
             }
+            finally {
+                // Good scans will keep the device awake
+                if (acquiredInfo == FINGERPRINT_ACQUIRED_GOOD) {
+                    userActivity();
+                }
+            }
         }
 
         /*
@@ -589,6 +611,8 @@
     };
 
     private final class FingerprintServiceWrapper extends IFingerprintService.Stub {
+        private static final String KEYGUARD_PACKAGE = "com.android.systemui";
+
         @Override // Binder call
         public long preEnroll(IBinder token) {
             checkPermission(MANAGE_FINGERPRINT);
@@ -638,7 +662,8 @@
 
         @Override // Binder call
         public void authenticate(final IBinder token, final long opId, final int groupId,
-                final IFingerprintServiceReceiver receiver, final int flags, String opPackageName) {
+                final IFingerprintServiceReceiver receiver, final int flags,
+                final String opPackageName) {
 
             if (!canUseFingerprint(opPackageName)) {
                 return;
@@ -647,6 +672,7 @@
             mHandler.post(new Runnable() {
                 @Override
                 public void run() {
+                    mIsKeyguard = KEYGUARD_PACKAGE.equals(opPackageName);
                     startAuthentication(token, opId, groupId, receiver, flags, restricted);
                 }
             });
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 @@
             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 @@
             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 @@
                     && 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 @@
         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 d771085..52bf560 100644
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -3400,6 +3400,27 @@
     }
 
     @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;
@@ -14256,6 +14277,7 @@
         boolean checkin = false;
 
         String packageName = null;
+        ArraySet<String> permissionNames = null;
 
         int opti = 0;
         while (opti < args.length) {
@@ -14279,6 +14301,7 @@
                 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");
@@ -14320,6 +14343,18 @@
                 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)) {
@@ -14602,8 +14637,8 @@
             }
 
             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())
@@ -14663,11 +14698,11 @@
             }
 
             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 @@
     }
 
     /**
+     * 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 @@
             }
         }
 
-        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 58d703a..98b41a4 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 @@
         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 @@
         }
         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 @@
                 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 @@
         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 @@
             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 @@
                     && !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 @@
                 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 @@
         }
 
         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 @@
                     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 @@
         }
     }
 
-    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 @@
                 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 @@
                     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 @@
         }
     }
 
-    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 @@
         }
     }
 
-    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(
diff --git a/services/core/java/com/android/server/power/PowerManagerService.java b/services/core/java/com/android/server/power/PowerManagerService.java
index 51bb36f..5a0bee9 100644
--- a/services/core/java/com/android/server/power/PowerManagerService.java
+++ b/services/core/java/com/android/server/power/PowerManagerService.java
@@ -3117,7 +3117,7 @@
                 return;
             }
 
-            if (eventTime > SystemClock.uptimeMillis()) {
+            if (eventTime > now) {
                 throw new IllegalArgumentException("event time must not be in the future");
             }