diff options
-rw-r--r-- | src/com/android/launcher3/Launcher.java | 118 | ||||
-rw-r--r-- | src/com/android/launcher3/LauncherAppWidgetHostView.java | 110 |
2 files changed, 110 insertions, 118 deletions
diff --git a/src/com/android/launcher3/Launcher.java b/src/com/android/launcher3/Launcher.java index f825e212c..5841bf5b6 100644 --- a/src/com/android/launcher3/Launcher.java +++ b/src/com/android/launcher3/Launcher.java @@ -30,7 +30,6 @@ import android.app.AlertDialog; import android.app.SearchManager; import android.appwidget.AppWidgetHostView; import android.appwidget.AppWidgetManager; -import android.appwidget.AppWidgetProviderInfo; import android.content.ActivityNotFoundException; import android.content.BroadcastReceiver; import android.content.ComponentCallbacks2; @@ -56,7 +55,6 @@ import android.os.AsyncTask; import android.os.Build; import android.os.Bundle; import android.os.Handler; -import android.os.Message; import android.os.StrictMode; import android.os.SystemClock; import android.os.Trace; @@ -84,7 +82,6 @@ import android.view.accessibility.AccessibilityManager; import android.view.accessibility.AccessibilityNodeInfo; import android.view.animation.OvershootInterpolator; import android.view.inputmethod.InputMethodManager; -import android.widget.Advanceable; import android.widget.ImageView; import android.widget.TextView; import android.widget.Toast; @@ -278,27 +275,16 @@ public class Launcher extends Activity private IconCache mIconCache; private ExtractedColors mExtractedColors; private LauncherAccessibilityDelegate mAccessibilityDelegate; + private Handler mHandler = new Handler(); private boolean mIsResumeFromActionScreenOff; - @Thunk boolean mUserPresent = true; - private boolean mVisible; - private boolean mHasFocus; - private boolean mAttached; + private boolean mHasFocus = false; + private boolean mAttached = false; /** Maps launcher activity components to their list of shortcut ids. */ private MultiHashMap<ComponentKey, String> mDeepShortcutMap = new MultiHashMap<>(); private View.OnTouchListener mHapticFeedbackTouchListener; - // Related to the auto-advancing of widgets - private final int ADVANCE_MSG = 1; - private static final int ADVANCE_INTERVAL = 20000; - private static final int ADVANCE_STAGGER = 250; - - private boolean mAutoAdvanceRunning = false; - private long mAutoAdvanceSentTime; - private long mAutoAdvanceTimeLeft = -1; - @Thunk HashMap<View, AppWidgetProviderInfo> mWidgetsToAdvance = new HashMap<>(); - // Determines how long to wait after a rotation before restoring the screen orientation to // match the sensor state. private static final int RESTORE_SCREEN_ORIENTATION_DELAY = 500; @@ -1572,10 +1558,6 @@ public class Launcher extends Activity mWorkspace.addInScreen(hostView, item.container, item.screenId, item.cellX, item.cellY, item.spanX, item.spanY, insert); - - if (!item.isCustomWidget()) { - addWidgetToAutoAdvanceIfNeeded(hostView, appWidgetInfo); - } } private final BroadcastReceiver mReceiver = new BroadcastReceiver() { @@ -1583,9 +1565,7 @@ public class Launcher extends Activity public void onReceive(Context context, Intent intent) { final String action = intent.getAction(); if (Intent.ACTION_SCREEN_OFF.equals(action)) { - mUserPresent = false; mDragLayer.clearResizeFrame(); - updateAutoAdvanceState(); // Reset AllApps to its initial state only if we are not in the middle of // processing a multi-step drop @@ -1596,9 +1576,6 @@ public class Launcher extends Activity } } mIsResumeFromActionScreenOff = true; - } else if (Intent.ACTION_USER_PRESENT.equals(action)) { - mUserPresent = true; - updateAutoAdvanceState(); } } }; @@ -1610,11 +1587,9 @@ public class Launcher extends Activity // Listen for broadcasts related to user-presence final IntentFilter filter = new IntentFilter(); filter.addAction(Intent.ACTION_SCREEN_OFF); - filter.addAction(Intent.ACTION_USER_PRESENT); registerReceiver(mReceiver, filter); FirstFrameAnimatorHelper.initializeDrawListener(getWindow().getDecorView()); mAttached = true; - mVisible = true; if (mLauncherCallbacks != null) { mLauncherCallbacks.onAttachedToWindow(); @@ -1624,13 +1599,10 @@ public class Launcher extends Activity @Override public void onDetachedFromWindow() { super.onDetachedFromWindow(); - mVisible = false; - if (mAttached) { unregisterReceiver(mReceiver); mAttached = false; } - updateAutoAdvanceState(); if (mLauncherCallbacks != null) { mLauncherCallbacks.onDetachedFromWindow(); @@ -1638,12 +1610,10 @@ public class Launcher extends Activity } public void onWindowVisibilityChanged(int visibility) { - mVisible = visibility == View.VISIBLE; - updateAutoAdvanceState(); // The following code used to be in onResume, but it turns out onResume is called when // you're in All Apps and click home to go to the workspace. onWindowVisibilityChanged // is a more appropriate event to handle - if (mVisible) { + if (visibility == View.VISIBLE) { if (!mWorkspaceLoading) { final ViewTreeObserver observer = mWorkspace.getViewTreeObserver(); // We want to let Launcher draw itself at least once before we force it to build @@ -1678,72 +1648,6 @@ public class Launcher extends Activity } } - @Thunk void sendAdvanceMessage(long delay) { - mHandler.removeMessages(ADVANCE_MSG); - Message msg = mHandler.obtainMessage(ADVANCE_MSG); - mHandler.sendMessageDelayed(msg, delay); - mAutoAdvanceSentTime = System.currentTimeMillis(); - } - - @Thunk void updateAutoAdvanceState() { - boolean autoAdvanceRunning = mVisible && mUserPresent && !mWidgetsToAdvance.isEmpty(); - if (autoAdvanceRunning != mAutoAdvanceRunning) { - mAutoAdvanceRunning = autoAdvanceRunning; - if (autoAdvanceRunning) { - long delay = mAutoAdvanceTimeLeft == -1 ? ADVANCE_INTERVAL : mAutoAdvanceTimeLeft; - sendAdvanceMessage(delay); - } else { - if (!mWidgetsToAdvance.isEmpty()) { - mAutoAdvanceTimeLeft = Math.max(0, ADVANCE_INTERVAL - - (System.currentTimeMillis() - mAutoAdvanceSentTime)); - } - mHandler.removeMessages(ADVANCE_MSG); - mHandler.removeMessages(0); // Remove messages sent using postDelayed() - } - } - } - - @Thunk final Handler mHandler = new Handler(new Handler.Callback() { - - @Override - public boolean handleMessage(Message msg) { - if (msg.what == ADVANCE_MSG) { - int i = 0; - for (View key: mWidgetsToAdvance.keySet()) { - final View v = key.findViewById(mWidgetsToAdvance.get(key).autoAdvanceViewId); - final int delay = ADVANCE_STAGGER * i; - if (v instanceof Advanceable) { - mHandler.postDelayed(new Runnable() { - public void run() { - ((Advanceable) v).advance(); - } - }, delay); - } - i++; - } - sendAdvanceMessage(ADVANCE_INTERVAL); - } - return true; - } - }); - - private void addWidgetToAutoAdvanceIfNeeded(View hostView, AppWidgetProviderInfo appWidgetInfo) { - if (appWidgetInfo == null || appWidgetInfo.autoAdvanceViewId == -1) return; - View v = hostView.findViewById(appWidgetInfo.autoAdvanceViewId); - if (v instanceof Advanceable) { - mWidgetsToAdvance.put(hostView, appWidgetInfo); - ((Advanceable) v).fyiWillBeAdvancedByHostKThx(); - updateAutoAdvanceState(); - } - } - - private void removeWidgetToAutoAdvance(View hostView) { - if (mWidgetsToAdvance.containsKey(hostView)) { - mWidgetsToAdvance.remove(hostView); - updateAutoAdvanceState(); - } - } - public void showOutOfSpaceMessage(boolean isHotseatLayout) { int strId = (isHotseatLayout ? R.string.hotseat_out_of_space : R.string.out_of_space); Toast.makeText(this, getString(strId), Toast.LENGTH_SHORT).show(); @@ -1938,9 +1842,6 @@ public class Launcher extends Activity public void onDestroy() { super.onDestroy(); - // Remove all pending runnables - mHandler.removeMessages(ADVANCE_MSG); - mHandler.removeMessages(0); mWorkspace.removeCallbacks(mBuildLayersRunnable); mWorkspace.removeFolderListeners(); @@ -1963,8 +1864,6 @@ public class Launcher extends Activity } mAppWidgetHost = null; - mWidgetsToAdvance.clear(); - TextKeyListener.getInstance().release(); ((AccessibilityManager) getSystemService(ACCESSIBILITY_SERVICE)) @@ -2284,7 +2183,6 @@ public class Launcher extends Activity } else if (itemInfo instanceof LauncherAppWidgetInfo) { final LauncherAppWidgetInfo widgetInfo = (LauncherAppWidgetInfo) itemInfo; mWorkspace.removeWorkspaceItem(v); - removeWidgetToAutoAdvance(v); if (deleteFromDb) { deleteWidgetInfo(widgetInfo); } @@ -3233,10 +3131,6 @@ public class Launcher extends Activity // Change the state *after* we've called all the transition code mState = State.WORKSPACE; - // Resume the auto-advance of widgets - mUserPresent = true; - updateAutoAdvanceState(); - if (changed) { // Send an accessibility event to announce the context change getWindow().getDecorView() @@ -3342,9 +3236,6 @@ public class Launcher extends Activity // Change the state *after* we've called all the transition code mState = toState; - // Pause the auto-advance of widgets until we are out of AllApps - mUserPresent = false; - updateAutoAdvanceState(); closeFolder(); closeShortcutsContainer(); @@ -3570,7 +3461,6 @@ public class Launcher extends Activity mWorkspace.clearDropTargets(); mWorkspace.removeAllWorkspaceScreens(); - mWidgetsToAdvance.clear(); if (mHotseat != null) { mHotseat.resetLayout(); } 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(); + } } |