Merge "Fix Wrong parameter in HashMap.remove"
diff --git a/core/java/android/view/DisplayList.java b/core/java/android/view/DisplayList.java
index 5e34a36..e996e67 100644
--- a/core/java/android/view/DisplayList.java
+++ b/core/java/android/view/DisplayList.java
@@ -28,6 +28,8 @@
  * @hide 
  */
 public abstract class DisplayList {
+    private boolean mDirty;
+
     /**
      * Flag used when calling
      * {@link HardwareCanvas#drawDisplayList(DisplayList, android.graphics.Rect, int)} 
@@ -96,6 +98,28 @@
     public abstract void clear();
 
     /**
+     * Sets the dirty flag. When a display list is dirty, both
+     * {@link #invalidate()} and {@link #clear()} should be invoked whenever
+     * possible.
+     *
+     * @param dirty True to mark the display list dirty, false otherwise
+     *
+     * @see #isDirty()
+     */
+    public void setDirty(boolean dirty) {
+        mDirty = dirty;
+    }
+
+    /**
+     * Indicates whether the display list is dirty.
+     *
+     * @see #setDirty(boolean)
+     */
+    public boolean isDirty() {
+        return mDirty;
+    }
+
+    /**
      * Returns whether the display list is currently usable. If this returns false,
      * the display list should be re-recorded prior to replaying it.
      *
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index 63019bd..f9bb05b 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -11562,8 +11562,8 @@
             imm.focusIn(this);
         }
 
-        if (mAttachInfo != null && mDisplayList != null) {
-            mAttachInfo.mViewRootImpl.dequeueDisplayList(mDisplayList);
+        if (mDisplayList != null) {
+            mDisplayList.setDirty(false);
         }
     }
 
@@ -11843,6 +11843,7 @@
 
         if (mAttachInfo != null) {
             if (mDisplayList != null) {
+                mDisplayList.setDirty(true);
                 mAttachInfo.mViewRootImpl.enqueueDisplayList(mDisplayList);
             }
             mAttachInfo.mViewRootImpl.cancelInvalidate(this);
diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java
index 6def170..85fab28 100644
--- a/core/java/android/view/ViewRootImpl.java
+++ b/core/java/android/view/ViewRootImpl.java
@@ -297,7 +297,7 @@
     private long mFpsPrevTime = -1;
     private int mFpsNumFrames;
 
-    private final ArrayList<DisplayList> mDisplayLists = new ArrayList<DisplayList>(24);
+    private final ArrayList<DisplayList> mDisplayLists = new ArrayList<DisplayList>();
     
     /**
      * see {@link #playSoundEffect(int)}
@@ -2128,7 +2128,7 @@
 
     private void draw(boolean fullRedrawNeeded) {
         Surface surface = mSurface;
-        if (surface == null || !surface.isValid()) {
+        if (!surface.isValid()) {
             return;
         }
 
@@ -2209,6 +2209,8 @@
                     appScale + ", width=" + mWidth + ", height=" + mHeight);
         }
 
+        invalidateDisplayLists();
+
         attachInfo.mTreeObserver.dispatchOnDraw();
 
         if (!dirty.isEmpty() || mIsAnimating) {
@@ -2419,8 +2421,11 @@
 
         for (int i = 0; i < count; i++) {
             final DisplayList displayList = displayLists.get(i);
-            displayList.invalidate();
-            displayList.clear();
+            if (displayList.isDirty()) {
+                displayList.invalidate();
+                displayList.clear();
+                displayList.setDirty(false);
+            }
         }
 
         displayLists.clear();
@@ -2794,11 +2799,10 @@
     private final static int MSG_UPDATE_CONFIGURATION = 18;
     private final static int MSG_PROCESS_INPUT_EVENTS = 19;
     private final static int MSG_DISPATCH_SCREEN_STATE = 20;
-    private final static int MSG_INVALIDATE_DISPLAY_LIST = 21;
-    private final static int MSG_CLEAR_ACCESSIBILITY_FOCUS_HOST = 22;
-    private final static int MSG_DISPATCH_DONE_ANIMATING = 23;
-    private final static int MSG_INVALIDATE_WORLD = 24;
-    private final static int MSG_WINDOW_MOVED = 25;
+    private final static int MSG_CLEAR_ACCESSIBILITY_FOCUS_HOST = 21;
+    private final static int MSG_DISPATCH_DONE_ANIMATING = 22;
+    private final static int MSG_INVALIDATE_WORLD = 23;
+    private final static int MSG_WINDOW_MOVED = 24;
 
     final class ViewRootHandler extends Handler {
         @Override
@@ -2844,8 +2848,6 @@
                     return "MSG_PROCESS_INPUT_EVENTS";
                 case MSG_DISPATCH_SCREEN_STATE:
                     return "MSG_DISPATCH_SCREEN_STATE";
-                case MSG_INVALIDATE_DISPLAY_LIST:
-                    return "MSG_INVALIDATE_DISPLAY_LIST";
                 case MSG_CLEAR_ACCESSIBILITY_FOCUS_HOST:
                     return "MSG_CLEAR_ACCESSIBILITY_FOCUS_HOST";
                 case MSG_DISPATCH_DONE_ANIMATING:
@@ -3052,7 +3054,7 @@
                 handleDragEvent(event);
             } break;
             case MSG_DISPATCH_SYSTEM_UI_VISIBILITY: {
-                handleDispatchSystemUiVisibilityChanged((SystemUiVisibilityInfo)msg.obj);
+                handleDispatchSystemUiVisibilityChanged((SystemUiVisibilityInfo) msg.obj);
             } break;
             case MSG_UPDATE_CONFIGURATION: {
                 Configuration config = (Configuration)msg.obj;
@@ -3066,9 +3068,6 @@
                     handleScreenStateChange(msg.arg1 == 1);
                 }
             } break;
-            case MSG_INVALIDATE_DISPLAY_LIST: {
-                invalidateDisplayLists();
-            } break;
             case MSG_CLEAR_ACCESSIBILITY_FOCUS_HOST: {
                 setAccessibilityFocus(null, null);
             } break;
@@ -4153,6 +4152,7 @@
             }
 
             if (mAdded && !mFirst) {
+                invalidateDisplayLists();
                 destroyHardwareRenderer();
 
                 if (mView != null) {
@@ -4572,19 +4572,6 @@
 
     public void enqueueDisplayList(DisplayList displayList) {
         mDisplayLists.add(displayList);
-
-        mHandler.removeMessages(MSG_INVALIDATE_DISPLAY_LIST);
-        Message msg = mHandler.obtainMessage(MSG_INVALIDATE_DISPLAY_LIST);
-        mHandler.sendMessage(msg);
-    }
-
-    public void dequeueDisplayList(DisplayList displayList) {
-        if (mDisplayLists.remove(displayList)) {
-            displayList.invalidate();
-            if (mDisplayLists.size() == 0) {
-                mHandler.removeMessages(MSG_INVALIDATE_DISPLAY_LIST);
-            }
-        }
     }
 
     public void cancelInvalidate(View view) {
diff --git a/core/java/com/android/internal/util/StateMachine.java b/core/java/com/android/internal/util/StateMachine.java
index 0ede336..3944659 100644
--- a/core/java/com/android/internal/util/StateMachine.java
+++ b/core/java/com/android/internal/util/StateMachine.java
@@ -863,16 +863,19 @@
                 }
             }
 
-            if (mLogRecords.logOnlyTransitions()) {
-                /** Record only if there is a transition */
-                if (destState != null) {
+            // Log only if state machine has not quit
+            if (mSm != null) {
+                if (mLogRecords.logOnlyTransitions()) {
+                    /** Record only if there is a transition */
+                    if (destState != null) {
+                        mLogRecords.add(mMsg, mSm.getLogRecString(mMsg), msgProcessedState,
+                                orgState, destState);
+                    }
+                } else if (recordLogMsg) {
+                    /** Record message */
                     mLogRecords.add(mMsg, mSm.getLogRecString(mMsg), msgProcessedState,
                             orgState, destState);
                 }
-            } else if (recordLogMsg) {
-                /** Record message */
-                mLogRecords.add(mMsg, mSm.getLogRecString(mMsg), msgProcessedState,
-                        orgState, destState);
             }
         }
 
diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml
index d1a7703..cb8d0e5 100644
--- a/core/res/res/values/strings.xml
+++ b/core/res/res/values/strings.xml
@@ -3096,7 +3096,7 @@
     <!-- Choice in the ringtone picker.  If chosen, the default ringtone will be used. This fills in the actual ringtone's title into the message. -->
     <string name="ringtone_default_with_actual">Default ringtone (<xliff:g id="actual_ringtone">%1$s</xliff:g>)</string>
     <!-- Choice in the ringtone picker.  If chosen, there will be silence instead of a ringtone played. -->
-    <string name="ringtone_silent">Silent</string>
+    <string name="ringtone_silent">None</string>
     <!-- The title of the ringtone picker dialog. -->
     <string name="ringtone_picker_title">Ringtones</string>
     <!-- If there is ever a ringtone set for some setting, but that ringtone can no longer be resolved, t his is shown instead.  For example, if the ringtone was on a SD card and it had been removed, this woudl be shown for ringtones on that SD card. -->
diff --git a/services/java/com/android/server/BluetoothManagerService.java b/services/java/com/android/server/BluetoothManagerService.java
index 7f52157..5a2088c 100755
--- a/services/java/com/android/server/BluetoothManagerService.java
+++ b/services/java/com/android/server/BluetoothManagerService.java
@@ -513,8 +513,8 @@
         }
     }
     public String getAddress() {
-        mContext.enforceCallingOrSelfPermission(BLUETOOTH_ADMIN_PERM,
-                                                "Need BLUETOOTH ADMIN permission");
+        mContext.enforceCallingOrSelfPermission(BLUETOOTH_PERM,
+                                                "Need BLUETOOTH permission");
 
         if ((Binder.getCallingUid() != Process.SYSTEM_UID) &&
             (!checkIfCallerIsForegroundUser())) {
@@ -538,8 +538,8 @@
     }
 
     public String getName() {
-        mContext.enforceCallingOrSelfPermission(BLUETOOTH_ADMIN_PERM,
-                                                "Need BLUETOOTH ADMIN permission");
+        mContext.enforceCallingOrSelfPermission(BLUETOOTH_PERM,
+                                                "Need BLUETOOTH permission");
 
         if ((Binder.getCallingUid() != Process.SYSTEM_UID) &&
             (!checkIfCallerIsForegroundUser())) {
diff --git a/services/java/com/android/server/wm/WindowManagerService.java b/services/java/com/android/server/wm/WindowManagerService.java
index dc1121b..45935dd 100644
--- a/services/java/com/android/server/wm/WindowManagerService.java
+++ b/services/java/com/android/server/wm/WindowManagerService.java
@@ -3648,8 +3648,7 @@
                 mStartingIconInTransition = false;
                 mSkipAppTransitionAnimation = false;
                 mH.removeMessages(H.APP_TRANSITION_TIMEOUT);
-                mH.sendMessageDelayed(mH.obtainMessage(H.APP_TRANSITION_TIMEOUT),
-                        5000);
+                mH.sendEmptyMessageDelayed(H.APP_TRANSITION_TIMEOUT, 5000);
             }
         }
     }
@@ -4192,8 +4191,7 @@
                 if (mAppsFreezingScreen == 1) {
                     startFreezingDisplayLocked(false, 0, 0);
                     mH.removeMessages(H.APP_FREEZE_TIMEOUT);
-                    mH.sendMessageDelayed(mH.obtainMessage(H.APP_FREEZE_TIMEOUT),
-                            5000);
+                    mH.sendEmptyMessageDelayed(H.APP_FREEZE_TIMEOUT, 5000);
                 }
             }
             final int N = wtoken.allAppWindows.size();
@@ -4715,8 +4713,7 @@
                 try {
                     startFreezingDisplayLocked(false, exitAnim, enterAnim);
                     mH.removeMessages(H.CLIENT_FREEZE_TIMEOUT);
-                    mH.sendMessageDelayed(mH.obtainMessage(H.CLIENT_FREEZE_TIMEOUT),
-                            5000);
+                    mH.sendEmptyMessageDelayed(H.CLIENT_FREEZE_TIMEOUT, 5000);
                 } finally {
                     Binder.restoreCallingIdentity(origId);
                 }
@@ -4844,7 +4841,7 @@
         }
 
         // Persist setting
-        mH.obtainMessage(H.PERSIST_ANIMATION_SCALE).sendToTarget();
+        mH.sendEmptyMessage(H.PERSIST_ANIMATION_SCALE);
     }
 
     public void setAnimationScales(float[] scales) {
@@ -4866,7 +4863,7 @@
         }
 
         // Persist setting
-        mH.obtainMessage(H.PERSIST_ANIMATION_SCALE).sendToTarget();
+        mH.sendEmptyMessage(H.PERSIST_ANIMATION_SCALE);
     }
 
     private void setAnimatorDurationScale(float scale) {
@@ -4976,8 +4973,7 @@
             hideBootMessagesLocked();
             // If the screen still doesn't come up after 30 seconds, give
             // up and turn it on.
-            Message msg = mH.obtainMessage(H.BOOT_TIMEOUT);
-            mH.sendMessageDelayed(msg, 30*1000);
+            mH.sendEmptyMessageDelayed(H.BOOT_TIMEOUT, 30*1000);
         }
 
         mPolicy.systemBooted();
@@ -5000,7 +4996,7 @@
         if (!mSystemBooted && !mShowingBootMessages) {
             return;
         }
-        mH.sendMessage(mH.obtainMessage(H.ENABLE_SCREEN));
+        mH.sendEmptyMessage(H.ENABLE_SCREEN);
     }
 
     public void performBootTimeout() {
@@ -5562,7 +5558,7 @@
 
         mWindowsFreezingScreen = true;
         mH.removeMessages(H.WINDOW_FREEZE_TIMEOUT);
-        mH.sendMessageDelayed(mH.obtainMessage(H.WINDOW_FREEZE_TIMEOUT),
+        mH.sendEmptyMessageDelayed(H.WINDOW_FREEZE_TIMEOUT,
                 WINDOW_FREEZE_TIMEOUT_DURATION);
         mWaitingForConfig = true;
         getDefaultDisplayContentLocked().layoutNeeded = true;
@@ -6949,8 +6945,7 @@
                             if (mAnimator.mAnimating || mLayoutToAnim.mAnimationScheduled) {
                                 // If we are animating, don't do the gc now but
                                 // delay a bit so we don't interrupt the animation.
-                                mH.sendMessageDelayed(mH.obtainMessage(H.FORCE_GC),
-                                        2000);
+                                sendEmptyMessageDelayed(H.FORCE_GC, 2000);
                                 return;
                             }
                             // If we are currently rotating the display, it will
@@ -7075,7 +7070,7 @@
                     // Used to send multiple changes from the animation side to the layout side.
                     synchronized (mWindowMap) {
                         if (copyAnimToLayoutParamsLocked()) {
-                            mH.sendEmptyMessage(CLEAR_PENDING_ACTIONS);
+                            sendEmptyMessage(CLEAR_PENDING_ACTIONS);
                             performLayoutAndPlaceSurfacesLocked();
                         }
                     }
@@ -7637,7 +7632,7 @@
 
             if (mWindowsChanged && !mWindowChangeListeners.isEmpty()) {
                 mH.removeMessages(H.REPORT_WINDOWS_CHANGE);
-                mH.sendMessage(mH.obtainMessage(H.REPORT_WINDOWS_CHANGE));
+                mH.sendEmptyMessage(H.REPORT_WINDOWS_CHANGE);
             }
         } catch (RuntimeException e) {
             mInLayout = false;
@@ -7832,8 +7827,8 @@
                 // XXX should probably keep timeout from
                 // when we first froze the display.
                 mH.removeMessages(H.WINDOW_FREEZE_TIMEOUT);
-                mH.sendMessageDelayed(mH.obtainMessage(
-                        H.WINDOW_FREEZE_TIMEOUT), WINDOW_FREEZE_TIMEOUT_DURATION);
+                mH.sendEmptyMessageDelayed(H.WINDOW_FREEZE_TIMEOUT, 
+                        WINDOW_FREEZE_TIMEOUT_DURATION);
             }
         }
     }
@@ -9515,8 +9510,7 @@
         // processes holds on others can be released if they are
         // no longer needed.
         mH.removeMessages(H.FORCE_GC);
-        mH.sendMessageDelayed(mH.obtainMessage(H.FORCE_GC),
-                2000);
+        mH.sendEmptyMessageDelayed(H.FORCE_GC, 2000);
 
         mScreenFrozenLock.release();