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

Commit e86f11fa authored by Sunny Goyal's avatar Sunny Goyal
Browse files

Adding support for loading workspace in the absence of Launcher.

> LoadWorkspace can be called with a LoaderResult which does not bind anything.
> Synchronous bind does not look for a valid page id, and will fallback to the
  current pageId similar to full load flow

Bug: 37616877
Change-Id: If14491dc79c5b85ae1019cc93e4e08759df3387d
parent 3a5b8352
Loading
Loading
Loading
Loading
+29 −70
Original line number Diff line number Diff line
@@ -42,7 +42,7 @@ import com.android.launcher3.graphics.LauncherIcons;
import com.android.launcher3.model.AddWorkspaceItemsTask;
import com.android.launcher3.model.BgDataModel;
import com.android.launcher3.model.CacheDataUpdatedTask;
import com.android.launcher3.model.ExtendedModelTask;
import com.android.launcher3.model.BaseModelUpdateTask;
import com.android.launcher3.model.LoaderResults;
import com.android.launcher3.model.LoaderTask;
import com.android.launcher3.model.ModelWriter;
@@ -80,7 +80,6 @@ import java.util.concurrent.Executor;
 */
public class LauncherModel extends BroadcastReceiver
        implements LauncherAppsCompat.OnAppsChangedCallbackCompat {
    static final boolean DEBUG_TASKS = false;
    private static final boolean DEBUG_RECEIVER = false;

    static final String TAG = "Launcher.Model";
@@ -425,7 +424,7 @@ public class LauncherModel extends BroadcastReceiver
    public void forceReload() {
        synchronized (mLock) {
            // Stop any existing loaders first, so they don't set mModelLoaded to true later
            stopLoaderLocked();
            stopLoader();
            mModelLoaded = false;
        }

@@ -451,16 +450,6 @@ public class LauncherModel extends BroadcastReceiver
        }
    }

    /**
     * If there is already a loader task running, tell it to stop.
     */
    private void stopLoaderLocked() {
        LoaderTask oldTask = mLoaderTask;
        if (oldTask != null) {
            oldTask.stopLocked();
        }
    }

    public boolean isCurrentCallbacks(Callbacks callbacks) {
        return (mCallbacks != null && mCallbacks.get() == callbacks);
    }
@@ -484,12 +473,10 @@ public class LauncherModel extends BroadcastReceiver
                        });

                // If there is already one running, tell it to stop.
                stopLoaderLocked();
                stopLoader();
                LoaderResults loaderResults = new LoaderResults(mApp, sBgDataModel,
                        mBgAllAppsList, synchronousBindPage, mCallbacks);
                if (synchronousBindPage != PagedView.INVALID_RESTORE_PAGE
                        && mModelLoaded && !mIsLoaderTaskRunning) {

                if (mModelLoaded && !mIsLoaderTaskRunning) {
                    // Divide the set of loaded items into those that we are binding synchronously,
                    // and everything else that is to be bound normally (asynchronously).
                    loaderResults.bindWorkspace();
@@ -500,20 +487,32 @@ public class LauncherModel extends BroadcastReceiver
                    loaderResults.bindWidgets();
                    return true;
                } else {
                    mLoaderTask = new LoaderTask(mApp, mBgAllAppsList, sBgDataModel, loaderResults);
                    sWorker.post(mLoaderTask);
                    startLoaderForResults(loaderResults);
                }
            }
        }
        return false;
    }

    /**
     * If there is already a loader task running, tell it to stop.
     */
    public void stopLoader() {
        synchronized (mLock) {
            if (mLoaderTask != null) {
                mLoaderTask.stopLocked();
            LoaderTask oldTask = mLoaderTask;
            mLoaderTask = null;
            if (oldTask != null) {
                oldTask.stopLocked();
            }
        }
    }

    public void startLoaderForResults(LoaderResults results) {
        synchronized (mLock) {
            stopLoader();
            mLoaderTask = new LoaderTask(mApp, mBgAllAppsList, sBgDataModel, results);
            runOnWorkerThread(mLoaderTask);
        }
    }

    /**
@@ -529,7 +528,7 @@ public class LauncherModel extends BroadcastReceiver
    }

    public void onInstallSessionCreated(final PackageInstallInfo sessionInfo) {
        enqueueModelUpdateTask(new ExtendedModelTask() {
        enqueueModelUpdateTask(new BaseModelUpdateTask() {
            @Override
            public void execute(LauncherAppState app, BgDataModel dataModel, AllAppsList apps) {
                apps.addPromiseApp(app.getContext(), sessionInfo);
@@ -607,8 +606,8 @@ public class LauncherModel extends BroadcastReceiver
                CacheDataUpdatedTask.OP_CACHE_UPDATE, user, updatedPackages));
    }

    public void enqueueModelUpdateTask(BaseModelUpdateTask task) {
        task.init(this);
    public void enqueueModelUpdateTask(ModelUpdateTask task) {
        task.init(mApp, this, sBgDataModel, mBgAllAppsList, mUiExecutor);
        runOnWorkerThread(task);
    }

@@ -624,54 +623,14 @@ public class LauncherModel extends BroadcastReceiver
    /**
     * A runnable which changes/updates the data model of the launcher based on certain events.
     */
    public static abstract class BaseModelUpdateTask implements Runnable {

        private LauncherModel mModel;
        private Executor mUiExecutor;

        /* package private */
        void init(LauncherModel model) {
            mModel = model;
            mUiExecutor = mModel.mUiExecutor;
        }

        @Override
        public final void run() {
            if (!mModel.mModelLoaded) {
                if (DEBUG_TASKS) {
                    Log.d(TAG, "Ignoring model task since loader is pending=" + this);
                }
                // Loader has not yet run.
                return;
            }
            execute(mModel.mApp, sBgDataModel, mModel.mBgAllAppsList);
        }

        /**
         * Execute the actual task. Called on the worker thread.
         */
        public abstract void execute(
                LauncherAppState app, BgDataModel dataModel, AllAppsList apps);
    public interface ModelUpdateTask extends Runnable {

        /**
         * Schedules a {@param task} to be executed on the current callbacks.
         * Called before the task is posted to initialize the internal state.
         */
        public final void scheduleCallbackTask(final CallbackTask task) {
            final Callbacks callbacks = mModel.getCallback();
            mUiExecutor.execute(new Runnable() {
                public void run() {
                    Callbacks cb = mModel.getCallback();
                    if (callbacks == cb && cb != null) {
                        task.execute(callbacks);
                    }
                }
            });
        }
        void init(LauncherAppState app, LauncherModel model,
                BgDataModel dataModel, AllAppsList allAppsList, Executor uiExecutor);

        public ModelWriter getModelWriter() {
            // Updates from model task, do not deal with icon position in hotseat.
            return mModel.getWriter(false /* hasVerticalHotseat */);
        }
    }

    public void updateAndBindShortcutInfo(final ShortcutInfo si, final ShortcutInfoCompat info) {
@@ -689,7 +648,7 @@ public class LauncherModel extends BroadcastReceiver
     * Utility method to update a shortcut on the background thread.
     */
    public void updateAndBindShortcutInfo(final Provider<ShortcutInfo> shortcutProvider) {
        enqueueModelUpdateTask(new ExtendedModelTask() {
        enqueueModelUpdateTask(new BaseModelUpdateTask() {
            @Override
            public void execute(LauncherAppState app, BgDataModel dataModel, AllAppsList apps) {
                ShortcutInfo info = shortcutProvider.get();
@@ -701,7 +660,7 @@ public class LauncherModel extends BroadcastReceiver
    }

    public void refreshAndBindWidgetsAndShortcuts(@Nullable final PackageUserKey packageUser) {
        enqueueModelUpdateTask(new ExtendedModelTask() {
        enqueueModelUpdateTask(new BaseModelUpdateTask() {
            @Override
            public void execute(LauncherAppState app, BgDataModel dataModel, AllAppsList apps) {
                dataModel.widgetsModel.update(app, packageUser);
+1 −1
Original line number Diff line number Diff line
@@ -47,7 +47,7 @@ import java.util.List;
/**
 * Task to add auto-created workspace items.
 */
public class AddWorkspaceItemsTask extends ExtendedModelTask {
public class AddWorkspaceItemsTask extends BaseModelUpdateTask {

    private final Provider<List<Pair<ItemInfo, Object>>> mAppsProvider;

+65 −3
Original line number Diff line number Diff line
@@ -16,8 +16,12 @@
package com.android.launcher3.model;

import android.os.UserHandle;
import android.util.Log;

import com.android.launcher3.LauncherModel.BaseModelUpdateTask;
import com.android.launcher3.AllAppsList;
import com.android.launcher3.LauncherAppState;
import com.android.launcher3.LauncherModel;
import com.android.launcher3.LauncherModel.ModelUpdateTask;
import com.android.launcher3.LauncherModel.CallbackTask;
import com.android.launcher3.LauncherModel.Callbacks;
import com.android.launcher3.ShortcutInfo;
@@ -25,11 +29,69 @@ import com.android.launcher3.util.ComponentKey;
import com.android.launcher3.util.MultiHashMap;

import java.util.ArrayList;
import java.util.concurrent.Executor;

/**
 * Extension of {@link BaseModelUpdateTask} with some utility methods
 * Extension of {@link ModelUpdateTask} with some utility methods
 */
public abstract class ExtendedModelTask extends BaseModelUpdateTask {
public abstract class BaseModelUpdateTask implements ModelUpdateTask {

    private static final boolean DEBUG_TASKS = false;
    private static final String TAG = "BaseModelUpdateTask";

    private LauncherAppState mApp;
    private LauncherModel mModel;
    private BgDataModel mDataModel;
    private AllAppsList mAllAppsList;
    private Executor mUiExecutor;

    public void init(LauncherAppState app, LauncherModel model,
            BgDataModel dataModel, AllAppsList allAppsList, Executor uiExecutor) {
        mApp = app;
        mModel = model;
        mDataModel = dataModel;
        mAllAppsList = allAppsList;
        mUiExecutor = uiExecutor;
    }

    @Override
    public final void run() {
        if (!mModel.isModelLoaded()) {
            if (DEBUG_TASKS) {
                Log.d(TAG, "Ignoring model task since loader is pending=" + this);
            }
            // Loader has not yet run.
            return;
        }
        execute(mApp, mDataModel, mAllAppsList);
    }

    /**
     * Execute the actual task. Called on the worker thread.
     */
    public abstract void execute(
            LauncherAppState app, BgDataModel dataModel, AllAppsList apps);

    /**
     * Schedules a {@param task} to be executed on the current callbacks.
     */
    public final void scheduleCallbackTask(final CallbackTask task) {
        final Callbacks callbacks = mModel.getCallback();
        mUiExecutor.execute(new Runnable() {
            public void run() {
                Callbacks cb = mModel.getCallback();
                if (callbacks == cb && cb != null) {
                    task.execute(callbacks);
                }
            }
        });
    }

    public ModelWriter getModelWriter() {
        // Updates from model task, do not deal with icon position in hotseat.
        return mModel.getWriter(false /* hasVerticalHotseat */);
    }


    public void bindUpdatedShortcuts(
            ArrayList<ShortcutInfo> updatedShortcuts, UserHandle user) {
+1 −1
Original line number Diff line number Diff line
@@ -34,7 +34,7 @@ import java.util.HashSet;
/**
 * Handles changes due to cache updates.
 */
public class CacheDataUpdatedTask extends ExtendedModelTask {
public class CacheDataUpdatedTask extends BaseModelUpdateTask {

    public static final int OP_CACHE_UPDATE = 1;
    public static final int OP_SESSION_UPDATE = 2;
+12 −1
Original line number Diff line number Diff line
@@ -16,6 +16,7 @@

package com.android.launcher3.model;

import android.os.Looper;
import android.util.Log;

import com.android.launcher3.AllAppsList;
@@ -32,6 +33,7 @@ import com.android.launcher3.PagedView;
import com.android.launcher3.Utilities;
import com.android.launcher3.config.FeatureFlags;
import com.android.launcher3.util.ComponentKey;
import com.android.launcher3.util.LooperIdleLock;
import com.android.launcher3.util.MultiHashMap;
import com.android.launcher3.util.ViewOnDrawExecutor;

@@ -45,7 +47,7 @@ import java.util.Set;
import java.util.concurrent.Executor;

/**
 * Helper class to handle results of {@link com.android.launcher3.LauncherModel.LoaderTask}.
 * Helper class to handle results of {@link com.android.launcher3.model.LoaderTask}.
 */
public class LoaderResults {

@@ -389,4 +391,13 @@ public class LoaderResults {
        };
        mUiExecutor.execute(r);
    }

    public LooperIdleLock newIdleLock(Object lock) {
        LooperIdleLock idleLock = new LooperIdleLock(lock, Looper.getMainLooper());
        // If we are not binding, there is no reason to wait for idle.
        if (mCallbacks.get() == null) {
            idleLock.queueIdle();
        }
        return idleLock;
    }
}
Loading