Simplifying Launcher binding callbacks
> Making all methods as default > Removing obsolete logic around synchronous binding > Removing some UI dependencies from bind callbacks Bug: 187353581 Test: Manual Change-Id: I0d2bbb060af2cab7c64541d7695055629dfaf0b8
This commit is contained in:
parent
ab4fb243b7
commit
4a48a988c8
|
@ -41,20 +41,11 @@ import com.android.launcher3.icons.ComponentWithLabel;
|
|||
import com.android.launcher3.icons.IconCache;
|
||||
import com.android.launcher3.model.BgDataModel.FixedContainerItems;
|
||||
import com.android.launcher3.model.QuickstepModelDelegate.PredictorState;
|
||||
import com.android.launcher3.model.data.AppInfo;
|
||||
import com.android.launcher3.model.data.ItemInfo;
|
||||
import com.android.launcher3.model.data.LauncherAppWidgetInfo;
|
||||
import com.android.launcher3.model.data.WorkspaceItemInfo;
|
||||
import com.android.launcher3.shadows.ShadowDeviceFlag;
|
||||
import com.android.launcher3.util.ComponentKey;
|
||||
import com.android.launcher3.util.IntArray;
|
||||
import com.android.launcher3.util.IntSet;
|
||||
import com.android.launcher3.util.ItemInfoMatcher;
|
||||
import com.android.launcher3.util.LauncherModelHelper;
|
||||
import com.android.launcher3.util.ViewOnDrawExecutor;
|
||||
import com.android.launcher3.widget.LauncherAppWidgetProviderInfo;
|
||||
import com.android.launcher3.widget.PendingAddWidgetInfo;
|
||||
import com.android.launcher3.widget.model.WidgetsListBaseEntry;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
@ -68,9 +59,6 @@ import org.robolectric.shadows.ShadowAppWidgetManager;
|
|||
import org.robolectric.shadows.ShadowPackageManager;
|
||||
import org.robolectric.util.ReflectionHelpers;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
|
@ -243,60 +231,5 @@ public final class WidgetsPredicationUpdateTaskTest {
|
|||
public IntSet getPagesToBindSynchronously() {
|
||||
return IntSet.wrap(0);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void clearPendingBinds() { }
|
||||
|
||||
@Override
|
||||
public void startBinding() { }
|
||||
|
||||
@Override
|
||||
public void bindItems(List<ItemInfo> shortcuts, boolean forceAnimateIcons) { }
|
||||
|
||||
@Override
|
||||
public void bindScreens(IntArray orderedScreenIds) { }
|
||||
|
||||
@Override
|
||||
public void finishFirstPageBind(ViewOnDrawExecutor executor) { }
|
||||
|
||||
@Override
|
||||
public void finishBindingItems(IntSet pagesBoundFirst) { }
|
||||
|
||||
@Override
|
||||
public void preAddApps() { }
|
||||
|
||||
@Override
|
||||
public void bindAppsAdded(IntArray newScreens, ArrayList<ItemInfo> addNotAnimated,
|
||||
ArrayList<ItemInfo> addAnimated) { }
|
||||
|
||||
@Override
|
||||
public void bindIncrementalDownloadProgressUpdated(AppInfo app) { }
|
||||
|
||||
@Override
|
||||
public void bindWorkspaceItemsChanged(List<WorkspaceItemInfo> updated) { }
|
||||
|
||||
@Override
|
||||
public void bindWidgetsRestored(ArrayList<LauncherAppWidgetInfo> widgets) { }
|
||||
|
||||
@Override
|
||||
public void bindRestoreItemsChange(HashSet<ItemInfo> updates) { }
|
||||
|
||||
@Override
|
||||
public void bindWorkspaceComponentsRemoved(ItemInfoMatcher matcher) { }
|
||||
|
||||
@Override
|
||||
public void bindAllWidgets(List<WidgetsListBaseEntry> widgets) { }
|
||||
|
||||
@Override
|
||||
public void onPagesBoundSynchronously(IntSet pages) { }
|
||||
|
||||
@Override
|
||||
public void executeOnNextDraw(ViewOnDrawExecutor executor) { }
|
||||
|
||||
@Override
|
||||
public void bindDeepShortcutMap(HashMap<ComponentKey, Integer> deepShortcutMap) { }
|
||||
|
||||
@Override
|
||||
public void bindAllApplications(AppInfo[] apps, int flags) { }
|
||||
}
|
||||
}
|
||||
|
|
|
@ -35,7 +35,7 @@ import com.android.launcher3.util.IntSet;
|
|||
import com.android.launcher3.util.LauncherLayoutBuilder;
|
||||
import com.android.launcher3.util.LauncherModelHelper;
|
||||
import com.android.launcher3.util.LooperExecutor;
|
||||
import com.android.launcher3.util.ViewOnDrawExecutor;
|
||||
import com.android.launcher3.util.RunnableList;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
@ -106,14 +106,14 @@ public class ModelMultiCallbacksTest {
|
|||
// No effect on callbacks when removing an callback
|
||||
mModelHelper.getModel().removeCallbacks(cb2);
|
||||
waitForLoaderAndTempMainThread();
|
||||
assertNull(cb1.mDeferredExecutor);
|
||||
assertNull(cb2.mDeferredExecutor);
|
||||
assertNull(cb1.mPendingTasks);
|
||||
assertNull(cb2.mPendingTasks);
|
||||
|
||||
// Reloading only loads registered callbacks
|
||||
mModelHelper.getModel().startLoader();
|
||||
waitForLoaderAndTempMainThread();
|
||||
cb1.verifySynchronouslyBound(3);
|
||||
assertNull(cb2.mDeferredExecutor);
|
||||
assertNull(cb2.mPendingTasks);
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -180,19 +180,15 @@ public class ModelMultiCallbacksTest {
|
|||
final List<ItemInfo> mItems = new ArrayList<>();
|
||||
IntSet mPageToBindSync = IntSet.wrap(0);
|
||||
IntSet mPageBoundSync = new IntSet();
|
||||
ViewOnDrawExecutor mDeferredExecutor;
|
||||
RunnableList mPendingTasks;
|
||||
AppInfo[] mAppInfos;
|
||||
|
||||
MyCallbacks() { }
|
||||
|
||||
@Override
|
||||
public void onPagesBoundSynchronously(IntSet pages) {
|
||||
mPageBoundSync = pages;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void executeOnNextDraw(ViewOnDrawExecutor executor) {
|
||||
mDeferredExecutor = executor;
|
||||
public void onInitialBindComplete(IntSet boundPages, RunnableList pendingTasks) {
|
||||
mPageBoundSync = boundPages;
|
||||
mPendingTasks = pendingTasks;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -213,19 +209,19 @@ public class ModelMultiCallbacksTest {
|
|||
public void reset() {
|
||||
mItems.clear();
|
||||
mPageBoundSync = new IntSet();
|
||||
mDeferredExecutor = null;
|
||||
mPendingTasks = null;
|
||||
mAppInfos = null;
|
||||
}
|
||||
|
||||
public void verifySynchronouslyBound(int totalItems) {
|
||||
// Verify that the requested page is bound synchronously
|
||||
assertEquals(mPageBoundSync, mPageToBindSync);
|
||||
assertEquals(mPageToBindSync, mPageBoundSync);
|
||||
assertEquals(mItems.size(), 1);
|
||||
assertEquals(mItems.get(0).screenId, mPageBoundSync);
|
||||
assertNotNull(mDeferredExecutor);
|
||||
assertEquals(IntSet.wrap(mItems.get(0).screenId), mPageBoundSync);
|
||||
assertNotNull(mPendingTasks);
|
||||
|
||||
// Verify that all other pages are bound properly
|
||||
mDeferredExecutor.runAllTasks();
|
||||
mPendingTasks.executeAllAndDestroy();
|
||||
assertEquals(mItems.size(), totalItems);
|
||||
}
|
||||
|
||||
|
|
|
@ -81,7 +81,7 @@ public class LauncherUIHelper {
|
|||
doLayout(launcher);
|
||||
ViewOnDrawExecutor executor = ReflectionHelpers.getField(launcher, "mPendingExecutor");
|
||||
if (executor != null) {
|
||||
executor.runAllTasks();
|
||||
executor.markCompleted();
|
||||
}
|
||||
return launcher;
|
||||
}
|
||||
|
|
|
@ -118,6 +118,7 @@ import com.android.launcher3.allapps.AllAppsContainerView;
|
|||
import com.android.launcher3.allapps.AllAppsStore;
|
||||
import com.android.launcher3.allapps.AllAppsTransitionController;
|
||||
import com.android.launcher3.allapps.DiscoveryBounce;
|
||||
import com.android.launcher3.anim.AnimatorListeners;
|
||||
import com.android.launcher3.anim.PropertyListBuilder;
|
||||
import com.android.launcher3.compat.AccessibilityManagerCompat;
|
||||
import com.android.launcher3.config.FeatureFlags;
|
||||
|
@ -174,6 +175,7 @@ import com.android.launcher3.util.OnboardingPrefs;
|
|||
import com.android.launcher3.util.PackageManagerHelper;
|
||||
import com.android.launcher3.util.PackageUserKey;
|
||||
import com.android.launcher3.util.PendingRequestArgs;
|
||||
import com.android.launcher3.util.RunnableList;
|
||||
import com.android.launcher3.util.SafeCloseable;
|
||||
import com.android.launcher3.util.SystemUiController;
|
||||
import com.android.launcher3.util.Themes;
|
||||
|
@ -2060,7 +2062,7 @@ public class Launcher extends StatefulActivity<LauncherState> implements Launche
|
|||
@Override
|
||||
public void clearPendingBinds() {
|
||||
if (mPendingExecutor != null) {
|
||||
mPendingExecutor.markCompleted();
|
||||
mPendingExecutor.cancel();
|
||||
mPendingExecutor = null;
|
||||
|
||||
// We might have set this flag previously and forgot to clear it.
|
||||
|
@ -2482,25 +2484,6 @@ public class Launcher extends StatefulActivity<LauncherState> implements Launche
|
|||
return info;
|
||||
}
|
||||
|
||||
public void onPagesBoundSynchronously(IntSet pages) {
|
||||
mSynchronouslyBoundPages = pages;
|
||||
mWorkspace.setCurrentPage(pages.getArray().get(0));
|
||||
mPagesToBindSynchronously = new IntSet();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void executeOnNextDraw(ViewOnDrawExecutor executor) {
|
||||
clearPendingBinds();
|
||||
mPendingExecutor = executor;
|
||||
if (!isInState(ALL_APPS)) {
|
||||
mAppsView.getAppsStore().enableDeferUpdates(AllAppsStore.DEFER_UPDATES_NEXT_DRAW);
|
||||
mPendingExecutor.execute(() -> mAppsView.getAppsStore().disableDeferUpdates(
|
||||
AllAppsStore.DEFER_UPDATES_NEXT_DRAW));
|
||||
}
|
||||
|
||||
executor.attachTo(this);
|
||||
}
|
||||
|
||||
public void clearPendingExecutor(ViewOnDrawExecutor executor) {
|
||||
if (mPendingExecutor == executor) {
|
||||
mPendingExecutor = null;
|
||||
|
@ -2508,22 +2491,31 @@ public class Launcher extends StatefulActivity<LauncherState> implements Launche
|
|||
}
|
||||
|
||||
@Override
|
||||
public void finishFirstPageBind(final ViewOnDrawExecutor executor) {
|
||||
public void onInitialBindComplete(IntSet boundPages, RunnableList pendingTasks) {
|
||||
mSynchronouslyBoundPages = boundPages;
|
||||
if (!boundPages.isEmpty()) {
|
||||
mWorkspace.setCurrentPage(boundPages.getArray().get(0));
|
||||
}
|
||||
mPagesToBindSynchronously = new IntSet();
|
||||
|
||||
clearPendingBinds();
|
||||
ViewOnDrawExecutor executor = new ViewOnDrawExecutor(pendingTasks);
|
||||
mPendingExecutor = executor;
|
||||
if (!isInState(ALL_APPS)) {
|
||||
mAppsView.getAppsStore().enableDeferUpdates(AllAppsStore.DEFER_UPDATES_NEXT_DRAW);
|
||||
pendingTasks.add(() -> mAppsView.getAppsStore().disableDeferUpdates(
|
||||
AllAppsStore.DEFER_UPDATES_NEXT_DRAW));
|
||||
}
|
||||
|
||||
AlphaProperty property = mDragLayer.getAlphaProperty(ALPHA_INDEX_LAUNCHER_LOAD);
|
||||
if (property.getValue() < 1) {
|
||||
ObjectAnimator anim = ObjectAnimator.ofFloat(property, MultiValueAlpha.VALUE, 1);
|
||||
if (executor != null) {
|
||||
anim.addListener(new AnimatorListenerAdapter() {
|
||||
@Override
|
||||
public void onAnimationEnd(Animator animation) {
|
||||
executor.onLoadAnimationCompleted();
|
||||
}
|
||||
});
|
||||
}
|
||||
anim.addListener(AnimatorListeners.forEndCallback(executor::onLoadAnimationCompleted));
|
||||
anim.start();
|
||||
} else if (executor != null) {
|
||||
} else {
|
||||
executor.onLoadAnimationCompleted();
|
||||
}
|
||||
executor.attachTo(this);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -18,7 +18,9 @@ package com.android.launcher3.model;
|
|||
|
||||
import static com.android.launcher3.model.ModelUtils.filterCurrentWorkspaceItems;
|
||||
import static com.android.launcher3.model.ModelUtils.sortWorkspaceItemsSpatially;
|
||||
import static com.android.launcher3.util.Executors.MODEL_EXECUTOR;
|
||||
|
||||
import android.os.Process;
|
||||
import android.util.Log;
|
||||
|
||||
import com.android.launcher3.InvariantDeviceProfile;
|
||||
|
@ -33,7 +35,7 @@ import com.android.launcher3.util.IntArray;
|
|||
import com.android.launcher3.util.IntSet;
|
||||
import com.android.launcher3.util.LooperExecutor;
|
||||
import com.android.launcher3.util.LooperIdleLock;
|
||||
import com.android.launcher3.util.ViewOnDrawExecutor;
|
||||
import com.android.launcher3.util.RunnableList;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
|
@ -175,7 +177,6 @@ public abstract class BaseLoaderResults {
|
|||
currentScreenIndices = screenIndices;
|
||||
}
|
||||
|
||||
final boolean validFirstPage = !currentScreenIndices.isEmpty();
|
||||
|
||||
IntSet currentScreenIds = new IntSet();
|
||||
currentScreenIndices.forEach(
|
||||
|
@ -204,40 +205,25 @@ public abstract class BaseLoaderResults {
|
|||
// Bind workspace screens
|
||||
executeCallbacksTask(c -> c.bindScreens(mOrderedScreenIds), mUiExecutor);
|
||||
|
||||
Executor mainExecutor = mUiExecutor;
|
||||
// Load items on the current page.
|
||||
bindWorkspaceItems(currentWorkspaceItems, mainExecutor);
|
||||
bindAppWidgets(currentAppWidgets, mainExecutor);
|
||||
bindWorkspaceItems(currentWorkspaceItems, mUiExecutor);
|
||||
bindAppWidgets(currentAppWidgets, mUiExecutor);
|
||||
mExtraItems.forEach(item ->
|
||||
executeCallbacksTask(c -> c.bindExtraContainerItems(item), mainExecutor));
|
||||
executeCallbacksTask(c -> c.bindExtraContainerItems(item), mUiExecutor));
|
||||
|
||||
// In case of validFirstPage, only bind the first screen, and defer binding the
|
||||
// remaining screens after first onDraw (and an optional the fade animation whichever
|
||||
// happens later).
|
||||
// This ensures that the first screen is immediately visible (eg. during rotation)
|
||||
// In case of !validFirstPage, bind all pages one after other.
|
||||
RunnableList pendingTasks = new RunnableList();
|
||||
Executor pendingExecutor = pendingTasks::add;
|
||||
bindWorkspaceItems(otherWorkspaceItems, pendingExecutor);
|
||||
bindAppWidgets(otherAppWidgets, pendingExecutor);
|
||||
executeCallbacksTask(c -> c.finishBindingItems(currentScreenIndices), pendingExecutor);
|
||||
pendingExecutor.execute(
|
||||
() -> MODEL_EXECUTOR.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT));
|
||||
|
||||
final Executor deferredExecutor =
|
||||
validFirstPage ? new ViewOnDrawExecutor() : mainExecutor;
|
||||
|
||||
executeCallbacksTask(c -> c.finishFirstPageBind(
|
||||
validFirstPage ? (ViewOnDrawExecutor) deferredExecutor : null), mainExecutor);
|
||||
|
||||
bindWorkspaceItems(otherWorkspaceItems, deferredExecutor);
|
||||
bindAppWidgets(otherAppWidgets, deferredExecutor);
|
||||
// Tell the workspace that we're done binding items
|
||||
executeCallbacksTask(c -> c.finishBindingItems(currentScreenIndices), deferredExecutor);
|
||||
|
||||
if (validFirstPage) {
|
||||
executeCallbacksTask(c -> {
|
||||
// We are loading synchronously, which means, some of the pages will be
|
||||
// bound after first draw. Inform the mCallbacks that page binding is
|
||||
// not complete, and schedule the remaining pages.
|
||||
c.onPagesBoundSynchronously(currentScreenIndices);
|
||||
c.executeOnNextDraw((ViewOnDrawExecutor) deferredExecutor);
|
||||
|
||||
}, mUiExecutor);
|
||||
}
|
||||
executeCallbacksTask(
|
||||
c -> {
|
||||
MODEL_EXECUTOR.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
|
||||
c.onInitialBindComplete(currentScreenIndices, pendingTasks);
|
||||
}, mUiExecutor);
|
||||
}
|
||||
|
||||
private void bindWorkspaceItems(
|
||||
|
|
|
@ -49,7 +49,7 @@ import com.android.launcher3.util.IntArray;
|
|||
import com.android.launcher3.util.IntSet;
|
||||
import com.android.launcher3.util.IntSparseArrayMap;
|
||||
import com.android.launcher3.util.ItemInfoMatcher;
|
||||
import com.android.launcher3.util.ViewOnDrawExecutor;
|
||||
import com.android.launcher3.util.RunnableList;
|
||||
import com.android.launcher3.widget.model.WidgetsListBaseEntry;
|
||||
|
||||
import java.io.FileDescriptor;
|
||||
|
@ -462,35 +462,41 @@ public class BgDataModel {
|
|||
* Returns an IntSet of page numbers to bind first, synchronously if possible
|
||||
* or an empty IntSet
|
||||
*/
|
||||
IntSet getPagesToBindSynchronously();
|
||||
void clearPendingBinds();
|
||||
void startBinding();
|
||||
void bindItems(List<ItemInfo> shortcuts, boolean forceAnimateIcons);
|
||||
void bindScreens(IntArray orderedScreenIds);
|
||||
void finishFirstPageBind(ViewOnDrawExecutor executor);
|
||||
void finishBindingItems(IntSet pagesBoundFirst);
|
||||
void preAddApps();
|
||||
void bindAppsAdded(IntArray newScreens,
|
||||
ArrayList<ItemInfo> addNotAnimated, ArrayList<ItemInfo> addAnimated);
|
||||
default IntSet getPagesToBindSynchronously() {
|
||||
return new IntSet();
|
||||
}
|
||||
|
||||
default void clearPendingBinds() { }
|
||||
default void startBinding() { }
|
||||
|
||||
default void bindItems(List<ItemInfo> shortcuts, boolean forceAnimateIcons) { }
|
||||
default void bindScreens(IntArray orderedScreenIds) { }
|
||||
default void finishBindingItems(IntSet pagesBoundFirst) { }
|
||||
default void preAddApps() { }
|
||||
default void bindAppsAdded(IntArray newScreens,
|
||||
ArrayList<ItemInfo> addNotAnimated, ArrayList<ItemInfo> addAnimated) { }
|
||||
|
||||
/**
|
||||
* Binds updated incremental download progress
|
||||
*/
|
||||
void bindIncrementalDownloadProgressUpdated(AppInfo app);
|
||||
void bindWorkspaceItemsChanged(List<WorkspaceItemInfo> updated);
|
||||
void bindWidgetsRestored(ArrayList<LauncherAppWidgetInfo> widgets);
|
||||
void bindRestoreItemsChange(HashSet<ItemInfo> updates);
|
||||
void bindWorkspaceComponentsRemoved(ItemInfoMatcher matcher);
|
||||
void bindAllWidgets(List<WidgetsListBaseEntry> widgets);
|
||||
void onPagesBoundSynchronously(IntSet pages);
|
||||
void executeOnNextDraw(ViewOnDrawExecutor executor);
|
||||
void bindDeepShortcutMap(HashMap<ComponentKey, Integer> deepShortcutMap);
|
||||
default void bindIncrementalDownloadProgressUpdated(AppInfo app) { }
|
||||
default void bindWorkspaceItemsChanged(List<WorkspaceItemInfo> updated) { }
|
||||
default void bindWidgetsRestored(ArrayList<LauncherAppWidgetInfo> widgets) { }
|
||||
default void bindRestoreItemsChange(HashSet<ItemInfo> updates) { }
|
||||
default void bindWorkspaceComponentsRemoved(ItemInfoMatcher matcher) { }
|
||||
default void bindAllWidgets(List<WidgetsListBaseEntry> widgets) { }
|
||||
|
||||
default void onInitialBindComplete(IntSet boundPages, RunnableList pendingTasks) {
|
||||
pendingTasks.executeAllAndDestroy();
|
||||
}
|
||||
|
||||
default void bindDeepShortcutMap(HashMap<ComponentKey, Integer> deepShortcutMap) { }
|
||||
|
||||
/**
|
||||
* Binds extra item provided any external source
|
||||
*/
|
||||
default void bindExtraContainerItems(FixedContainerItems item) { }
|
||||
|
||||
void bindAllApplications(AppInfo[] apps, int flags);
|
||||
default void bindAllApplications(AppInfo[] apps, int flags) { }
|
||||
}
|
||||
}
|
||||
|
|
|
@ -35,23 +35,13 @@ import com.android.launcher3.model.BgDataModel;
|
|||
import com.android.launcher3.model.data.AppInfo;
|
||||
import com.android.launcher3.model.data.ItemInfo;
|
||||
import com.android.launcher3.model.data.ItemInfoWithIcon;
|
||||
import com.android.launcher3.model.data.LauncherAppWidgetInfo;
|
||||
import com.android.launcher3.model.data.WorkspaceItemInfo;
|
||||
import com.android.launcher3.popup.PopupContainerWithArrow;
|
||||
import com.android.launcher3.popup.PopupDataProvider;
|
||||
import com.android.launcher3.util.ComponentKey;
|
||||
import com.android.launcher3.util.IntArray;
|
||||
import com.android.launcher3.util.IntSet;
|
||||
import com.android.launcher3.util.ItemInfoMatcher;
|
||||
import com.android.launcher3.util.Themes;
|
||||
import com.android.launcher3.util.ViewOnDrawExecutor;
|
||||
import com.android.launcher3.views.BaseDragLayer;
|
||||
import com.android.launcher3.widget.model.WidgetsListBaseEntry;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Launcher activity for secondary displays
|
||||
|
@ -175,68 +165,11 @@ public class SecondaryDisplayLauncher extends BaseDraggingActivity
|
|||
return mDragLayer;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IntSet getPagesToBindSynchronously() {
|
||||
return new IntSet();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void clearPendingBinds() { }
|
||||
|
||||
@Override
|
||||
public void startBinding() { }
|
||||
|
||||
@Override
|
||||
public void bindItems(List<ItemInfo> shortcuts, boolean forceAnimateIcons) { }
|
||||
|
||||
@Override
|
||||
public void bindScreens(IntArray orderedScreenIds) { }
|
||||
|
||||
@Override
|
||||
public void finishFirstPageBind(ViewOnDrawExecutor executor) {
|
||||
if (executor != null) {
|
||||
executor.onLoadAnimationCompleted();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void finishBindingItems(IntSet pagesBoundFirst) { }
|
||||
|
||||
@Override
|
||||
public void preAddApps() { }
|
||||
|
||||
@Override
|
||||
public void bindAppsAdded(IntArray newScreens, ArrayList<ItemInfo> addNotAnimated,
|
||||
ArrayList<ItemInfo> addAnimated) { }
|
||||
|
||||
@Override
|
||||
public void bindIncrementalDownloadProgressUpdated(AppInfo app) {
|
||||
mAppsView.getAppsStore().updateProgressBar(app);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void bindWorkspaceItemsChanged(List<WorkspaceItemInfo> updated) { }
|
||||
|
||||
@Override
|
||||
public void bindWidgetsRestored(ArrayList<LauncherAppWidgetInfo> widgets) { }
|
||||
|
||||
@Override
|
||||
public void bindRestoreItemsChange(HashSet<ItemInfo> updates) { }
|
||||
|
||||
@Override
|
||||
public void bindWorkspaceComponentsRemoved(ItemInfoMatcher matcher) { }
|
||||
|
||||
@Override
|
||||
public void bindAllWidgets(List<WidgetsListBaseEntry> widgets) { }
|
||||
|
||||
@Override
|
||||
public void onPagesBoundSynchronously(IntSet pages) { }
|
||||
|
||||
@Override
|
||||
public void executeOnNextDraw(ViewOnDrawExecutor executor) {
|
||||
executor.attachTo(getDragLayer(), false, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when apps-button is clicked
|
||||
*/
|
||||
|
|
|
@ -16,28 +16,21 @@
|
|||
|
||||
package com.android.launcher3.util;
|
||||
|
||||
import static com.android.launcher3.util.Executors.MODEL_EXECUTOR;
|
||||
|
||||
import android.os.Process;
|
||||
import android.view.View;
|
||||
import android.view.View.OnAttachStateChangeListener;
|
||||
import android.view.ViewTreeObserver.OnDrawListener;
|
||||
|
||||
import androidx.annotation.VisibleForTesting;
|
||||
|
||||
import com.android.launcher3.Launcher;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.concurrent.Executor;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
/**
|
||||
* An executor which runs all the tasks after the first onDraw is called on the target view.
|
||||
*/
|
||||
public class ViewOnDrawExecutor implements Executor, OnDrawListener, Runnable,
|
||||
public class ViewOnDrawExecutor implements OnDrawListener, Runnable,
|
||||
OnAttachStateChangeListener {
|
||||
|
||||
private final ArrayList<Runnable> mTasks = new ArrayList<>();
|
||||
private final RunnableList mTasks;
|
||||
|
||||
private Consumer<ViewOnDrawExecutor> mOnClearCallback;
|
||||
private View mAttachedView;
|
||||
|
@ -46,22 +39,16 @@ public class ViewOnDrawExecutor implements Executor, OnDrawListener, Runnable,
|
|||
private boolean mLoadAnimationCompleted;
|
||||
private boolean mFirstDrawCompleted;
|
||||
|
||||
public void attachTo(Launcher launcher) {
|
||||
attachTo(launcher.getWorkspace(), true /* waitForLoadAnimation */,
|
||||
launcher::clearPendingExecutor);
|
||||
private boolean mCancelled;
|
||||
|
||||
public ViewOnDrawExecutor(RunnableList tasks) {
|
||||
mTasks = tasks;
|
||||
}
|
||||
|
||||
/**
|
||||
* Attached the executor to the existence of the view
|
||||
*/
|
||||
public void attachTo(View attachedView, boolean waitForLoadAnimation,
|
||||
Consumer<ViewOnDrawExecutor> onClearCallback) {
|
||||
mOnClearCallback = onClearCallback;
|
||||
mAttachedView = attachedView;
|
||||
public void attachTo(Launcher launcher) {
|
||||
mOnClearCallback = launcher::clearPendingExecutor;
|
||||
mAttachedView = launcher.getWorkspace();
|
||||
mAttachedView.addOnAttachStateChangeListener(this);
|
||||
if (!waitForLoadAnimation) {
|
||||
mLoadAnimationCompleted = true;
|
||||
}
|
||||
|
||||
if (mAttachedView.isAttachedToWindow()) {
|
||||
attachObserver();
|
||||
|
@ -74,12 +61,6 @@ public class ViewOnDrawExecutor implements Executor, OnDrawListener, Runnable,
|
|||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(Runnable command) {
|
||||
mTasks.add(command);
|
||||
MODEL_EXECUTOR.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onViewAttachedToWindow(View v) {
|
||||
attachObserver();
|
||||
|
@ -105,12 +86,17 @@ public class ViewOnDrawExecutor implements Executor, OnDrawListener, Runnable,
|
|||
public void run() {
|
||||
// Post the pending tasks after both onDraw and onLoadAnimationCompleted have been called.
|
||||
if (mLoadAnimationCompleted && mFirstDrawCompleted && !mCompleted) {
|
||||
runAllTasks();
|
||||
markCompleted();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Executes all tasks immediately
|
||||
*/
|
||||
public void markCompleted() {
|
||||
mTasks.clear();
|
||||
if (!mCancelled) {
|
||||
mTasks.executeAllAndDestroy();
|
||||
}
|
||||
mCompleted = true;
|
||||
if (mAttachedView != null) {
|
||||
mAttachedView.getViewTreeObserver().removeOnDrawListener(this);
|
||||
|
@ -119,21 +105,10 @@ public class ViewOnDrawExecutor implements Executor, OnDrawListener, Runnable,
|
|||
if (mOnClearCallback != null) {
|
||||
mOnClearCallback.accept(this);
|
||||
}
|
||||
MODEL_EXECUTOR.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT);
|
||||
}
|
||||
|
||||
protected boolean isCompleted() {
|
||||
return mCompleted;
|
||||
}
|
||||
|
||||
/**
|
||||
* Executes all tasks immediately
|
||||
*/
|
||||
@VisibleForTesting
|
||||
public void runAllTasks() {
|
||||
for (final Runnable r : mTasks) {
|
||||
r.run();
|
||||
}
|
||||
public void cancel() {
|
||||
mCancelled = true;
|
||||
markCompleted();
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue