OSDN Git Service

Fix dodgy states of keyguard transport controls
authorAdam Powell <adamp@google.com>
Tue, 15 Oct 2013 22:30:06 +0000 (15:30 -0700)
committerAdam Powell <adamp@google.com>
Wed, 16 Oct 2013 01:10:41 +0000 (18:10 -0700)
If a layout has already been requested when we want to show the
correct widget pane, post the event for later and immediately return.

This works because PagedView has some interesting ideas about
maintaining a consistent state. It will attempt to recalculate the
current page position during measurement, but thanks to a reliance on
this measurement to establish scrolling boundaries that scrollTo uses
for clamping plus other code that depends on the idea that it can add
a new widget pane view and immediately scroll to it, this attempt to
scroll fails if the target page was added and measurement is not yet
complete. This patch ensures we don't hit these edge cases in a few
known ways.

While this ends things in the correct state, it predictably has a few
visual artifacts. Situations where things would completely fail
before, positioning pages incorrectly or fading out wrong pages now
will briefly flash and fade the widget frames or in some cases will
visibly animate from the starting page to the correct one. We should
address these issues in a future release.

Bug 11217368
Bug 9760604

Change-Id: I989d03b5bfdd5b6403a6b67a8aae7585ca0c8ae0

packages/Keyguard/src/com/android/keyguard/KeyguardHostView.java
packages/Keyguard/src/com/android/keyguard/KeyguardWidgetPager.java

index fdc06a6..e94cf18 100644 (file)
 
 package com.android.keyguard;
 
-import com.android.internal.widget.LockPatternUtils;
-import com.android.keyguard.KeyguardSecurityModel.SecurityMode;
-import com.android.keyguard.KeyguardUpdateMonitor.DisplayClientState;
-
 import android.app.Activity;
 import android.app.ActivityManager;
 import android.app.ActivityOptions;
@@ -55,6 +51,9 @@ import android.view.MotionEvent;
 import android.view.View;
 import android.view.WindowManager;
 import android.widget.RemoteViews.OnClickHandler;
+import com.android.internal.widget.LockPatternUtils;
+import com.android.keyguard.KeyguardSecurityModel.SecurityMode;
+import com.android.keyguard.KeyguardUpdateMonitor.DisplayClientState;
 
 import java.io.File;
 import java.lang.ref.WeakReference;
@@ -280,7 +279,7 @@ public class KeyguardHostView extends KeyguardViewBase {
             if (newState != mTransportState) {
                 mTransportState = newState;
                 if (DEBUGXPORT) Log.v(TAG, "update widget: transport state changed");
-                KeyguardHostView.this.post(mSwitchPageRunnable);
+                KeyguardHostView.this.postShowAppropriateWidgetPage();
             }
         }
         @Override
@@ -292,7 +291,7 @@ public class KeyguardHostView extends KeyguardViewBase {
                 if (newState != mTransportState) {
                     mTransportState = newState;
                     if (DEBUGXPORT) Log.v(TAG, "update widget: play state changed");
-                    KeyguardHostView.this.post(mSwitchPageRunnable);
+                    KeyguardHostView.this.postShowAppropriateWidgetPage();
                 }
             }
         }
@@ -496,6 +495,7 @@ public class KeyguardHostView extends KeyguardViewBase {
     @Override
     protected void onDetachedFromWindow() {
         super.onDetachedFromWindow();
+        removeCallbacks(mSwitchPageRunnable);
         mAppWidgetHost.stopListening();
         KeyguardUpdateMonitor.getInstance(mContext).removeCallback(mUpdateMonitorCallbacks);
     }
@@ -1438,7 +1438,7 @@ public class KeyguardHostView extends KeyguardViewBase {
         mAppWidgetToShow = ss.appWidgetToShow;
         setInsets(ss.insets);
         if (DEBUG) Log.d(TAG, "onRestoreInstanceState, transport=" + mTransportState);
-        post(mSwitchPageRunnable);
+        postShowAppropriateWidgetPage();
     }
 
     @Override
@@ -1471,13 +1471,22 @@ public class KeyguardHostView extends KeyguardViewBase {
         }
     }
 
-    private void showAppropriateWidgetPage() {
+    void showAppropriateWidgetPage() {
         int state = mTransportState;
         ensureTransportPresentOrRemoved(state);
+        if (mAppWidgetContainer.isLayoutRequested()) {
+            postShowAppropriateWidgetPage();
+            return;
+        }
         int pageToShow = getAppropriateWidgetPage(state);
         mAppWidgetContainer.setCurrentPage(pageToShow);
     }
 
+    void postShowAppropriateWidgetPage() {
+        removeCallbacks(mSwitchPageRunnable);
+        post(mSwitchPageRunnable);
+    }
+
     /**
      * Examines the current state and adds the transport to the widget pager when the state changes.
      *
index 704af6e..e07e0d0 100644 (file)
@@ -40,7 +40,6 @@ import android.view.accessibility.AccessibilityManager;
 import android.view.animation.DecelerateInterpolator;
 import android.widget.FrameLayout;
 import android.widget.TextClock;
-
 import com.android.internal.widget.LockPatternUtils;
 
 import java.util.ArrayList;