am 42164efa: Merge "Ensuring bindAppWidget isn\'t called until boot completed (issue 7469267)" into jb-mr1-lockscreen-dev

* commit '42164efac3f4422e66d176de24e1a0857cacabab':
  Ensuring bindAppWidget isn't called until boot completed (issue 7469267)
diff --git a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardHostView.java b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardHostView.java
index 2d63ef8..1ee0e86 100644
--- a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardHostView.java
+++ b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardHostView.java
@@ -75,6 +75,9 @@
     private SecurityMode mCurrentSecuritySelection = SecurityMode.Invalid;
     private int mAppWidgetToShow;
 
+    private boolean mBootCompleted = false;
+    private boolean mCheckAppWidgetConsistencyOnBootCompleted = false;
+
     protected Runnable mLaunchRunnable;
 
     protected int mFailedAttempts;
@@ -140,6 +143,19 @@
         }
     }
 
+    private KeyguardUpdateMonitorCallback mUpdateMonitorCallbacks =
+            new KeyguardUpdateMonitorCallback() {
+        @Override
+        public void onBootCompleted() {
+            mBootCompleted = true;
+            if (mCheckAppWidgetConsistencyOnBootCompleted) {
+                checkAppWidgetConsistency();
+                mSwitchPageRunnable.run();
+                mCheckAppWidgetConsistencyOnBootCompleted = false;
+            }
+        }
+    };
+
     @Override
     public boolean onTouchEvent(MotionEvent ev) {
         boolean result = super.onTouchEvent(ev);
@@ -263,12 +279,14 @@
     protected void onAttachedToWindow() {
         super.onAttachedToWindow();
         mAppWidgetHost.startListening();
+        KeyguardUpdateMonitor.getInstance(mContext).registerCallback(mUpdateMonitorCallbacks);
     }
 
     @Override
     protected void onDetachedFromWindow() {
         super.onDetachedFromWindow();
         mAppWidgetHost.stopListening();
+        KeyguardUpdateMonitor.getInstance(mContext).removeCallback(mUpdateMonitorCallbacks);
     }
 
     private AppWidgetHost getAppWidgetHost() {
@@ -1086,8 +1104,13 @@
         }
         return appWidgetId;
     }
-
     public void checkAppWidgetConsistency() {
+        // Since this method may bind a widget (which we can't do until boot completed) we
+        // may have to defer it until after boot complete.
+        if (!mBootCompleted) {
+            mCheckAppWidgetConsistencyOnBootCompleted = true;
+            return;
+        }
         final int childCount = mAppWidgetContainer.getChildCount();
         boolean widgetPageExists = false;
         for (int i = 0; i < childCount; i++) {
diff --git a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardUpdateMonitor.java b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardUpdateMonitor.java
index 5fb8cf0..51f0418 100644
--- a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardUpdateMonitor.java
+++ b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardUpdateMonitor.java
@@ -81,6 +81,8 @@
     private static final int MSG_USER_SWITCHED = 310;
     private static final int MSG_USER_REMOVED = 311;
     private static final int MSG_KEYGUARD_VISIBILITY_CHANGED = 312;
+    protected static final int MSG_BOOT_COMPLETED = 313;
+
 
     private static KeyguardUpdateMonitor sInstance;
 
@@ -152,6 +154,9 @@
                 case MSG_KEYGUARD_VISIBILITY_CHANGED:
                     handleKeyguardVisibilityChanged(msg.arg1);
                     break;
+                case MSG_BOOT_COMPLETED:
+                    handleBootCompleted();
+                    break;
 
             }
         }
@@ -198,6 +203,8 @@
             } else if (Intent.ACTION_USER_REMOVED.equals(action)) {
                 mHandler.sendMessage(mHandler.obtainMessage(MSG_USER_REMOVED,
                        intent.getIntExtra(Intent.EXTRA_USER_HANDLE, 0), 0));
+            } else if (Intent.ACTION_BOOT_COMPLETED.equals(action)) {
+                mHandler.sendMessage(mHandler.obtainMessage(MSG_BOOT_COMPLETED));
             }
         }
     };
@@ -340,6 +347,7 @@
         filter.addAction(AudioManager.RINGER_MODE_CHANGED_ACTION);
         filter.addAction(DevicePolicyManager.ACTION_DEVICE_POLICY_MANAGER_STATE_CHANGED);
         filter.addAction(Intent.ACTION_USER_REMOVED);
+        filter.addAction(Intent.ACTION_BOOT_COMPLETED);
         context.registerReceiver(mBroadcastReceiver, filter);
 
         try {
@@ -420,6 +428,18 @@
     }
 
     /**
+     * Handle {@link #MSG_BOOT_COMPLETED}
+     */
+    protected void handleBootCompleted() {
+        for (int i = 0; i < mCallbacks.size(); i++) {
+            KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
+            if (cb != null) {
+                cb.onBootCompleted();
+            }
+        }
+    }
+
+    /**
      * Handle {@link #MSG_USER_SWITCHED}
      */
     protected void handleUserRemoved(int userId) {
diff --git a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardUpdateMonitorCallback.java b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardUpdateMonitorCallback.java
index 8c9ac8b..1ba1388 100644
--- a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardUpdateMonitorCallback.java
+++ b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardUpdateMonitorCallback.java
@@ -99,4 +99,12 @@
      * Called when a user is removed.
      */
     void onUserRemoved(int userId) { }
+
+    /**
+     * Called when boot completed.
+     *
+     * Note, this callback will only be received if boot complete occurs after registering with
+     * KeyguardUpdateMonitor.
+     */
+    void onBootCompleted() { }
 }