Merge "Fix leak on density change." into nyc-dev
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index e408cca..8fb49b1 100755
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -8981,6 +8981,14 @@
          * @hide
          */
         public static final String ENABLE_CELLULAR_ON_BOOT = "enable_cellular_on_boot";
+
+        /**
+         * The maximum allowed notification enqueue rate in Hertz.
+         *
+         * Should be a float, and includes both posts and updates.
+         * @hide
+         */
+        public static final String MAX_NOTIFICATION_ENQUEUE_RATE = "max_notification_enqueue_rate";
     }
 
     /**
diff --git a/core/java/com/android/internal/util/FastPrintWriter.java b/core/java/com/android/internal/util/FastPrintWriter.java
index c74fea0..e46e6b0 100644
--- a/core/java/com/android/internal/util/FastPrintWriter.java
+++ b/core/java/com/android/internal/util/FastPrintWriter.java
@@ -1,5 +1,6 @@
 package com.android.internal.util;
 
+import android.util.Log;
 import android.util.Printer;
 
 import java.io.IOException;
@@ -328,11 +329,13 @@
     }
 
     private void flushBytesLocked() throws IOException {
-        int position;
-        if ((position = mBytes.position()) > 0) {
-            mBytes.flip();
-            mOutputStream.write(mBytes.array(), 0, position);
-            mBytes.clear();
+        if (!mIoError) {
+            int position;
+            if ((position = mBytes.position()) > 0) {
+                mBytes.flip();
+                mOutputStream.write(mBytes.array(), 0, position);
+                mBytes.clear();
+            }
         }
     }
 
@@ -352,11 +355,15 @@
                     }
                     break;
                 }
-                flushBytesLocked();
-                mOutputStream.flush();
+                if (!mIoError) {
+                    flushBytesLocked();
+                    mOutputStream.flush();
+                }
             } else if (mWriter != null) {
-                mWriter.write(mText, 0, mPos);
-                mWriter.flush();
+                if (!mIoError) {
+                    mWriter.write(mText, 0, mPos);
+                    mWriter.flush();
+                }
             } else {
                 int nonEolOff = 0;
                 final int sepLen = mSeparator.length();
@@ -385,12 +392,15 @@
         synchronized (lock) {
             try {
                 flushLocked();
-                if (mOutputStream != null) {
-                    mOutputStream.flush();
-                } else if (mWriter != null) {
-                    mWriter.flush();
+                if (!mIoError) {
+                    if (mOutputStream != null) {
+                        mOutputStream.flush();
+                    } else if (mWriter != null) {
+                        mWriter.flush();
+                    }
                 }
             } catch (IOException e) {
+                Log.w("FastPrintWriter", "Write failure", e);
                 setError();
             }
         }
@@ -407,6 +417,7 @@
                     mWriter.close();
                 }
             } catch (IOException e) {
+                Log.w("FastPrintWriter", "Write failure", e);
                 setError();
             }
         }
@@ -425,6 +436,8 @@
             try {
                 appendLocked(charArray, 0, charArray.length);
             } catch (IOException e) {
+                Log.w("FastPrintWriter", "Write failure", e);
+                setError();
             }
         }
     }
@@ -442,6 +455,8 @@
             try {
                 appendLocked(ch);
             } catch (IOException e) {
+                Log.w("FastPrintWriter", "Write failure", e);
+                setError();
             }
         }
     }
@@ -465,6 +480,7 @@
             try {
                 appendLocked(str, 0, str.length());
             } catch (IOException e) {
+                Log.w("FastPrintWriter", "Write failure", e);
                 setError();
             }
         }
@@ -500,6 +516,7 @@
                     flushLocked();
                 }
             } catch (IOException e) {
+                Log.w("FastPrintWriter", "Write failure", e);
                 setError();
             }
         }
@@ -564,6 +581,8 @@
             try {
                 appendLocked(buf, offset, count);
             } catch (IOException e) {
+                Log.w("FastPrintWriter", "Write failure", e);
+                setError();
             }
         }
     }
@@ -584,6 +603,8 @@
             try {
                 appendLocked((char) oneChar);
             } catch (IOException e) {
+                Log.w("FastPrintWriter", "Write failure", e);
+                setError();
             }
         }
     }
@@ -600,6 +621,8 @@
             try {
                 appendLocked(str, 0, str.length());
             } catch (IOException e) {
+                Log.w("FastPrintWriter", "Write failure", e);
+                setError();
             }
         }
     }
@@ -624,6 +647,8 @@
             try {
                 appendLocked(str, offset, count);
             } catch (IOException e) {
+                Log.w("FastPrintWriter", "Write failure", e);
+                setError();
             }
         }
     }
diff --git a/packages/Keyguard/src/com/android/keyguard/KeyguardPinBasedInputView.java b/packages/Keyguard/src/com/android/keyguard/KeyguardPinBasedInputView.java
index c8719f3..8d6e07e 100644
--- a/packages/Keyguard/src/com/android/keyguard/KeyguardPinBasedInputView.java
+++ b/packages/Keyguard/src/com/android/keyguard/KeyguardPinBasedInputView.java
@@ -239,8 +239,7 @@
     @Override
     public boolean onKey(View v, int keyCode, KeyEvent event) {
         if (event.getAction() == KeyEvent.ACTION_DOWN) {
-            onKeyDown(keyCode, event);
-            return true;
+            return onKeyDown(keyCode, event);
         }
         return false;
     }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableNotificationRow.java b/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableNotificationRow.java
index 760f432..aedc7df 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableNotificationRow.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableNotificationRow.java
@@ -1097,7 +1097,7 @@
             mIsSystemExpanded = expand;
             notifyHeightChanged(false /* needsAnimation */);
             logExpansionEvent(false, wasExpanded);
-            if (mChildrenContainer != null) {
+            if (mIsSummaryWithChildren) {
                 mChildrenContainer.updateGroupOverflow();
             }
         }
@@ -1166,13 +1166,14 @@
             mChildrenContainer.recreateNotificationHeader(mExpandClickListener,
                     mEntry.notification);
         }
+        getShowingLayout().updateBackgroundColor(false /* animate */);
         mPrivateLayout.updateExpandButtons(isExpandable());
         updateChildrenHeaderAppearance();
         updateChildrenVisibility();
     }
 
     public void updateChildrenHeaderAppearance() {
-        if (mChildrenContainer != null) {
+        if (mIsSummaryWithChildren) {
             mChildrenContainer.updateChildrenHeaderAppearance();
         }
     }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationCustomViewWrapper.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationCustomViewWrapper.java
index 61df44a..85e87dd 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationCustomViewWrapper.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationCustomViewWrapper.java
@@ -127,7 +127,8 @@
 
     @Override
     public int getCustomBackgroundColor() {
-        return mBackgroundColor;
+        // Parent notifications should always use the normal background color
+        return mRow.isSummaryWithChildren() ? 0 : mBackgroundColor;
     }
 
     @Override
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/QSTileHost.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/QSTileHost.java
index 29b4db1..68e5d0b 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/QSTileHost.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/QSTileHost.java
@@ -369,13 +369,15 @@
     }
 
     public void addTile(String spec) {
-        if (mTileSpecs.contains(spec)) {
+        final String setting = Settings.Secure.getStringForUser(mContext.getContentResolver(),
+                TILES_SETTING, ActivityManager.getCurrentUser());
+        final List<String> tileSpecs = loadTileSpecs(mContext, setting);
+        if (tileSpecs.contains(spec)) {
             return;
         }
-        ArrayList<String> specs = new ArrayList<>(mTileSpecs);
-        specs.add(spec);
+        tileSpecs.add(spec);
         Settings.Secure.putStringForUser(mContext.getContentResolver(), TILES_SETTING,
-                TextUtils.join(",", specs), ActivityManager.getCurrentUser());
+                TextUtils.join(",", tileSpecs), ActivityManager.getCurrentUser());
     }
 
     public void addTile(ComponentName tile) {
diff --git a/packages/SystemUI/src/com/android/systemui/volume/ZenModePanel.java b/packages/SystemUI/src/com/android/systemui/volume/ZenModePanel.java
index a67299e..0c712be 100644
--- a/packages/SystemUI/src/com/android/systemui/volume/ZenModePanel.java
+++ b/packages/SystemUI/src/com/android/systemui/volume/ZenModePanel.java
@@ -501,9 +501,17 @@
         if (mCountdownConditionSupported) {
             Condition nextAlarmCondition = getTimeUntilNextAlarmCondition();
             if (nextAlarmCondition != null) {
+                mZenRadioGroup.getChildAt(
+                        COUNTDOWN_ALARM_CONDITION_INDEX).setVisibility(View.VISIBLE);
+                mZenRadioGroupContent.getChildAt(
+                        COUNTDOWN_ALARM_CONDITION_INDEX).setVisibility(View.VISIBLE);
                 bind(nextAlarmCondition,
                         mZenRadioGroupContent.getChildAt(COUNTDOWN_ALARM_CONDITION_INDEX),
                         COUNTDOWN_ALARM_CONDITION_INDEX);
+            } else {
+                mZenRadioGroup.getChildAt(COUNTDOWN_ALARM_CONDITION_INDEX).setVisibility(View.GONE);
+                mZenRadioGroupContent.getChildAt(
+                        COUNTDOWN_ALARM_CONDITION_INDEX).setVisibility(View.GONE);
             }
         }
         // ensure something is selected
diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java
index a8b1a4a..0af0c73 100644
--- a/services/core/java/com/android/server/notification/NotificationManagerService.java
+++ b/services/core/java/com/android/server/notification/NotificationManagerService.java
@@ -181,7 +181,7 @@
             = SystemProperties.getBoolean("debug.child_notifs", true);
 
     static final int MAX_PACKAGE_NOTIFICATIONS = 50;
-    static final float MAX_PACKAGE_ENQUEUE_RATE = 50f;
+    static final float DEFAULT_MAX_NOTIFICATION_ENQUEUE_RATE = 50f;
 
     // message codes
     static final int MESSAGE_TIMEOUT = 2;
@@ -305,6 +305,7 @@
     private static final int MY_PID = Process.myPid();
     private RankingHandler mRankingHandler;
     private long mLastOverRateLogTime;
+    private float mMaxPackageEnqueueRate = DEFAULT_MAX_NOTIFICATION_ENQUEUE_RATE;
 
     private static class Archive {
         final int mBufferSize;
@@ -817,6 +818,8 @@
     private final class SettingsObserver extends ContentObserver {
         private final Uri NOTIFICATION_LIGHT_PULSE_URI
                 = Settings.System.getUriFor(Settings.System.NOTIFICATION_LIGHT_PULSE);
+        private final Uri NOTIFICATION_RATE_LIMIT_URI
+                = Settings.Global.getUriFor(Settings.Global.MAX_NOTIFICATION_ENQUEUE_RATE);
 
         SettingsObserver(Handler handler) {
             super(handler);
@@ -826,6 +829,8 @@
             ContentResolver resolver = getContext().getContentResolver();
             resolver.registerContentObserver(NOTIFICATION_LIGHT_PULSE_URI,
                     false, this, UserHandle.USER_ALL);
+            resolver.registerContentObserver(NOTIFICATION_RATE_LIMIT_URI,
+                    false, this, UserHandle.USER_ALL);
             update(null);
         }
 
@@ -843,6 +848,10 @@
                     updateNotificationPulse();
                 }
             }
+            if (uri == null || NOTIFICATION_RATE_LIMIT_URI.equals(uri)) {
+                mMaxPackageEnqueueRate = Settings.Global.getFloat(resolver,
+                            Settings.Global.MAX_NOTIFICATION_ENQUEUE_RATE, mMaxPackageEnqueueRate);
+            }
         }
     }
 
@@ -899,6 +908,10 @@
     public void onStart() {
         Resources resources = getContext().getResources();
 
+        mMaxPackageEnqueueRate = Settings.Global.getFloat(getContext().getContentResolver(),
+                Settings.Global.MAX_NOTIFICATION_ENQUEUE_RATE,
+                DEFAULT_MAX_NOTIFICATION_ENQUEUE_RATE);
+
         mAm = ActivityManagerNative.getDefault();
         mAppOps = (AppOpsManager) getContext().getSystemService(Context.APP_OPS_SERVICE);
         mVibrator = (Vibrator) getContext().getSystemService(Context.VIBRATOR_SERVICE);
@@ -2369,6 +2382,7 @@
                     pw.println("  mDisableNotificationEffects=" + mDisableNotificationEffects);
                     pw.println("  mCallState=" + callStateToString(mCallState));
                     pw.println("  mSystemReady=" + mSystemReady);
+                    pw.println("  mMaxPackageEnqueueRate=" + mMaxPackageEnqueueRate);
                 }
                 pw.println("  mArchive=" + mArchive.toString());
                 Iterator<StatusBarNotification> iter = mArchive.descendingIterator();
@@ -2512,7 +2526,7 @@
         if (!isSystemNotification && !isNotificationFromListener) {
             synchronized (mNotificationList) {
                 final float appEnqueueRate = mUsageStats.getAppEnqueueRate(pkg);
-                if (appEnqueueRate > MAX_PACKAGE_ENQUEUE_RATE) {
+                if (appEnqueueRate > mMaxPackageEnqueueRate) {
                     mUsageStats.registerOverRateQuota(pkg);
                     final long now = SystemClock.elapsedRealtime();
                     if ((now - mLastOverRateLogTime) > MIN_PACKAGE_OVERRATE_LOG_INTERVAL) {
diff --git a/services/core/java/com/android/server/pm/UserManagerService.java b/services/core/java/com/android/server/pm/UserManagerService.java
index 9d8ba12..b916790 100644
--- a/services/core/java/com/android/server/pm/UserManagerService.java
+++ b/services/core/java/com/android/server/pm/UserManagerService.java
@@ -1009,9 +1009,13 @@
                 // in getUserRestrictionSource on who set local policies.
                 mGlobalRestrictionOwnerUserId = userId;
             } else {
-                // When profile owner sets restrictions it passes null global bundle and we reset 
-                // global restriction owner userId.
-                mGlobalRestrictionOwnerUserId = UserHandle.USER_NULL;
+                if (mGlobalRestrictionOwnerUserId == userId) {
+                    // When profile owner sets restrictions it passes null global bundle and we
+                    // reset global restriction owner userId.
+                    // This means this user used to have DO, but now the DO is gone and the user
+                    // instead has PO.
+                    mGlobalRestrictionOwnerUserId = UserHandle.USER_NULL;
+                }
             }
             {
                 // Update local.
diff --git a/services/java/com/android/server/SystemServer.java b/services/java/com/android/server/SystemServer.java
index eed4351..476a559 100644
--- a/services/java/com/android/server/SystemServer.java
+++ b/services/java/com/android/server/SystemServer.java
@@ -701,13 +701,15 @@
         // as appropriate.
         mSystemServiceManager.startService(UiModeManagerService.class);
 
-        Trace.traceBegin(Trace.TRACE_TAG_SYSTEM_SERVER, "UpdatePackagesIfNeeded");
-        try {
-            mPackageManagerService.updatePackagesIfNeeded();
-        } catch (Throwable e) {
-            reportWtf("update packages", e);
+        if (!mOnlyCore) {
+            Trace.traceBegin(Trace.TRACE_TAG_SYSTEM_SERVER, "UpdatePackagesIfNeeded");
+            try {
+                mPackageManagerService.updatePackagesIfNeeded();
+            } catch (Throwable e) {
+                reportWtf("update packages", e);
+            }
+            Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER);
         }
-        Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER);
 
         Trace.traceBegin(Trace.TRACE_TAG_SYSTEM_SERVER, "PerformFstrimIfNeeded");
         try {