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