diff --git a/src/com/android/launcher3/Launcher.java b/src/com/android/launcher3/Launcher.java index 9d31492daf..7688b9d092 100644 --- a/src/com/android/launcher3/Launcher.java +++ b/src/com/android/launcher3/Launcher.java @@ -908,14 +908,6 @@ public class Launcher extends BaseActivity mWaitingForResume.setStayPressed(false); } - // It is possible that widgets can receive updates while launcher is not in the foreground. - // Consequently, the widgets will be inflated in the orientation of the foreground activity - // (framework issue). On resuming, we ensure that any widgets are inflated for the current - // orientation. - if (!isWorkspaceLoading()) { - getWorkspace().reinflateWidgetsIfNecessary(); - } - updateInteraction(Workspace.State.NORMAL, mWorkspace.getState()); mWorkspace.onResume(); @@ -3257,7 +3249,10 @@ public class Launcher extends BaseActivity info.pendingItemInfo = null; } - mWorkspace.reinflateWidgetsIfNecessary(); + if (((PendingAppWidgetHostView) view).isReinflateIfNeeded()) { + view.reinflate(); + } + getModelWriter().updateItemInDatabase(info); return info; } diff --git a/src/com/android/launcher3/LauncherAppWidgetHost.java b/src/com/android/launcher3/LauncherAppWidgetHost.java index 819f23faeb..70440fa309 100644 --- a/src/com/android/launcher3/LauncherAppWidgetHost.java +++ b/src/com/android/launcher3/LauncherAppWidgetHost.java @@ -122,7 +122,6 @@ public class LauncherAppWidgetHost extends AppWidgetHost { context.getSystemService(Context.LAYOUT_INFLATER_SERVICE); inflater.inflate(appWidget.initialLayout, lahv); lahv.setAppWidget(0, appWidget); - lahv.updateLastInflationOrientation(); return lahv; } else { try { diff --git a/src/com/android/launcher3/LauncherAppWidgetHostView.java b/src/com/android/launcher3/LauncherAppWidgetHostView.java index 7fe1308764..6f953e5f0a 100644 --- a/src/com/android/launcher3/LauncherAppWidgetHostView.java +++ b/src/com/android/launcher3/LauncherAppWidgetHostView.java @@ -19,6 +19,7 @@ package com.android.launcher3; import android.appwidget.AppWidgetHostView; import android.appwidget.AppWidgetProviderInfo; import android.content.Context; +import android.content.res.Configuration; import android.graphics.PointF; import android.graphics.Rect; import android.os.Handler; @@ -58,10 +59,14 @@ public class LauncherAppWidgetHostView extends AppWidgetHostView private final CheckLongPressHelper mLongPressHelper; private final StylusEventHelper mStylusEventHelper; - private final Context mContext; + private final Launcher mLauncher; + + private static final int DONT_REINFLATE = 0; + private static final int REINFLATE_ON_RESUME = 1; + private static final int REINFLATE_ON_CONFIG_CHANGE = 2; @ViewDebug.ExportedProperty(category = "launcher") - private int mPreviousOrientation; + private int mReinflateStatus; private float mSlop; @@ -85,11 +90,11 @@ public class LauncherAppWidgetHostView extends AppWidgetHostView public LauncherAppWidgetHostView(Context context) { super(context); - mContext = context; + mLauncher = Launcher.getLauncher(context); mLongPressHelper = new CheckLongPressHelper(this, this); mStylusEventHelper = new StylusEventHelper(new SimpleOnStylusPressListener(this), this); mInflater = LayoutInflater.from(context); - setAccessibilityDelegate(Launcher.getLauncher(context).getAccessibilityDelegate()); + setAccessibilityDelegate(mLauncher.getAccessibilityDelegate()); setBackgroundResource(R.drawable.widget_internal_focus_bg); if (Utilities.ATLEAST_OREO) { @@ -112,18 +117,28 @@ public class LauncherAppWidgetHostView extends AppWidgetHostView return mInflater.inflate(R.layout.appwidget_error, this, false); } - public void updateLastInflationOrientation() { - mPreviousOrientation = mContext.getResources().getConfiguration().orientation; - } - @Override public void updateAppWidget(RemoteViews remoteViews) { - // Store the orientation in which the widget was inflated - updateLastInflationOrientation(); super.updateAppWidget(remoteViews); // The provider info or the views might have changed. checkIfAutoAdvance(); + + // It is possible that widgets can receive updates while launcher is not in the foreground. + // Consequently, the widgets will be inflated for the orientation of the foreground activity + // (framework issue). On resuming, we ensure that any widgets are inflated for the current + // orientation. + if (mReinflateStatus == DONT_REINFLATE && !isSameOrientation()) { + mReinflateStatus = REINFLATE_ON_RESUME; + if (!mLauncher.waitUntilResume(new ReInflateRunnable())) { + mReinflateStatus = REINFLATE_ON_CONFIG_CHANGE; + } + } + } + + private boolean isSameOrientation() { + return mLauncher.getResources().getConfiguration().orientation == + mLauncher.getOrientation(); } private boolean checkScrollableRecursively(ViewGroup viewGroup) { @@ -142,14 +157,6 @@ public class LauncherAppWidgetHostView extends AppWidgetHostView return false; } - public boolean isReinflateRequired(int orientation) { - // Re-inflate is required if the orientation has changed since last inflated. - if (mPreviousOrientation != orientation) { - return true; - } - return false; - } - public boolean onInterceptTouchEvent(MotionEvent ev) { // Just in case the previous long press hasn't been cleared, we make sure to start fresh // on touch down. @@ -473,4 +480,45 @@ public class LauncherAppWidgetHostView extends AppWidgetHostView public PointF getTranslationForCentering() { return mTranslationForCentering; } + + @Override + protected void onConfigurationChanged(Configuration newConfig) { + super.onConfigurationChanged(newConfig); + + if (mReinflateStatus == REINFLATE_ON_CONFIG_CHANGE) { + // We are finally in the same orientation + reinflateIfNecessary(); + } + } + + private void reinflateIfNecessary() { + if (!isSameOrientation()) { + // We cannot reinflate yet, wait until next config change + mReinflateStatus = REINFLATE_ON_CONFIG_CHANGE; + return; + } + + mReinflateStatus = DONT_REINFLATE; + if (isAttachedToWindow()) { + LauncherAppWidgetInfo info = (LauncherAppWidgetInfo) getTag(); + reinflate(); + } + } + + public void reinflate() { + LauncherAppWidgetInfo info = (LauncherAppWidgetInfo) getTag(); + // Remove and rebind the current widget (which was inflated in the wrong + // orientation), but don't delete it from the database + mLauncher.removeItem(this, info, false /* deleteFromDb */); + mLauncher.bindAppWidget(info); + } + + private class ReInflateRunnable implements Runnable { + @Override + public void run() { + if (mReinflateStatus == REINFLATE_ON_RESUME) { + reinflateIfNecessary(); + } + } + } } diff --git a/src/com/android/launcher3/PendingAppWidgetHostView.java b/src/com/android/launcher3/PendingAppWidgetHostView.java index c2d5501693..b86d413185 100644 --- a/src/com/android/launcher3/PendingAppWidgetHostView.java +++ b/src/com/android/launcher3/PendingAppWidgetHostView.java @@ -110,9 +110,7 @@ public class PendingAppWidgetHostView extends LauncherAppWidgetHostView mClickListener = l; } - @Override - public boolean isReinflateRequired(int orientation) { - // Re inflate is required any time the widget restore status changes + public boolean isReinflateIfNeeded() { return mStartState != mInfo.restoreStatus; } diff --git a/src/com/android/launcher3/Workspace.java b/src/com/android/launcher3/Workspace.java index b80bdc0c96..7297ee12e9 100644 --- a/src/com/android/launcher3/Workspace.java +++ b/src/com/android/launcher3/Workspace.java @@ -1043,30 +1043,6 @@ public class Workspace extends PagedView return super.onInterceptTouchEvent(ev); } - protected void reinflateWidgetsIfNecessary() { - final int clCount = getChildCount(); - for (int i = 0; i < clCount; i++) { - CellLayout cl = (CellLayout) getChildAt(i); - ShortcutAndWidgetContainer swc = cl.getShortcutsAndWidgets(); - final int itemCount = swc.getChildCount(); - for (int j = 0; j < itemCount; j++) { - View v = swc.getChildAt(j); - - if (v instanceof LauncherAppWidgetHostView - && v.getTag() instanceof LauncherAppWidgetInfo) { - LauncherAppWidgetInfo info = (LauncherAppWidgetInfo) v.getTag(); - LauncherAppWidgetHostView lahv = (LauncherAppWidgetHostView) v; - if (lahv.isReinflateRequired(mLauncher.getOrientation())) { - // Remove and rebind the current widget (which was inflated in the wrong - // orientation), but don't delete it from the database - mLauncher.removeItem(lahv, info, false /* deleteFromDb */); - mLauncher.bindAppWidget(info); - } - } - } - } - } - @Override protected void determineScrollingStart(MotionEvent ev) { if (!isFinishedSwitchingState()) return;