Merge "Cache and reuses LauncherAppWidgetHostView when launcher resumes" into tm-qpr-dev
This commit is contained in:
@@ -277,6 +277,10 @@ public final class FeatureFlags {
|
||||
"ENABLE_DISMISS_PREDICTION_UNDO", false,
|
||||
"Show an 'Undo' snackbar when users dismiss a predicted hotseat item");
|
||||
|
||||
public static final BooleanFlag ENABLE_CACHED_WIDGET = getDebugFlag(
|
||||
"ENABLE_CACHED_WIDGET", true,
|
||||
"Show previously cached widgets as opposed to deferred widget where available");
|
||||
|
||||
public static void initialize(Context context) {
|
||||
synchronized (sDebugFlags) {
|
||||
for (DebugFlag flag : sDebugFlags) {
|
||||
|
||||
@@ -28,6 +28,7 @@ import android.content.Intent;
|
||||
import android.os.Bundle;
|
||||
import android.os.Handler;
|
||||
import android.util.SparseArray;
|
||||
import android.widget.RemoteViews;
|
||||
import android.widget.Toast;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
@@ -37,6 +38,7 @@ import com.android.launcher3.BaseDraggingActivity;
|
||||
import com.android.launcher3.LauncherAppState;
|
||||
import com.android.launcher3.R;
|
||||
import com.android.launcher3.Utilities;
|
||||
import com.android.launcher3.config.FeatureFlags;
|
||||
import com.android.launcher3.model.WidgetsModel;
|
||||
import com.android.launcher3.model.data.ItemInfo;
|
||||
import com.android.launcher3.testing.TestLogging;
|
||||
@@ -70,13 +72,14 @@ public class LauncherAppWidgetHost extends AppWidgetHost {
|
||||
private final ArrayList<ProviderChangedListener> mProviderChangeListeners = new ArrayList<>();
|
||||
private final SparseArray<LauncherAppWidgetHostView> mViews = new SparseArray<>();
|
||||
private final SparseArray<PendingAppWidgetHostView> mPendingViews = new SparseArray<>();
|
||||
private final SparseArray<LauncherAppWidgetHostView> mDeferredViews = new SparseArray<>();
|
||||
private final SparseArray<RemoteViews> mCachedRemoteViews = new SparseArray<>();
|
||||
|
||||
private final Context mContext;
|
||||
private int mFlags = FLAG_STATE_IS_NORMAL;
|
||||
|
||||
private IntConsumer mAppWidgetRemovedCallback = null;
|
||||
|
||||
|
||||
public LauncherAppWidgetHost(Context context) {
|
||||
this(context, null);
|
||||
}
|
||||
@@ -95,6 +98,11 @@ public class LauncherAppWidgetHost extends AppWidgetHost {
|
||||
if (mPendingViews.get(appWidgetId) != null) {
|
||||
view = mPendingViews.get(appWidgetId);
|
||||
mPendingViews.remove(appWidgetId);
|
||||
} else if (mDeferredViews.get(appWidgetId) != null) {
|
||||
// In case the widget view is deferred, we will simply return the deferred view as
|
||||
// opposed to instantiate a new instance of LauncherAppWidgetHostView since launcher
|
||||
// already added the former to the workspace.
|
||||
view = mDeferredViews.get(appWidgetId);
|
||||
} else {
|
||||
view = new LauncherAppWidgetHostView(context);
|
||||
}
|
||||
@@ -120,12 +128,25 @@ public class LauncherAppWidgetHost extends AppWidgetHost {
|
||||
// widgets upon bind anyway. See issue 14255011 for more context.
|
||||
}
|
||||
|
||||
// We go in reverse order and inflate any deferred widget
|
||||
// We go in reverse order and inflate any deferred or cached widget
|
||||
for (int i = mViews.size() - 1; i >= 0; i--) {
|
||||
LauncherAppWidgetHostView view = mViews.valueAt(i);
|
||||
if (view instanceof DeferredAppWidgetHostView) {
|
||||
view.reInflate();
|
||||
}
|
||||
if (FeatureFlags.ENABLE_CACHED_WIDGET.get()) {
|
||||
final int appWidgetId = mViews.keyAt(i);
|
||||
if (view == mDeferredViews.get(appWidgetId)) {
|
||||
// If the widget view was deferred, we'll need to call super.createView here
|
||||
// to make the binder call to system process to fetch cumulative updates to this
|
||||
// widget, as well as setting up this view for future updates.
|
||||
super.createView(view.mLauncher, appWidgetId, view.getAppWidgetInfo());
|
||||
// At this point #onCreateView should have been called, which in turn returned
|
||||
// the deferred view. There's no reason to keep the reference anymore, so we
|
||||
// removed it here.
|
||||
mDeferredViews.remove(appWidgetId);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -221,10 +242,28 @@ public class LauncherAppWidgetHost extends AppWidgetHost {
|
||||
CustomWidgetManager.INSTANCE.get(context).onViewCreated(lahv);
|
||||
return lahv;
|
||||
} else if ((mFlags & FLAG_LISTENING) == 0) {
|
||||
DeferredAppWidgetHostView view = new DeferredAppWidgetHostView(context);
|
||||
view.setAppWidget(appWidgetId, appWidget);
|
||||
mViews.put(appWidgetId, view);
|
||||
return view;
|
||||
// Since the launcher hasn't started listening to widget updates, we can't simply call
|
||||
// super.createView here because the later will make a binder call to retrieve
|
||||
// RemoteViews from system process.
|
||||
// TODO: have launcher always listens to widget updates in background so that this
|
||||
// check can be removed altogether.
|
||||
if (FeatureFlags.ENABLE_CACHED_WIDGET.get()
|
||||
&& mCachedRemoteViews.get(appWidgetId) != null) {
|
||||
// We've found RemoteViews from cache for this widget, so we will instantiate a
|
||||
// widget host view and populate it with the cached RemoteViews.
|
||||
final LauncherAppWidgetHostView view = new LauncherAppWidgetHostView(context);
|
||||
view.setAppWidget(appWidgetId, appWidget);
|
||||
view.updateAppWidget(mCachedRemoteViews.get(appWidgetId));
|
||||
mDeferredViews.put(appWidgetId, view);
|
||||
mViews.put(appWidgetId, view);
|
||||
return view;
|
||||
} else {
|
||||
// When cache misses, a placeholder for the widget will be returned instead.
|
||||
DeferredAppWidgetHostView view = new DeferredAppWidgetHostView(context);
|
||||
view.setAppWidget(appWidgetId, appWidget);
|
||||
mViews.put(appWidgetId, view);
|
||||
return view;
|
||||
}
|
||||
} else {
|
||||
try {
|
||||
return super.createView(context, appWidgetId, appWidget);
|
||||
@@ -281,6 +320,16 @@ public class LauncherAppWidgetHost extends AppWidgetHost {
|
||||
@Override
|
||||
public void clearViews() {
|
||||
super.clearViews();
|
||||
if (FeatureFlags.ENABLE_CACHED_WIDGET.get()) {
|
||||
// First, we clear any previously cached content from existing widgets
|
||||
mCachedRemoteViews.clear();
|
||||
// Then we proceed to cache the content from the widgets
|
||||
for (int i = 0; i < mViews.size(); i++) {
|
||||
final int appWidgetId = mViews.keyAt(i);
|
||||
final LauncherAppWidgetHostView view = mViews.get(appWidgetId);
|
||||
mCachedRemoteViews.put(appWidgetId, view.mLastRemoteViews);
|
||||
}
|
||||
}
|
||||
mViews.clear();
|
||||
}
|
||||
|
||||
|
||||
@@ -43,6 +43,7 @@ import com.android.launcher3.CheckLongPressHelper;
|
||||
import com.android.launcher3.Launcher;
|
||||
import com.android.launcher3.R;
|
||||
import com.android.launcher3.Utilities;
|
||||
import com.android.launcher3.config.FeatureFlags;
|
||||
import com.android.launcher3.dragndrop.DragLayer;
|
||||
import com.android.launcher3.model.data.ItemInfo;
|
||||
import com.android.launcher3.model.data.LauncherAppWidgetInfo;
|
||||
@@ -85,7 +86,7 @@ public class LauncherAppWidgetHostView extends BaseLauncherAppWidgetHostView
|
||||
private Runnable mAutoAdvanceRunnable;
|
||||
|
||||
private long mDeferUpdatesUntilMillis = 0;
|
||||
private RemoteViews mDeferredRemoteViews;
|
||||
RemoteViews mLastRemoteViews;
|
||||
private boolean mHasDeferredColorChange = false;
|
||||
private @Nullable SparseIntArray mDeferredColorChange = null;
|
||||
|
||||
@@ -150,11 +151,18 @@ public class LauncherAppWidgetHostView extends BaseLauncherAppWidgetHostView
|
||||
TRACE_METHOD_NAME + getAppWidgetInfo().provider, getAppWidgetId());
|
||||
mTrackingWidgetUpdate = false;
|
||||
}
|
||||
if (isDeferringUpdates()) {
|
||||
mDeferredRemoteViews = remoteViews;
|
||||
return;
|
||||
if (FeatureFlags.ENABLE_CACHED_WIDGET.get()) {
|
||||
mLastRemoteViews = remoteViews;
|
||||
if (isDeferringUpdates()) {
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
if (isDeferringUpdates()) {
|
||||
mLastRemoteViews = remoteViews;
|
||||
return;
|
||||
}
|
||||
mLastRemoteViews = null;
|
||||
}
|
||||
mDeferredRemoteViews = null;
|
||||
|
||||
super.updateAppWidget(remoteViews);
|
||||
|
||||
@@ -218,8 +226,7 @@ public class LauncherAppWidgetHostView extends BaseLauncherAppWidgetHostView
|
||||
SparseIntArray deferredColors;
|
||||
boolean hasDeferredColors;
|
||||
mDeferUpdatesUntilMillis = 0;
|
||||
remoteViews = mDeferredRemoteViews;
|
||||
mDeferredRemoteViews = null;
|
||||
remoteViews = mLastRemoteViews;
|
||||
deferredColors = mDeferredColorChange;
|
||||
hasDeferredColors = mHasDeferredColorChange;
|
||||
mDeferredColorChange = null;
|
||||
|
||||
Reference in New Issue
Block a user