diff --git a/res/drawable/bg_deferred_app_widget.xml b/res/drawable/bg_deferred_app_widget.xml
new file mode 100644
index 0000000000..07bae480b2
--- /dev/null
+++ b/res/drawable/bg_deferred_app_widget.xml
@@ -0,0 +1,25 @@
+
+
+
+
+
+
diff --git a/src/com/android/launcher3/AppWidgetResizeFrame.java b/src/com/android/launcher3/AppWidgetResizeFrame.java
index 1e95333ff2..7648e30375 100644
--- a/src/com/android/launcher3/AppWidgetResizeFrame.java
+++ b/src/com/android/launcher3/AppWidgetResizeFrame.java
@@ -19,6 +19,7 @@ import android.view.ViewGroup;
import com.android.launcher3.accessibility.DragViewStateAnnouncer;
import com.android.launcher3.dragndrop.DragLayer;
import com.android.launcher3.util.FocusLogic;
+import com.android.launcher3.widget.LauncherAppWidgetHostView;
public class AppWidgetResizeFrame extends AbstractFloatingView implements View.OnKeyListener {
private static final int SNAP_DURATION = 150;
diff --git a/src/com/android/launcher3/CellLayout.java b/src/com/android/launcher3/CellLayout.java
index 01b6ca987e..4087df1b10 100644
--- a/src/com/android/launcher3/CellLayout.java
+++ b/src/com/android/launcher3/CellLayout.java
@@ -60,6 +60,7 @@ import com.android.launcher3.util.GridOccupancy;
import com.android.launcher3.util.ParcelableSparseArray;
import com.android.launcher3.util.Themes;
import com.android.launcher3.util.Thunk;
+import com.android.launcher3.widget.LauncherAppWidgetHostView;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
diff --git a/src/com/android/launcher3/Launcher.java b/src/com/android/launcher3/Launcher.java
index 44660ecc10..9eaa6c73a4 100644
--- a/src/com/android/launcher3/Launcher.java
+++ b/src/com/android/launcher3/Launcher.java
@@ -29,8 +29,6 @@ import static com.android.launcher3.LauncherState.ALL_APPS;
import static com.android.launcher3.LauncherState.NORMAL;
import static com.android.launcher3.LauncherState.OVERVIEW;
import static com.android.launcher3.logging.LoggerUtils.newContainerTarget;
-import static com.android.launcher3.util.RunnableWithId.RUNNABLE_ID_BIND_APPS;
-import static com.android.launcher3.util.RunnableWithId.RUNNABLE_ID_BIND_WIDGETS;
import android.Manifest;
import android.animation.Animator;
@@ -127,15 +125,16 @@ import com.android.launcher3.util.MultiHashMap;
import com.android.launcher3.util.PackageManagerHelper;
import com.android.launcher3.util.PackageUserKey;
import com.android.launcher3.util.PendingRequestArgs;
-import com.android.launcher3.util.RunnableWithId;
import com.android.launcher3.util.SystemUiController;
import com.android.launcher3.util.Themes;
import com.android.launcher3.util.Thunk;
import com.android.launcher3.util.TraceHelper;
import com.android.launcher3.util.UiThreadHelper;
import com.android.launcher3.util.ViewOnDrawExecutor;
+import com.android.launcher3.widget.LauncherAppWidgetHostView;
import com.android.launcher3.widget.PendingAddShortcutInfo;
import com.android.launcher3.widget.PendingAddWidgetInfo;
+import com.android.launcher3.widget.PendingAppWidgetHostView;
import com.android.launcher3.widget.WidgetAddFlowHandler;
import com.android.launcher3.widget.WidgetHostViewLoader;
import com.android.launcher3.widget.WidgetListRowEntry;
@@ -237,9 +236,7 @@ public class Launcher extends BaseActivity
@Thunk boolean mWorkspaceLoading = true;
private boolean mPaused = true;
- private boolean mOnResumeNeedsLoad;
- private final ArrayList mBindOnResumeCallbacks = new ArrayList<>();
private OnResumeCallback mOnResumeCallback;
private ViewOnDrawExecutor mPendingExecutor;
@@ -811,20 +808,6 @@ public class Launcher extends BaseActivity
mAppLaunchSuccess = false;
getUserEventDispatcher().resetElapsedSessionMillis();
mPaused = false;
- if (mOnResumeNeedsLoad) {
- setWorkspaceLoading(true);
- mModel.startLoader(getCurrentWorkspaceScreen());
- mOnResumeNeedsLoad = false;
- }
- if (mBindOnResumeCallbacks.size() > 0) {
- // We might have postponed some bind calls until onResume (see waitUntilResume) --
- // execute them here
- for (int i = 0; i < mBindOnResumeCallbacks.size(); i++) {
- mBindOnResumeCallbacks.get(i).run();
- }
- mBindOnResumeCallbacks.clear();
- }
-
setOnResumeCallback(null);
// Process any items that were added while Launcher was away.
InstallShortcutReceiver.disableAndFlushInstallQueue(
@@ -1161,20 +1144,12 @@ public class Launcher extends BaseActivity
};
public void updateIconBadges(final Set updatedBadges) {
- Runnable r = new Runnable() {
- @Override
- public void run() {
- mWorkspace.updateIconBadges(updatedBadges);
- mAppsView.updateIconBadges(updatedBadges);
+ mWorkspace.updateIconBadges(updatedBadges);
+ mAppsView.updateIconBadges(updatedBadges);
- PopupContainerWithArrow popup = PopupContainerWithArrow.getOpen(Launcher.this);
- if (popup != null) {
- popup.updateNotificationHeader(updatedBadges);
- }
- }
- };
- if (!waitUntilResume(r)) {
- r.run();
+ PopupContainerWithArrow popup = PopupContainerWithArrow.getOpen(Launcher.this);
+ if (popup != null) {
+ popup.updateNotificationHeader(updatedBadges);
}
}
@@ -2156,33 +2131,6 @@ public class Launcher extends BaseActivity
return result;
}
- /**
- * If the activity is currently paused, signal that we need to run the passed Runnable
- * in onResume.
- *
- * This needs to be called from incoming places where resources might have been loaded
- * while the activity is paused. That is because the Configuration (e.g., rotation) might be
- * wrong when we're not running, and if the activity comes back to what the configuration was
- * when we were paused, activity is not restarted.
- *
- * Implementation of the method from LauncherModel.Callbacks.
- *
- * @return {@code true} if we are currently paused. The caller might be able to skip some work
- */
- @Thunk boolean waitUntilResume(Runnable run) {
- if (mPaused) {
- if (LOGD) Log.d(TAG, "Deferring update until onResume");
- if (run instanceof RunnableWithId) {
- // Remove any runnables which have the same id
- while (mBindOnResumeCallbacks.remove(run)) { }
- }
- mBindOnResumeCallbacks.add(run);
- return true;
- } else {
- return false;
- }
- }
-
public void setOnResumeCallback(OnResumeCallback callback) {
if (mOnResumeCallback != null) {
mOnResumeCallback.onLauncherResume();
@@ -2190,31 +2138,6 @@ public class Launcher extends BaseActivity
mOnResumeCallback = callback;
}
- /**
- * If the activity is currently paused, signal that we need to re-run the loader
- * in onResume.
- *
- * This needs to be called from incoming places where resources might have been loaded
- * while we are paused. That is becaues the Configuration might be wrong
- * when we're not running, and if it comes back to what it was when we
- * were paused, we are not restarted.
- *
- * Implementation of the method from LauncherModel.Callbacks.
- *
- * @return true if we are currently paused. The caller might be able to
- * skip some work in that case since we will come back again.
- */
- @Override
- public boolean setLoadOnResume() {
- if (mPaused) {
- if (LOGD) Log.d(TAG, "setLoadOnResume");
- mOnResumeNeedsLoad = true;
- return true;
- } else {
- return false;
- }
- }
-
/**
* Implementation of the method from LauncherModel.Callbacks.
*/
@@ -2233,7 +2156,6 @@ public class Launcher extends BaseActivity
*/
@Override
public void clearPendingBinds() {
- mBindOnResumeCallbacks.clear();
if (mPendingExecutor != null) {
mPendingExecutor.markCompleted();
mPendingExecutor = null;
@@ -2297,18 +2219,8 @@ public class Launcher extends BaseActivity
}
@Override
- public void bindAppsAdded(final ArrayList newScreens,
- final ArrayList addNotAnimated,
- final ArrayList addAnimated) {
- Runnable r = new Runnable() {
- public void run() {
- bindAppsAdded(newScreens, addNotAnimated, addAnimated);
- }
- };
- if (waitUntilResume(r)) {
- return;
- }
-
+ public void bindAppsAdded(ArrayList newScreens, ArrayList addNotAnimated,
+ ArrayList addAnimated) {
// Add the new screens
if (newScreens != null) {
bindAddScreens(newScreens);
@@ -2334,15 +2246,6 @@ public class Launcher extends BaseActivity
*/
@Override
public void bindItems(final List items, final boolean forceAnimateIcons) {
- Runnable r = new Runnable() {
- public void run() {
- bindItems(items, forceAnimateIcons);
- }
- };
- if (waitUntilResume(r)) {
- return;
- }
-
// Get the list of added items and intersect them with the set of items here
final AnimatorSet anim = LauncherAnimUtils.createAnimatorSet();
final Collection bounceAnims = new ArrayList<>();
@@ -2585,7 +2488,7 @@ public class Launcher extends BaseActivity
}
if (((PendingAppWidgetHostView) view).isReinflateIfNeeded()) {
- view.reinflate();
+ view.reInflate();
}
getModelWriter().updateItemInDatabase(info);
@@ -2613,27 +2516,11 @@ public class Launcher extends BaseActivity
@Override
public void finishFirstPageBind(final ViewOnDrawExecutor executor) {
- Runnable r = new Runnable() {
- public void run() {
- finishFirstPageBind(executor);
- }
- };
- if (waitUntilResume(r)) {
- return;
- }
-
- Runnable onComplete = new Runnable() {
- @Override
- public void run() {
- if (executor != null) {
- executor.onLoadAnimationCompleted();
- }
- }
- };
if (mDragLayer.getAlpha() < 1) {
- mDragLayer.animate().alpha(1).withEndAction(onComplete).start();
- } else {
- onComplete.run();
+ mDragLayer.animate().alpha(1).withEndAction(
+ executor == null ? null : executor::onLoadAnimationCompleted).start();
+ } else if (executor != null) {
+ executor.onLoadAnimationCompleted();
}
}
@@ -2643,10 +2530,6 @@ public class Launcher extends BaseActivity
* Implementation of the method from LauncherModel.Callbacks.
*/
public void finishBindingItems() {
- Runnable r = this::finishBindingItems;
- if (waitUntilResume(r)) {
- return;
- }
TraceHelper.beginSection("finishBindingItems");
mWorkspace.restoreInstanceStateForRemainingPages();
@@ -2687,21 +2570,12 @@ public class Launcher extends BaseActivity
*
* Implementation of the method from LauncherModel.Callbacks.
*/
- public void bindAllApplications(final ArrayList apps) {
- Runnable r = new RunnableWithId(RUNNABLE_ID_BIND_APPS) {
- public void run() {
- bindAllApplications(apps);
- }
- };
- if (waitUntilResume(r)) {
- return;
- }
-
+ public void bindAllApplications(ArrayList apps) {
if (mAppsView != null) {
Executor pendingExecutor = getPendingExecutor();
if (pendingExecutor != null && !isInState(ALL_APPS)) {
// Wait until the fade in animation has finished before setting all apps list.
- pendingExecutor.execute(r);
+ pendingExecutor.execute(() -> bindAllApplications(apps));
return;
}
@@ -2734,47 +2608,22 @@ public class Launcher extends BaseActivity
*
* Implementation of the method from LauncherModel.Callbacks.
*/
- public void bindAppsAddedOrUpdated(final ArrayList apps) {
- Runnable r = new Runnable() {
- public void run() {
- bindAppsAddedOrUpdated(apps);
- }
- };
- if (waitUntilResume(r)) {
- return;
- }
-
+ @Override
+ public void bindAppsAddedOrUpdated(ArrayList apps) {
if (mAppsView != null) {
mAppsView.addOrUpdateApps(apps);
}
}
@Override
- public void bindPromiseAppProgressUpdated(final PromiseAppInfo app) {
- Runnable r = new Runnable() {
- public void run() {
- bindPromiseAppProgressUpdated(app);
- }
- };
- if (waitUntilResume(r)) {
- return;
- }
-
+ public void bindPromiseAppProgressUpdated(PromiseAppInfo app) {
if (mAppsView != null) {
mAppsView.updatePromiseAppProgress(app);
}
}
@Override
- public void bindWidgetsRestored(final ArrayList widgets) {
- Runnable r = new Runnable() {
- public void run() {
- bindWidgetsRestored(widgets);
- }
- };
- if (waitUntilResume(r)) {
- return;
- }
+ public void bindWidgetsRestored(ArrayList widgets) {
mWorkspace.widgetsRestored(widgets);
}
@@ -2785,16 +2634,7 @@ public class Launcher extends BaseActivity
* @param updated list of shortcuts which have changed.
*/
@Override
- public void bindShortcutsChanged(final ArrayList updated, final UserHandle user) {
- Runnable r = new Runnable() {
- public void run() {
- bindShortcutsChanged(updated, user);
- }
- };
- if (waitUntilResume(r)) {
- return;
- }
-
+ public void bindShortcutsChanged(ArrayList updated, final UserHandle user) {
if (!updated.isEmpty()) {
mWorkspace.updateShortcuts(updated);
}
@@ -2806,16 +2646,7 @@ public class Launcher extends BaseActivity
* Implementation of the method from LauncherModel.Callbacks.
*/
@Override
- public void bindRestoreItemsChange(final HashSet updates) {
- Runnable r = new Runnable() {
- public void run() {
- bindRestoreItemsChange(updates);
- }
- };
- if (waitUntilResume(r)) {
- return;
- }
-
+ public void bindRestoreItemsChange(HashSet updates) {
mWorkspace.updateRestoreItems(updates);
}
@@ -2828,29 +2659,12 @@ public class Launcher extends BaseActivity
*/
@Override
public void bindWorkspaceComponentsRemoved(final ItemInfoMatcher matcher) {
- Runnable r = new Runnable() {
- public void run() {
- bindWorkspaceComponentsRemoved(matcher);
- }
- };
- if (waitUntilResume(r)) {
- return;
- }
mWorkspace.removeItemsByMatcher(matcher);
mDragController.onAppsRemoved(matcher);
}
@Override
public void bindAppInfosRemoved(final ArrayList appInfos) {
- Runnable r = new Runnable() {
- public void run() {
- bindAppInfosRemoved(appInfos);
- }
- };
- if (waitUntilResume(r)) {
- return;
- }
-
// Update AllApps
if (mAppsView != null) {
mAppsView.removeApps(appInfos);
@@ -2860,16 +2674,6 @@ public class Launcher extends BaseActivity
@Override
public void bindAllWidgets(final ArrayList allWidgets) {
mPopupDataProvider.setAllWidgets(allWidgets);
- Runnable r = new RunnableWithId(RUNNABLE_ID_BIND_WIDGETS) {
- @Override
- public void run() {
- bindAllWidgets(allWidgets);
- }
- };
- if (waitUntilResume(r)) {
- return;
- }
-
AbstractFloatingView topView = AbstractFloatingView.getTopOpenView(this);
if (topView != null) {
topView.onWidgetsBound();
diff --git a/src/com/android/launcher3/LauncherAppState.java b/src/com/android/launcher3/LauncherAppState.java
index 0136c7087f..a46692b0b5 100644
--- a/src/com/android/launcher3/LauncherAppState.java
+++ b/src/com/android/launcher3/LauncherAppState.java
@@ -27,6 +27,7 @@ import android.util.Log;
import com.android.launcher3.compat.LauncherAppsCompat;
import com.android.launcher3.compat.PackageInstallerCompat;
import com.android.launcher3.compat.UserManagerCompat;
+import com.android.launcher3.config.FeatureFlags;
import com.android.launcher3.notification.NotificationListener;
import com.android.launcher3.util.ConfigMonitor;
import com.android.launcher3.util.Preconditions;
@@ -39,6 +40,8 @@ import static com.android.launcher3.SettingsActivity.NOTIFICATION_BADGING;
public class LauncherAppState {
+ public static final String ACTION_FORCE_ROLOAD = "force-reload-launcher";
+
// We do not need any synchronization for this variable as its only written on UI thread.
private static LauncherAppState INSTANCE;
@@ -103,6 +106,10 @@ public class LauncherAppState {
filter.addAction(Intent.ACTION_MANAGED_PROFILE_UNAVAILABLE);
filter.addAction(Intent.ACTION_MANAGED_PROFILE_UNLOCKED);
+ if (FeatureFlags.IS_DOGFOOD_BUILD) {
+ filter.addAction(ACTION_FORCE_ROLOAD);
+ }
+
mContext.registerReceiver(mModel, filter);
UserManagerCompat.getInstance(mContext).enableAndResetCache();
new ConfigMonitor(mContext).register();
diff --git a/src/com/android/launcher3/LauncherAppWidgetHost.java b/src/com/android/launcher3/LauncherAppWidgetHost.java
index 9aa74b38d5..7bc713922b 100644
--- a/src/com/android/launcher3/LauncherAppWidgetHost.java
+++ b/src/com/android/launcher3/LauncherAppWidgetHost.java
@@ -26,11 +26,14 @@ import android.content.ActivityNotFoundException;
import android.content.Context;
import android.content.Intent;
import android.os.Handler;
+import android.util.Log;
import android.util.SparseArray;
import android.view.LayoutInflater;
import android.widget.Toast;
import com.android.launcher3.config.FeatureFlags;
+import com.android.launcher3.widget.DeferredAppWidgetHostView;
+import com.android.launcher3.widget.LauncherAppWidgetHostView;
import java.util.ArrayList;
@@ -84,6 +87,14 @@ public class LauncherAppWidgetHost extends AppWidgetHost {
// have been established by this point, and we will end up populating the
// widgets upon bind anyway. See issue 14255011 for more context.
}
+
+ // We go in reverse order and inflate any deferred widget
+ for (int i = mViews.size() - 1; i >= 0; i--) {
+ LauncherAppWidgetHostView view = mViews.valueAt(i);
+ if (view instanceof DeferredAppWidgetHostView) {
+ view.reInflate();
+ }
+ }
}
@Override
@@ -178,6 +189,11 @@ public class LauncherAppWidgetHost extends AppWidgetHost {
inflater.inflate(appWidget.initialLayout, lahv);
lahv.setAppWidget(0, appWidget);
return lahv;
+ } else if ((mFlags & FLAG_LISTENING) == 0) {
+ DeferredAppWidgetHostView view = new DeferredAppWidgetHostView(context);
+ view.setAppWidget(appWidgetId, appWidget);
+ mViews.put(appWidgetId, view);
+ return view;
} else {
try {
return super.createView(context, appWidgetId, appWidget);
diff --git a/src/com/android/launcher3/LauncherModel.java b/src/com/android/launcher3/LauncherModel.java
index 469c5f1c09..35bf9e9ee8 100644
--- a/src/com/android/launcher3/LauncherModel.java
+++ b/src/com/android/launcher3/LauncherModel.java
@@ -16,6 +16,9 @@
package com.android.launcher3;
+import static com.android.launcher3.LauncherAppState.ACTION_FORCE_ROLOAD;
+import static com.android.launcher3.config.FeatureFlags.IS_DOGFOOD_BUILD;
+
import android.content.BroadcastReceiver;
import android.content.ComponentName;
import android.content.ContentProviderOperation;
@@ -37,6 +40,7 @@ import android.util.Pair;
import com.android.launcher3.compat.LauncherAppsCompat;
import com.android.launcher3.compat.PackageInstallerCompat.PackageInstallInfo;
import com.android.launcher3.compat.UserManagerCompat;
+import com.android.launcher3.config.FeatureFlags;
import com.android.launcher3.graphics.LauncherIcons;
import com.android.launcher3.model.AddWorkspaceItemsTask;
import com.android.launcher3.model.BgDataModel;
@@ -135,7 +139,6 @@ public class LauncherModel extends BroadcastReceiver
};
public interface Callbacks {
- public boolean setLoadOnResume();
public int getCurrentWorkspaceScreen();
public void clearPendingBinds();
public void startBinding();
@@ -405,6 +408,8 @@ public class LauncherModel extends BroadcastReceiver
enqueueModelUpdateTask(new UserLockStateChangedTask(user));
}
}
+ } else if (IS_DOGFOOD_BUILD && ACTION_FORCE_ROLOAD.equals(action)) {
+ forceReload();
}
}
@@ -419,25 +424,11 @@ public class LauncherModel extends BroadcastReceiver
mModelLoaded = false;
}
- // Do this here because if the launcher activity is running it will be restarted.
- // If it's not running startLoaderFromBackground will merely tell it that it needs
- // to reload.
- startLoaderFromBackground();
- }
-
- /**
- * When the launcher is in the background, it's possible for it to miss paired
- * configuration changes. So whenever we trigger the loader from the background
- * tell the launcher that it needs to re-run the loader when it comes back instead
- * of doing it now.
- */
- public void startLoaderFromBackground() {
+ // Start the loader if launcher is already running, otherwise the loader will run,
+ // the next time launcher starts
Callbacks callbacks = getCallback();
if (callbacks != null) {
- // Only actually run the loader if they're not paused.
- if (!callbacks.setLoadOnResume()) {
- startLoader(callbacks.getCurrentWorkspaceScreen());
- }
+ startLoader(callbacks.getCurrentWorkspaceScreen());
}
}
diff --git a/src/com/android/launcher3/ShortcutAndWidgetContainer.java b/src/com/android/launcher3/ShortcutAndWidgetContainer.java
index 841c0cd57a..1a63326dd2 100644
--- a/src/com/android/launcher3/ShortcutAndWidgetContainer.java
+++ b/src/com/android/launcher3/ShortcutAndWidgetContainer.java
@@ -23,6 +23,7 @@ import android.view.View;
import android.view.ViewGroup;
import com.android.launcher3.CellLayout.ContainerType;
+import com.android.launcher3.widget.LauncherAppWidgetHostView;
public class ShortcutAndWidgetContainer extends ViewGroup {
static final String TAG = "ShortcutAndWidgetContainer";
diff --git a/src/com/android/launcher3/Workspace.java b/src/com/android/launcher3/Workspace.java
index 417366d18a..efafb9c424 100644
--- a/src/com/android/launcher3/Workspace.java
+++ b/src/com/android/launcher3/Workspace.java
@@ -88,8 +88,10 @@ import com.android.launcher3.util.LongArrayMap;
import com.android.launcher3.util.PackageUserKey;
import com.android.launcher3.util.Thunk;
import com.android.launcher3.util.WallpaperOffsetInterpolator;
+import com.android.launcher3.widget.LauncherAppWidgetHostView;
import com.android.launcher3.widget.PendingAddShortcutInfo;
import com.android.launcher3.widget.PendingAddWidgetInfo;
+import com.android.launcher3.widget.PendingAppWidgetHostView;
import java.util.ArrayList;
import java.util.HashSet;
@@ -3510,7 +3512,7 @@ public class Workspace extends PagedView
return false;
});
for (PendingAppWidgetHostView view : views) {
- view.reinflate();
+ view.reInflate();
}
}
diff --git a/src/com/android/launcher3/accessibility/LauncherAccessibilityDelegate.java b/src/com/android/launcher3/accessibility/LauncherAccessibilityDelegate.java
index 512db721e8..3b6fea9465 100644
--- a/src/com/android/launcher3/accessibility/LauncherAccessibilityDelegate.java
+++ b/src/com/android/launcher3/accessibility/LauncherAccessibilityDelegate.java
@@ -21,20 +21,17 @@ import com.android.launcher3.AppWidgetResizeFrame;
import com.android.launcher3.BubbleTextView;
import com.android.launcher3.ButtonDropTarget;
import com.android.launcher3.CellLayout;
-import com.android.launcher3.DeleteDropTarget;
import com.android.launcher3.DropTarget.DragObject;
import com.android.launcher3.FolderInfo;
-import com.android.launcher3.InfoDropTarget;
import com.android.launcher3.ItemInfo;
import com.android.launcher3.Launcher;
-import com.android.launcher3.LauncherAppWidgetHostView;
+import com.android.launcher3.widget.LauncherAppWidgetHostView;
import com.android.launcher3.LauncherAppWidgetInfo;
import com.android.launcher3.LauncherSettings;
import com.android.launcher3.LauncherSettings.Favorites;
import com.android.launcher3.PendingAddItemInfo;
import com.android.launcher3.R;
import com.android.launcher3.ShortcutInfo;
-import com.android.launcher3.UninstallDropTarget;
import com.android.launcher3.Workspace;
import com.android.launcher3.dragndrop.DragController.DragListener;
import com.android.launcher3.dragndrop.DragOptions;
diff --git a/src/com/android/launcher3/graphics/DragPreviewProvider.java b/src/com/android/launcher3/graphics/DragPreviewProvider.java
index 902906f4b7..6a328e9230 100644
--- a/src/com/android/launcher3/graphics/DragPreviewProvider.java
+++ b/src/com/android/launcher3/graphics/DragPreviewProvider.java
@@ -31,7 +31,7 @@ import android.view.View;
import com.android.launcher3.BubbleTextView;
import com.android.launcher3.Launcher;
-import com.android.launcher3.LauncherAppWidgetHostView;
+import com.android.launcher3.widget.LauncherAppWidgetHostView;
import com.android.launcher3.R;
import com.android.launcher3.config.FeatureFlags;
import com.android.launcher3.folder.FolderIcon;
diff --git a/src/com/android/launcher3/util/RunnableWithId.java b/src/com/android/launcher3/util/RunnableWithId.java
deleted file mode 100644
index 030eb09ff3..0000000000
--- a/src/com/android/launcher3/util/RunnableWithId.java
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.launcher3.util;
-
-/**
- * A runnable with an id associated which is used for equality check.
- */
-public abstract class RunnableWithId implements Runnable {
-
- public static final int RUNNABLE_ID_BIND_APPS = 1;
- public static final int RUNNABLE_ID_BIND_WIDGETS = 2;
-
- public final int id;
-
- public RunnableWithId(int id) {
- this.id = id;
- }
-
- @Override
- public boolean equals(Object obj) {
- return obj instanceof RunnableWithId && ((RunnableWithId) obj).id == id;
- }
-}
diff --git a/src/com/android/launcher3/widget/DeferredAppWidgetHostView.java b/src/com/android/launcher3/widget/DeferredAppWidgetHostView.java
new file mode 100644
index 0000000000..37e5efcb78
--- /dev/null
+++ b/src/com/android/launcher3/widget/DeferredAppWidgetHostView.java
@@ -0,0 +1,83 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.launcher3.widget;
+
+import android.appwidget.AppWidgetProviderInfo;
+import android.content.Context;
+import android.graphics.Canvas;
+import android.graphics.Color;
+import android.text.Layout;
+import android.text.StaticLayout;
+import android.text.TextPaint;
+import android.text.TextUtils;
+import android.util.TypedValue;
+import android.widget.RemoteViews;
+
+import com.android.launcher3.R;
+
+/**
+ * A widget host views created while the host has not bind to the system service.
+ */
+public class DeferredAppWidgetHostView extends LauncherAppWidgetHostView {
+
+ private final TextPaint mPaint;
+ private Layout mSetupTextLayout;
+
+ public DeferredAppWidgetHostView(Context context) {
+ super(context);
+ setWillNotDraw(false);
+
+ mPaint = new TextPaint();
+ mPaint.setColor(Color.WHITE);
+ mPaint.setTextSize(TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_PX,
+ mLauncher.getDeviceProfile().iconTextSizePx, getResources().getDisplayMetrics()));
+ setBackgroundResource(R.drawable.bg_deferred_app_widget);
+ }
+
+ @Override
+ public void updateAppWidget(RemoteViews remoteViews) {
+ // Not allowed
+ }
+
+ @Override
+ protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
+ super.onMeasure(widthMeasureSpec, heightMeasureSpec);
+
+ AppWidgetProviderInfo info = getAppWidgetInfo();
+ if (info == null || TextUtils.isEmpty(info.label)) {
+ return;
+ }
+
+ // Use double padding so that there is extra space between background and text
+ int availableWidth = getMeasuredWidth() - 2 * (getPaddingLeft() + getPaddingRight());
+ if (mSetupTextLayout != null && mSetupTextLayout.getText().equals(info.label)
+ && mSetupTextLayout.getWidth() == availableWidth) {
+ return;
+ }
+ mSetupTextLayout = new StaticLayout(info.label, mPaint, availableWidth,
+ Layout.Alignment.ALIGN_CENTER, 1, 0, true);
+ }
+
+ @Override
+ protected void onDraw(Canvas canvas) {
+ if (mSetupTextLayout != null) {
+ canvas.translate(getPaddingLeft() * 2,
+ (getHeight() - mSetupTextLayout.getHeight()) / 2);
+ mSetupTextLayout.draw(canvas);
+ }
+ }
+}
diff --git a/src/com/android/launcher3/LauncherAppWidgetHostView.java b/src/com/android/launcher3/widget/LauncherAppWidgetHostView.java
similarity index 92%
rename from src/com/android/launcher3/LauncherAppWidgetHostView.java
rename to src/com/android/launcher3/widget/LauncherAppWidgetHostView.java
index 6f953e5f0a..0b1474a037 100644
--- a/src/com/android/launcher3/LauncherAppWidgetHostView.java
+++ b/src/com/android/launcher3/widget/LauncherAppWidgetHostView.java
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package com.android.launcher3;
+package com.android.launcher3.widget;
import android.appwidget.AppWidgetHostView;
import android.appwidget.AppWidgetProviderInfo;
@@ -37,6 +37,15 @@ import android.widget.AdapterView;
import android.widget.Advanceable;
import android.widget.RemoteViews;
+import com.android.launcher3.CheckLongPressHelper;
+import com.android.launcher3.ItemInfo;
+import com.android.launcher3.Launcher;
+import com.android.launcher3.LauncherAppWidgetInfo;
+import com.android.launcher3.LauncherAppWidgetProviderInfo;
+import com.android.launcher3.R;
+import com.android.launcher3.SimpleOnStylusPressListener;
+import com.android.launcher3.StylusEventHelper;
+import com.android.launcher3.Utilities;
import com.android.launcher3.dragndrop.DragLayer;
import com.android.launcher3.dragndrop.DragLayer.TouchCompleteListener;
@@ -59,14 +68,10 @@ public class LauncherAppWidgetHostView extends AppWidgetHostView
private final CheckLongPressHelper mLongPressHelper;
private final StylusEventHelper mStylusEventHelper;
- private final Launcher mLauncher;
-
- private static final int DONT_REINFLATE = 0;
- private static final int REINFLATE_ON_RESUME = 1;
- private static final int REINFLATE_ON_CONFIG_CHANGE = 2;
+ protected final Launcher mLauncher;
@ViewDebug.ExportedProperty(category = "launcher")
- private int mReinflateStatus;
+ private boolean mReinflateOnConfigChange;
private float mSlop;
@@ -128,12 +133,7 @@ public class LauncherAppWidgetHostView extends AppWidgetHostView
// Consequently, the widgets will be inflated for the orientation of the foreground activity
// (framework issue). On resuming, we ensure that any widgets are inflated for the current
// orientation.
- if (mReinflateStatus == DONT_REINFLATE && !isSameOrientation()) {
- mReinflateStatus = REINFLATE_ON_RESUME;
- if (!mLauncher.waitUntilResume(new ReInflateRunnable())) {
- mReinflateStatus = REINFLATE_ON_CONFIG_CHANGE;
- }
- }
+ mReinflateOnConfigChange = !isSameOrientation();
}
private boolean isSameOrientation() {
@@ -485,40 +485,20 @@ public class LauncherAppWidgetHostView extends AppWidgetHostView
protected void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
- if (mReinflateStatus == REINFLATE_ON_CONFIG_CHANGE) {
- // We are finally in the same orientation
- reinflateIfNecessary();
+ // Only reinflate when the final configuration is same as the required configuration
+ if (mReinflateOnConfigChange && isSameOrientation()) {
+ mReinflateOnConfigChange = false;
+ if (isAttachedToWindow()) {
+ reInflate();
+ }
}
}
- private void reinflateIfNecessary() {
- if (!isSameOrientation()) {
- // We cannot reinflate yet, wait until next config change
- mReinflateStatus = REINFLATE_ON_CONFIG_CHANGE;
- return;
- }
-
- mReinflateStatus = DONT_REINFLATE;
- if (isAttachedToWindow()) {
- LauncherAppWidgetInfo info = (LauncherAppWidgetInfo) getTag();
- reinflate();
- }
- }
-
- public void reinflate() {
+ public void reInflate() {
LauncherAppWidgetInfo info = (LauncherAppWidgetInfo) getTag();
// Remove and rebind the current widget (which was inflated in the wrong
// orientation), but don't delete it from the database
mLauncher.removeItem(this, info, false /* deleteFromDb */);
mLauncher.bindAppWidget(info);
}
-
- private class ReInflateRunnable implements Runnable {
- @Override
- public void run() {
- if (mReinflateStatus == REINFLATE_ON_RESUME) {
- reinflateIfNecessary();
- }
- }
- }
}
diff --git a/src/com/android/launcher3/PendingAppWidgetHostView.java b/src/com/android/launcher3/widget/PendingAppWidgetHostView.java
similarity index 96%
rename from src/com/android/launcher3/PendingAppWidgetHostView.java
rename to src/com/android/launcher3/widget/PendingAppWidgetHostView.java
index b86d413185..24bcebb2e1 100644
--- a/src/com/android/launcher3/PendingAppWidgetHostView.java
+++ b/src/com/android/launcher3/widget/PendingAppWidgetHostView.java
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package com.android.launcher3;
+package com.android.launcher3.widget;
import android.content.Context;
import android.graphics.Bitmap;
@@ -32,10 +32,19 @@ import android.view.ContextThemeWrapper;
import android.view.View;
import android.view.View.OnClickListener;
+import com.android.launcher3.DeviceProfile;
+import com.android.launcher3.FastBitmapDrawable;
+import com.android.launcher3.IconCache;
import com.android.launcher3.IconCache.ItemInfoUpdateReceiver;
+import com.android.launcher3.ItemInfoWithIcon;
+import com.android.launcher3.Launcher;
+import com.android.launcher3.LauncherAppWidgetInfo;
+import com.android.launcher3.R;
+import com.android.launcher3.Utilities;
import com.android.launcher3.graphics.DrawableFactory;
import com.android.launcher3.model.PackageItemInfo;
import com.android.launcher3.util.Themes;
+import com.android.launcher3.widget.LauncherAppWidgetHostView;
public class PendingAppWidgetHostView extends LauncherAppWidgetHostView
implements OnClickListener, ItemInfoUpdateReceiver {
@@ -48,7 +57,6 @@ public class PendingAppWidgetHostView extends LauncherAppWidgetHostView
private final LauncherAppWidgetInfo mInfo;
private final int mStartState;
private final boolean mDisabledForSafeMode;
- private Launcher mLauncher;
private Bitmap mIcon;
@@ -64,7 +72,6 @@ public class PendingAppWidgetHostView extends LauncherAppWidgetHostView
IconCache cache, boolean disabledForSafeMode) {
super(new ContextThemeWrapper(context, R.style.WidgetContainerTheme));
- mLauncher = Launcher.getLauncher(context);
mInfo = info;
mStartState = info.restoreStatus;
mDisabledForSafeMode = disabledForSafeMode;
diff --git a/tests/src/com/android/launcher3/ui/widget/BindWidgetTest.java b/tests/src/com/android/launcher3/ui/widget/BindWidgetTest.java
index 87103d7133..32f90a6d88 100644
--- a/tests/src/com/android/launcher3/ui/widget/BindWidgetTest.java
+++ b/tests/src/com/android/launcher3/ui/widget/BindWidgetTest.java
@@ -30,12 +30,12 @@ import android.support.test.runner.AndroidJUnit4;
import android.support.test.uiautomator.UiSelector;
import com.android.launcher3.LauncherAppWidgetHost;
-import com.android.launcher3.LauncherAppWidgetHostView;
+import com.android.launcher3.widget.LauncherAppWidgetHostView;
import com.android.launcher3.LauncherAppWidgetInfo;
import com.android.launcher3.LauncherAppWidgetProviderInfo;
import com.android.launcher3.LauncherModel;
import com.android.launcher3.LauncherSettings;
-import com.android.launcher3.PendingAppWidgetHostView;
+import com.android.launcher3.widget.PendingAppWidgetHostView;
import com.android.launcher3.Workspace;
import com.android.launcher3.compat.AppWidgetManagerCompat;
import com.android.launcher3.compat.PackageInstallerCompat;