Loading src/com/android/launcher3/LauncherAppState.java +10 −0 Original line number Diff line number Diff line Loading @@ -31,7 +31,11 @@ import android.content.SharedPreferences.OnSharedPreferenceChangeListener; import android.content.pm.LauncherApps; import android.os.UserHandle; import android.util.Log; import android.util.SparseArray; import android.widget.RemoteViews; import androidx.annotation.GuardedBy; import androidx.annotation.NonNull; import androidx.annotation.Nullable; import com.android.launcher3.config.FeatureFlags; Loading Loading @@ -70,6 +74,12 @@ public class LauncherAppState implements SafeCloseable { private final InvariantDeviceProfile mInvariantDeviceProfile; private final RunnableList mOnTerminateCallback = new RunnableList(); // WORKAROUND: b/269335387 remove this after widget background listener is enabled /* Array of RemoteViews cached by Launcher process */ @GuardedBy("itself") @NonNull public final SparseArray<RemoteViews> mCachedRemoteViews = new SparseArray<>(); public static LauncherAppState getInstance(final Context context) { return INSTANCE.get(context); } Loading src/com/android/launcher3/widget/LauncherWidgetHolder.java +44 −27 Original line number Diff line number Diff line Loading @@ -36,6 +36,7 @@ import androidx.annotation.Nullable; import com.android.launcher3.BaseActivity; 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; Loading Loading @@ -74,8 +75,6 @@ public class LauncherWidgetHolder { private final SparseArray<PendingAppWidgetHostView> mPendingViews = new SparseArray<>(); @NonNull private final SparseArray<LauncherAppWidgetHostView> mDeferredViews = new SparseArray<>(); @NonNull private final SparseArray<RemoteViews> mCachedRemoteViews = new SparseArray<>(); protected int mFlags = FLAG_STATE_IS_NORMAL; Loading Loading @@ -174,6 +173,12 @@ public class LauncherWidgetHolder { public void deleteAppWidgetId(int appWidgetId) { mWidgetHost.deleteAppWidgetId(appWidgetId); mViews.remove(appWidgetId); if (FeatureFlags.ENABLE_CACHED_WIDGET.get()) { final LauncherAppState state = LauncherAppState.getInstance(mContext); synchronized (state.mCachedRemoteViews) { state.mCachedRemoteViews.delete(appWidgetId); } } } /** Loading Loading @@ -308,7 +313,17 @@ public class LauncherWidgetHolder { if (WidgetsModel.GO_DISABLE_WIDGETS) { return; } if (FeatureFlags.ENABLE_CACHED_WIDGET.get()) { // Cache the content from the widgets when Launcher stops listening to widget updates final LauncherAppState state = LauncherAppState.getInstance(mContext); synchronized (state.mCachedRemoteViews) { for (int i = 0; i < mViews.size(); i++) { final int appWidgetId = mViews.keyAt(i); final LauncherAppWidgetHostView view = mViews.get(appWidgetId); state.mCachedRemoteViews.put(appWidgetId, view.mLastRemoteViews); } } } mWidgetHost.stopListening(); setListeningFlag(false); } Loading Loading @@ -350,23 +365,24 @@ public class LauncherWidgetHolder { // 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) { if (FeatureFlags.ENABLE_CACHED_WIDGET.get()) { final RemoteViews cachedRemoteViews = getCachedRemoteViews(appWidgetId); if (cachedRemoteViews != 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)); view.updateAppWidget(cachedRemoteViews); mDeferredViews.put(appWidgetId, view); mViews.put(appWidgetId, view); return view; } else { // When cache misses, a placeholder for the widget will be returned instead. } } // If cache misses or not enabled, a placeholder for the widget will be returned. DeferredAppWidgetHostView view = new DeferredAppWidgetHostView(context); view.setAppWidget(appWidgetId, appWidget); mViews.put(appWidgetId, view); return view; } } else { try { return mWidgetHost.createView(context, appWidgetId, appWidget); Loading Loading @@ -432,15 +448,8 @@ public class LauncherWidgetHolder { LauncherAppWidgetHost tempHost = (LauncherAppWidgetHost) mWidgetHost; tempHost.clearViews(); if (FeatureFlags.ENABLE_CACHED_WIDGET.get()) { // First, we clear any previously cached content from existing widgets mCachedRemoteViews.clear(); // Clear previously cached content from existing widgets mDeferredViews.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(); } Loading Loading @@ -481,6 +490,14 @@ public class LauncherWidgetHolder { return (flags & FLAGS_SHOULD_LISTEN) == FLAGS_SHOULD_LISTEN; } @Nullable private RemoteViews getCachedRemoteViews(int appWidgetId) { final LauncherAppState state = LauncherAppState.getInstance(mContext); synchronized (state.mCachedRemoteViews) { return state.mCachedRemoteViews.get(appWidgetId); } } /** * Returns the new LauncherWidgetHolder instance */ Loading Loading
src/com/android/launcher3/LauncherAppState.java +10 −0 Original line number Diff line number Diff line Loading @@ -31,7 +31,11 @@ import android.content.SharedPreferences.OnSharedPreferenceChangeListener; import android.content.pm.LauncherApps; import android.os.UserHandle; import android.util.Log; import android.util.SparseArray; import android.widget.RemoteViews; import androidx.annotation.GuardedBy; import androidx.annotation.NonNull; import androidx.annotation.Nullable; import com.android.launcher3.config.FeatureFlags; Loading Loading @@ -70,6 +74,12 @@ public class LauncherAppState implements SafeCloseable { private final InvariantDeviceProfile mInvariantDeviceProfile; private final RunnableList mOnTerminateCallback = new RunnableList(); // WORKAROUND: b/269335387 remove this after widget background listener is enabled /* Array of RemoteViews cached by Launcher process */ @GuardedBy("itself") @NonNull public final SparseArray<RemoteViews> mCachedRemoteViews = new SparseArray<>(); public static LauncherAppState getInstance(final Context context) { return INSTANCE.get(context); } Loading
src/com/android/launcher3/widget/LauncherWidgetHolder.java +44 −27 Original line number Diff line number Diff line Loading @@ -36,6 +36,7 @@ import androidx.annotation.Nullable; import com.android.launcher3.BaseActivity; 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; Loading Loading @@ -74,8 +75,6 @@ public class LauncherWidgetHolder { private final SparseArray<PendingAppWidgetHostView> mPendingViews = new SparseArray<>(); @NonNull private final SparseArray<LauncherAppWidgetHostView> mDeferredViews = new SparseArray<>(); @NonNull private final SparseArray<RemoteViews> mCachedRemoteViews = new SparseArray<>(); protected int mFlags = FLAG_STATE_IS_NORMAL; Loading Loading @@ -174,6 +173,12 @@ public class LauncherWidgetHolder { public void deleteAppWidgetId(int appWidgetId) { mWidgetHost.deleteAppWidgetId(appWidgetId); mViews.remove(appWidgetId); if (FeatureFlags.ENABLE_CACHED_WIDGET.get()) { final LauncherAppState state = LauncherAppState.getInstance(mContext); synchronized (state.mCachedRemoteViews) { state.mCachedRemoteViews.delete(appWidgetId); } } } /** Loading Loading @@ -308,7 +313,17 @@ public class LauncherWidgetHolder { if (WidgetsModel.GO_DISABLE_WIDGETS) { return; } if (FeatureFlags.ENABLE_CACHED_WIDGET.get()) { // Cache the content from the widgets when Launcher stops listening to widget updates final LauncherAppState state = LauncherAppState.getInstance(mContext); synchronized (state.mCachedRemoteViews) { for (int i = 0; i < mViews.size(); i++) { final int appWidgetId = mViews.keyAt(i); final LauncherAppWidgetHostView view = mViews.get(appWidgetId); state.mCachedRemoteViews.put(appWidgetId, view.mLastRemoteViews); } } } mWidgetHost.stopListening(); setListeningFlag(false); } Loading Loading @@ -350,23 +365,24 @@ public class LauncherWidgetHolder { // 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) { if (FeatureFlags.ENABLE_CACHED_WIDGET.get()) { final RemoteViews cachedRemoteViews = getCachedRemoteViews(appWidgetId); if (cachedRemoteViews != 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)); view.updateAppWidget(cachedRemoteViews); mDeferredViews.put(appWidgetId, view); mViews.put(appWidgetId, view); return view; } else { // When cache misses, a placeholder for the widget will be returned instead. } } // If cache misses or not enabled, a placeholder for the widget will be returned. DeferredAppWidgetHostView view = new DeferredAppWidgetHostView(context); view.setAppWidget(appWidgetId, appWidget); mViews.put(appWidgetId, view); return view; } } else { try { return mWidgetHost.createView(context, appWidgetId, appWidget); Loading Loading @@ -432,15 +448,8 @@ public class LauncherWidgetHolder { LauncherAppWidgetHost tempHost = (LauncherAppWidgetHost) mWidgetHost; tempHost.clearViews(); if (FeatureFlags.ENABLE_CACHED_WIDGET.get()) { // First, we clear any previously cached content from existing widgets mCachedRemoteViews.clear(); // Clear previously cached content from existing widgets mDeferredViews.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(); } Loading Loading @@ -481,6 +490,14 @@ public class LauncherWidgetHolder { return (flags & FLAGS_SHOULD_LISTEN) == FLAGS_SHOULD_LISTEN; } @Nullable private RemoteViews getCachedRemoteViews(int appWidgetId) { final LauncherAppState state = LauncherAppState.getInstance(mContext); synchronized (state.mCachedRemoteViews) { return state.mCachedRemoteViews.get(appWidgetId); } } /** * Returns the new LauncherWidgetHolder instance */ Loading