diff options
author | Sunny Goyal <sunnygoyal@google.com> | 2016-09-25 21:23:25 -0700 |
---|---|---|
committer | Sunny Goyal <sunnygoyal@google.com> | 2016-09-30 11:18:38 -0700 |
commit | 1acc56a4eb9a74f28e32eadf62f389d3221b50ff (patch) | |
tree | cd4abe2d544e7b08b7c08bcaae0d6cda4e26d382 /src/com/android/launcher3/LauncherAppWidgetHostView.java | |
parent | de45283519570477b2c01feaa12e19e53cf0b57d (diff) | |
download | android_packages_apps_Trebuchet-1acc56a4eb9a74f28e32eadf62f389d3221b50ff.tar.gz android_packages_apps_Trebuchet-1acc56a4eb9a74f28e32eadf62f389d3221b50ff.tar.bz2 android_packages_apps_Trebuchet-1acc56a4eb9a74f28e32eadf62f389d3221b50ff.zip |
Moving the widget auto-advance logic to AppWidgetHostView instead of
handling it in launcher
This fixes the bug where launcher ignores auto-advance property changes
during app update or widget remote views update as well as simplifies
widget management
On potential downside of this refactoring is that the auto advance will
keep running even when all-apps or widgets tray is open. We could
eventually use onVisibilityAggregated to handle visibility changes,
but currenly the workspace visibility is not being updated properly
in these cases
Change-Id: Ie7331fec1877f43ad23e634d37571d8f3ef51e59
Diffstat (limited to 'src/com/android/launcher3/LauncherAppWidgetHostView.java')
-rw-r--r-- | src/com/android/launcher3/LauncherAppWidgetHostView.java | 110 |
1 files changed, 106 insertions, 4 deletions
diff --git a/src/com/android/launcher3/LauncherAppWidgetHostView.java b/src/com/android/launcher3/LauncherAppWidgetHostView.java index ed1079ff3..fa5e519b1 100644 --- a/src/com/android/launcher3/LauncherAppWidgetHostView.java +++ b/src/com/android/launcher3/LauncherAppWidgetHostView.java @@ -20,6 +20,9 @@ import android.appwidget.AppWidgetHostView; import android.appwidget.AppWidgetProviderInfo; import android.content.Context; import android.graphics.Rect; +import android.os.Handler; +import android.os.SystemClock; +import android.util.SparseBooleanArray; import android.view.KeyEvent; import android.view.LayoutInflater; import android.view.MotionEvent; @@ -28,6 +31,7 @@ import android.view.ViewConfiguration; import android.view.ViewDebug; import android.view.ViewGroup; import android.view.accessibility.AccessibilityNodeInfo; +import android.widget.Advanceable; import android.widget.RemoteViews; import com.android.launcher3.dragndrop.DragLayer.TouchCompleteListener; @@ -39,6 +43,13 @@ import java.util.ArrayList; */ public class LauncherAppWidgetHostView extends AppWidgetHostView implements TouchCompleteListener { + // Related to the auto-advancing of widgets + private static final long ADVANCE_INTERVAL = 20000; + private static final long ADVANCE_STAGGER = 250; + + // Maintains a list of widget ids which are supposed to be auto advanced. + private static final SparseBooleanArray sAutoAdvanceWidgetIds = new SparseBooleanArray(); + LayoutInflater mInflater; private CheckLongPressHelper mLongPressHelper; @@ -54,6 +65,10 @@ public class LauncherAppWidgetHostView extends AppWidgetHostView implements Touc protected int mErrorViewId = R.layout.appwidget_error; + private boolean mIsAttachedToWindow; + private boolean mIsAutoAdvanceRegistered; + private Runnable mAutoAdvanceRunnable; + public LauncherAppWidgetHostView(Context context) { super(context); mContext = context; @@ -78,6 +93,9 @@ public class LauncherAppWidgetHostView extends AppWidgetHostView implements Touc // Store the orientation in which the widget was inflated updateLastInflationOrientation(); super.updateAppWidget(remoteViews); + + // The provider info or the views might have changed. + checkIfAutoAdvance(); } public boolean isReinflateRequired() { @@ -153,6 +171,19 @@ public class LauncherAppWidgetHostView extends AppWidgetHostView implements Touc protected void onAttachedToWindow() { super.onAttachedToWindow(); mSlop = ViewConfiguration.get(getContext()).getScaledTouchSlop(); + + mIsAttachedToWindow = true; + checkIfAutoAdvance(); + } + + @Override + protected void onDetachedFromWindow() { + super.onDetachedFromWindow(); + + // We can't directly use isAttachedToWindow() here, as this is called before the internal + // state is updated. So isAttachedToWindow() will return true until next frame. + mIsAttachedToWindow = false; + checkIfAutoAdvance(); } @Override @@ -171,10 +202,6 @@ public class LauncherAppWidgetHostView extends AppWidgetHostView implements Touc return info; } - public LauncherAppWidgetProviderInfo getLauncherAppWidgetProviderInfo() { - return (LauncherAppWidgetProviderInfo) getAppWidgetInfo(); - } - @Override public void onTouchComplete() { if (!mLongPressHelper.hasPerformedLongPress()) { @@ -296,4 +323,79 @@ public class LauncherAppWidgetHostView extends AppWidgetHostView implements Touc super.onInitializeAccessibilityNodeInfo(info); info.setClassName(getClass().getName()); } + + @Override + protected void onWindowVisibilityChanged(int visibility) { + super.onWindowVisibilityChanged(visibility); + maybeRegisterAutoAdvance(); + } + + private void checkIfAutoAdvance() { + boolean isAutoAdvance = false; + Advanceable target = getAdvanceable(); + if (target != null) { + isAutoAdvance = true; + target.fyiWillBeAdvancedByHostKThx(); + } + + boolean wasAutoAdvance = sAutoAdvanceWidgetIds.indexOfKey(getAppWidgetId()) >= 0; + if (isAutoAdvance != wasAutoAdvance) { + if (isAutoAdvance) { + sAutoAdvanceWidgetIds.put(getAppWidgetId(), true); + } else { + sAutoAdvanceWidgetIds.delete(getAppWidgetId()); + } + maybeRegisterAutoAdvance(); + } + } + + private Advanceable getAdvanceable() { + AppWidgetProviderInfo info = getAppWidgetInfo(); + if (info == null || info.autoAdvanceViewId == NO_ID || !mIsAttachedToWindow) { + return null; + } + View v = findViewById(info.autoAdvanceViewId); + return (v instanceof Advanceable) ? (Advanceable) v : null; + } + + private void maybeRegisterAutoAdvance() { + Handler handler = getHandler(); + boolean shouldRegisterAutoAdvance = getWindowVisibility() == VISIBLE && handler != null + && (sAutoAdvanceWidgetIds.indexOfKey(getAppWidgetId()) >= 0); + if (shouldRegisterAutoAdvance != mIsAutoAdvanceRegistered) { + mIsAutoAdvanceRegistered = shouldRegisterAutoAdvance; + if (mAutoAdvanceRunnable == null) { + mAutoAdvanceRunnable = new Runnable() { + @Override + public void run() { + runAutoAdvance(); + } + }; + } + + handler.removeCallbacks(mAutoAdvanceRunnable); + scheduleNextAdvance(); + } + } + + private void scheduleNextAdvance() { + if (!mIsAutoAdvanceRegistered) { + return; + } + long now = SystemClock.uptimeMillis(); + long advanceTime = now + (ADVANCE_INTERVAL - (now % ADVANCE_INTERVAL)) + + ADVANCE_STAGGER * sAutoAdvanceWidgetIds.indexOfKey(getAppWidgetId()); + Handler handler = getHandler(); + if (handler != null) { + handler.postAtTime(mAutoAdvanceRunnable, advanceTime); + } + } + + private void runAutoAdvance() { + Advanceable target = getAdvanceable(); + if (target != null) { + target.advance(); + } + scheduleNextAdvance(); + } } |