Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit a35d04af authored by Pinyao Ting's avatar Pinyao Ting Committed by Android (Google) Code Review
Browse files

Merge "Retains cached widget in launcher process" into tm-qpr-dev

parents be58eb2c bd638e7b
Loading
Loading
Loading
Loading
+10 −0
Original line number Diff line number Diff line
@@ -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;
@@ -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);
    }
+44 −27
Original line number Diff line number Diff line
@@ -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;
@@ -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;

@@ -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);
            }
        }
    }

    /**
@@ -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);
    }
@@ -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);
@@ -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();
    }
@@ -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
     */