Merge "Add permission to prevent third-parth apps from querying OOM scores"
diff --git a/api/current.txt b/api/current.txt
index 8674eef..d54b7fd 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -7441,12 +7441,16 @@
     method public static boolean compareMimeTypes(java.lang.String, java.lang.String);
     method public int describeContents();
     method public java.lang.String[] filterMimeTypes(java.lang.String);
+    method public android.os.PersistableBundle getExtras();
     method public java.lang.CharSequence getLabel();
     method public java.lang.String getMimeType(int);
     method public int getMimeTypeCount();
     method public boolean hasMimeType(java.lang.String);
+    method public void setExtras(android.os.PersistableBundle);
     method public void writeToParcel(android.os.Parcel, int);
     field public static final android.os.Parcelable.Creator<android.content.ClipDescription> CREATOR;
+    field public static final java.lang.String EXTRA_TARGET_COMPONENT_NAME = "android.content.extra.TARGET_COMPONENT_NAME";
+    field public static final java.lang.String EXTRA_USER_SERIAL_NUMBER = "android.content.extra.USER_SERIAL_NUMBER";
     field public static final java.lang.String MIMETYPE_TEXT_HTML = "text/html";
     field public static final java.lang.String MIMETYPE_TEXT_INTENT = "text/vnd.android.intent";
     field public static final java.lang.String MIMETYPE_TEXT_PLAIN = "text/plain";
diff --git a/api/system-current.txt b/api/system-current.txt
index 6dbd642..2ea5ebb 100644
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -7683,12 +7683,16 @@
     method public static boolean compareMimeTypes(java.lang.String, java.lang.String);
     method public int describeContents();
     method public java.lang.String[] filterMimeTypes(java.lang.String);
+    method public android.os.PersistableBundle getExtras();
     method public java.lang.CharSequence getLabel();
     method public java.lang.String getMimeType(int);
     method public int getMimeTypeCount();
     method public boolean hasMimeType(java.lang.String);
+    method public void setExtras(android.os.PersistableBundle);
     method public void writeToParcel(android.os.Parcel, int);
     field public static final android.os.Parcelable.Creator<android.content.ClipDescription> CREATOR;
+    field public static final java.lang.String EXTRA_TARGET_COMPONENT_NAME = "android.content.extra.TARGET_COMPONENT_NAME";
+    field public static final java.lang.String EXTRA_USER_SERIAL_NUMBER = "android.content.extra.USER_SERIAL_NUMBER";
     field public static final java.lang.String MIMETYPE_TEXT_HTML = "text/html";
     field public static final java.lang.String MIMETYPE_TEXT_INTENT = "text/vnd.android.intent";
     field public static final java.lang.String MIMETYPE_TEXT_PLAIN = "text/plain";
diff --git a/api/test-current.txt b/api/test-current.txt
index 2eb4356..904347d 100644
--- a/api/test-current.txt
+++ b/api/test-current.txt
@@ -7441,12 +7441,16 @@
     method public static boolean compareMimeTypes(java.lang.String, java.lang.String);
     method public int describeContents();
     method public java.lang.String[] filterMimeTypes(java.lang.String);
+    method public android.os.PersistableBundle getExtras();
     method public java.lang.CharSequence getLabel();
     method public java.lang.String getMimeType(int);
     method public int getMimeTypeCount();
     method public boolean hasMimeType(java.lang.String);
+    method public void setExtras(android.os.PersistableBundle);
     method public void writeToParcel(android.os.Parcel, int);
     field public static final android.os.Parcelable.Creator<android.content.ClipDescription> CREATOR;
+    field public static final java.lang.String EXTRA_TARGET_COMPONENT_NAME = "android.content.extra.TARGET_COMPONENT_NAME";
+    field public static final java.lang.String EXTRA_USER_SERIAL_NUMBER = "android.content.extra.USER_SERIAL_NUMBER";
     field public static final java.lang.String MIMETYPE_TEXT_HTML = "text/html";
     field public static final java.lang.String MIMETYPE_TEXT_INTENT = "text/vnd.android.intent";
     field public static final java.lang.String MIMETYPE_TEXT_PLAIN = "text/plain";
diff --git a/core/java/android/app/INotificationManager.aidl b/core/java/android/app/INotificationManager.aidl
index c1d5b19..c504ce3 100644
--- a/core/java/android/app/INotificationManager.aidl
+++ b/core/java/android/app/INotificationManager.aidl
@@ -93,6 +93,7 @@
     AutomaticZenRule addAutomaticZenRule(in AutomaticZenRule automaticZenRule);
     boolean updateAutomaticZenRule(in AutomaticZenRule automaticZenRule);
     boolean removeAutomaticZenRule(String id);
+    boolean removeAutomaticZenRules(String packageName);
 
     byte[] getBackupPayload(int user);
     void applyRestore(in byte[] payload, int user);
diff --git a/core/java/android/app/NotificationManager.java b/core/java/android/app/NotificationManager.java
index 3eb3e0f..89610e9 100644
--- a/core/java/android/app/NotificationManager.java
+++ b/core/java/android/app/NotificationManager.java
@@ -470,6 +470,20 @@
     }
 
     /**
+     * Deletes all automatic zen rules owned by the given package.
+     *
+     * @hide
+     */
+    public boolean removeAutomaticZenRules(String packageName) {
+        INotificationManager service = getService();
+        try {
+            return service.removeAutomaticZenRules(packageName);
+        } catch (RemoteException e) {
+        }
+        return false;
+    }
+
+    /**
      * Checks the ability to read/modify notification policy for the calling package.
      *
      * <p>
diff --git a/core/java/android/content/ClipDescription.java b/core/java/android/content/ClipDescription.java
index e988516..1b024e2 100644
--- a/core/java/android/content/ClipDescription.java
+++ b/core/java/android/content/ClipDescription.java
@@ -18,6 +18,7 @@
 
 import android.os.Parcel;
 import android.os.Parcelable;
+import android.os.PersistableBundle;
 import android.text.TextUtils;
 
 import java.util.ArrayList;
@@ -59,8 +60,35 @@
      */
     public static final String MIMETYPE_TEXT_INTENT = "text/vnd.android.intent";
 
+    /**
+     * The name of the extra used to define a component name when copying/dragging
+     * an app icon from Launcher.
+     * <p>
+     * Type: String
+     * </p>
+     * <p>
+     * Use {@link ComponentName#unflattenFromString(String)}
+     * and {@link ComponentName#flattenToString()} to convert the extra value
+     * to/from {@link ComponentName}.
+     * </p>
+     */
+    public static final String EXTRA_TARGET_COMPONENT_NAME =
+            "android.content.extra.TARGET_COMPONENT_NAME";
+
+    /**
+     * The name of the extra used to define a user serial number when copying/dragging
+     * an app icon from Launcher.
+     * <p>
+     * Type: long
+     * </p>
+     */
+    public static final String EXTRA_USER_SERIAL_NUMBER =
+            "android.content.extra.USER_SERIAL_NUMBER";
+
+
     final CharSequence mLabel;
     final String[] mMimeTypes;
+    private PersistableBundle mExtras;
 
     /**
      * Create a new clip.
@@ -173,6 +201,27 @@
         return mMimeTypes[index];
     }
 
+    /**
+     * Retrieve extended data from the clip description.
+     *
+     * @return the bundle containing extended data previously set with
+     * {@link #setExtras(PersistableBundle)}, or null if no extras have been set.
+     *
+     * @see #setExtras(PersistableBundle)
+     */
+    public PersistableBundle getExtras() {
+        return mExtras;
+    }
+
+    /**
+     * Add extended data to the clip description.
+     *
+     * @see #getExtras()
+     */
+    public void setExtras(PersistableBundle extras) {
+        mExtras = new PersistableBundle(extras);
+    }
+
     /** @hide */
     public void validate() {
         if (mMimeTypes == null) {
@@ -211,6 +260,13 @@
             b.append(mLabel);
             b.append('"');
         }
+        if (mExtras != null) {
+            if (!first) {
+                b.append(' ');
+            }
+            first = false;
+            b.append(mExtras.toString());
+        }
         return !first;
     }
 
@@ -236,11 +292,13 @@
     public void writeToParcel(Parcel dest, int flags) {
         TextUtils.writeToParcel(mLabel, dest, flags);
         dest.writeStringArray(mMimeTypes);
+        dest.writePersistableBundle(mExtras);
     }
 
     ClipDescription(Parcel in) {
         mLabel = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(in);
         mMimeTypes = in.createStringArray();
+        mExtras = in.readPersistableBundle();
     }
 
     public static final Parcelable.Creator<ClipDescription> CREATOR =
diff --git a/core/java/android/service/notification/ZenModeConfig.java b/core/java/android/service/notification/ZenModeConfig.java
index b3399d0..541623d 100644
--- a/core/java/android/service/notification/ZenModeConfig.java
+++ b/core/java/android/service/notification/ZenModeConfig.java
@@ -1110,7 +1110,7 @@
             if (!Objects.equals(id, to.id)) {
                 d.addLine(item, "id", id, to.id);
             }
-            if (creationTime == to.creationTime) {
+            if (creationTime != to.creationTime) {
                 d.addLine(item, "creationTime", creationTime, to.creationTime);
             }
         }
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index ee0521e..ef623eb 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -5389,6 +5389,11 @@
                     removeUriPermissionsForPackageLocked(packageName, userId, true);
                 }
 
+                // Remove all zen rules created by this package; revoke it's zen access.
+                INotificationManager inm = NotificationManager.getService();
+                inm.removeAutomaticZenRules(packageName);
+                inm.setNotificationPolicyAccessGranted(packageName, false);
+
                 Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
                         Uri.fromParts("package", packageName, null));
                 intent.putExtra(Intent.EXTRA_UID, pkgUid);
diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java
index 38893b8..e0b7370 100644
--- a/services/core/java/com/android/server/notification/NotificationManagerService.java
+++ b/services/core/java/com/android/server/notification/NotificationManagerService.java
@@ -1634,6 +1634,14 @@
         }
 
         @Override
+        public boolean removeAutomaticZenRules(String packageName) throws RemoteException {
+            Preconditions.checkNotNull(packageName, "Package name is null");
+            enforceSystemOrSystemUI("removeAutomaticZenRules");
+
+            return mZenModeHelper.removeAutomaticZenRules(packageName, "removeAutomaticZenRules");
+        }
+
+        @Override
         public void setInterruptionFilter(String pkg, int filter) throws RemoteException {
             enforcePolicyAccess(pkg, "setInterruptionFilter");
             final int zen = NotificationManager.zenModeFromInterruptionFilter(filter, -1);
diff --git a/services/core/java/com/android/server/notification/ZenModeHelper.java b/services/core/java/com/android/server/notification/ZenModeHelper.java
index dbdc3f4..3c891df 100644
--- a/services/core/java/com/android/server/notification/ZenModeHelper.java
+++ b/services/core/java/com/android/server/notification/ZenModeHelper.java
@@ -41,6 +41,7 @@
 import android.os.Handler;
 import android.os.Looper;
 import android.os.Message;
+import android.os.Process;
 import android.os.SystemClock;
 import android.os.UserHandle;
 import android.provider.Settings.Global;
@@ -274,7 +275,7 @@
             newConfig = mConfig.copy();
         }
         final String ruleId = automaticZenRule.getId();
-        ZenModeConfig.ZenRule rule = new ZenModeConfig.ZenRule();
+        ZenModeConfig.ZenRule rule;
         if (ruleId == null) {
             throw new IllegalArgumentException("Rule doesn't exist");
         } else {
@@ -307,13 +308,32 @@
         return setConfig(newConfig, reason, true);
     }
 
+    public boolean removeAutomaticZenRules(String packageName, String reason) {
+        ZenModeConfig newConfig;
+        synchronized (mConfig) {
+            if (mConfig == null) return false;
+            newConfig = mConfig.copy();
+        }
+        for (int i = newConfig.automaticRules.size() - 1; i >= 0; i--) {
+            ZenRule rule = newConfig.automaticRules.get(newConfig.automaticRules.keyAt(i));
+            if (rule.component.getPackageName().equals(packageName)
+                    && canManageAutomaticZenRule(rule)) {
+                newConfig.automaticRules.removeAt(i);
+            }
+        }
+        return setConfig(newConfig, reason, true);
+    }
+
     public boolean canManageAutomaticZenRule(ZenRule rule) {
-        if (mContext.checkCallingPermission(android.Manifest.permission.MANAGE_NOTIFICATIONS)
+        final int callingUid = Binder.getCallingUid();
+        if (callingUid == 0 || callingUid == Process.SYSTEM_UID) {
+            return true;
+        } else if (mContext.checkCallingPermission(android.Manifest.permission.MANAGE_NOTIFICATIONS)
                 == PackageManager.PERMISSION_GRANTED) {
             return true;
         } else {
-            String[] packages = mContext.getPackageManager().getPackagesForUid(
-                    Binder.getCallingUid());
+            String[] packages =
+                    mContext.getPackageManager().getPackagesForUid(Binder.getCallingUid());
             if (packages != null) {
                 final int packageCount = packages.length;
                 for (int i = 0; i < packageCount; i++) {