No more waiting around for resume
Apply model updates as son as they arrive instead of waiting for onResume. Various workspace items do not use any configuration dependent resources. For Widgets, we wait until the host starts lietening before inflating the actual view. Change-Id: Icb2f5e5940c1ce6c27062ccd34eff87e80af5ab1
This commit is contained in:
parent
e15e2a8267
commit
29947f0b53
|
@ -0,0 +1,25 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<!--
|
||||||
|
/*
|
||||||
|
**
|
||||||
|
** Copyright 2015, 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.
|
||||||
|
*/
|
||||||
|
-->
|
||||||
|
|
||||||
|
<inset
|
||||||
|
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:inset="8dp">
|
||||||
|
<color android:color="#77000000" />
|
||||||
|
</inset>
|
|
@ -19,6 +19,7 @@ import android.view.ViewGroup;
|
||||||
import com.android.launcher3.accessibility.DragViewStateAnnouncer;
|
import com.android.launcher3.accessibility.DragViewStateAnnouncer;
|
||||||
import com.android.launcher3.dragndrop.DragLayer;
|
import com.android.launcher3.dragndrop.DragLayer;
|
||||||
import com.android.launcher3.util.FocusLogic;
|
import com.android.launcher3.util.FocusLogic;
|
||||||
|
import com.android.launcher3.widget.LauncherAppWidgetHostView;
|
||||||
|
|
||||||
public class AppWidgetResizeFrame extends AbstractFloatingView implements View.OnKeyListener {
|
public class AppWidgetResizeFrame extends AbstractFloatingView implements View.OnKeyListener {
|
||||||
private static final int SNAP_DURATION = 150;
|
private static final int SNAP_DURATION = 150;
|
||||||
|
|
|
@ -60,6 +60,7 @@ import com.android.launcher3.util.GridOccupancy;
|
||||||
import com.android.launcher3.util.ParcelableSparseArray;
|
import com.android.launcher3.util.ParcelableSparseArray;
|
||||||
import com.android.launcher3.util.Themes;
|
import com.android.launcher3.util.Themes;
|
||||||
import com.android.launcher3.util.Thunk;
|
import com.android.launcher3.util.Thunk;
|
||||||
|
import com.android.launcher3.widget.LauncherAppWidgetHostView;
|
||||||
|
|
||||||
import java.lang.annotation.Retention;
|
import java.lang.annotation.Retention;
|
||||||
import java.lang.annotation.RetentionPolicy;
|
import java.lang.annotation.RetentionPolicy;
|
||||||
|
|
|
@ -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.NORMAL;
|
||||||
import static com.android.launcher3.LauncherState.OVERVIEW;
|
import static com.android.launcher3.LauncherState.OVERVIEW;
|
||||||
import static com.android.launcher3.logging.LoggerUtils.newContainerTarget;
|
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.Manifest;
|
||||||
import android.animation.Animator;
|
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.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.RunnableWithId;
|
|
||||||
import com.android.launcher3.util.SystemUiController;
|
import com.android.launcher3.util.SystemUiController;
|
||||||
import com.android.launcher3.util.Themes;
|
import com.android.launcher3.util.Themes;
|
||||||
import com.android.launcher3.util.Thunk;
|
import com.android.launcher3.util.Thunk;
|
||||||
import com.android.launcher3.util.TraceHelper;
|
import com.android.launcher3.util.TraceHelper;
|
||||||
import com.android.launcher3.util.UiThreadHelper;
|
import com.android.launcher3.util.UiThreadHelper;
|
||||||
import com.android.launcher3.util.ViewOnDrawExecutor;
|
import com.android.launcher3.util.ViewOnDrawExecutor;
|
||||||
|
import com.android.launcher3.widget.LauncherAppWidgetHostView;
|
||||||
import com.android.launcher3.widget.PendingAddShortcutInfo;
|
import com.android.launcher3.widget.PendingAddShortcutInfo;
|
||||||
import com.android.launcher3.widget.PendingAddWidgetInfo;
|
import com.android.launcher3.widget.PendingAddWidgetInfo;
|
||||||
|
import com.android.launcher3.widget.PendingAppWidgetHostView;
|
||||||
import com.android.launcher3.widget.WidgetAddFlowHandler;
|
import com.android.launcher3.widget.WidgetAddFlowHandler;
|
||||||
import com.android.launcher3.widget.WidgetHostViewLoader;
|
import com.android.launcher3.widget.WidgetHostViewLoader;
|
||||||
import com.android.launcher3.widget.WidgetListRowEntry;
|
import com.android.launcher3.widget.WidgetListRowEntry;
|
||||||
|
@ -237,9 +236,7 @@ public class Launcher extends BaseActivity
|
||||||
@Thunk boolean mWorkspaceLoading = true;
|
@Thunk boolean mWorkspaceLoading = true;
|
||||||
|
|
||||||
private boolean mPaused = true;
|
private boolean mPaused = true;
|
||||||
private boolean mOnResumeNeedsLoad;
|
|
||||||
|
|
||||||
private final ArrayList<Runnable> mBindOnResumeCallbacks = new ArrayList<>();
|
|
||||||
private OnResumeCallback mOnResumeCallback;
|
private OnResumeCallback mOnResumeCallback;
|
||||||
|
|
||||||
private ViewOnDrawExecutor mPendingExecutor;
|
private ViewOnDrawExecutor mPendingExecutor;
|
||||||
|
@ -811,20 +808,6 @@ public class Launcher extends BaseActivity
|
||||||
mAppLaunchSuccess = false;
|
mAppLaunchSuccess = false;
|
||||||
getUserEventDispatcher().resetElapsedSessionMillis();
|
getUserEventDispatcher().resetElapsedSessionMillis();
|
||||||
mPaused = false;
|
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);
|
setOnResumeCallback(null);
|
||||||
// Process any items that were added while Launcher was away.
|
// Process any items that were added while Launcher was away.
|
||||||
InstallShortcutReceiver.disableAndFlushInstallQueue(
|
InstallShortcutReceiver.disableAndFlushInstallQueue(
|
||||||
|
@ -1161,20 +1144,12 @@ public class Launcher extends BaseActivity
|
||||||
};
|
};
|
||||||
|
|
||||||
public void updateIconBadges(final Set<PackageUserKey> updatedBadges) {
|
public void updateIconBadges(final Set<PackageUserKey> updatedBadges) {
|
||||||
Runnable r = new Runnable() {
|
mWorkspace.updateIconBadges(updatedBadges);
|
||||||
@Override
|
mAppsView.updateIconBadges(updatedBadges);
|
||||||
public void run() {
|
|
||||||
mWorkspace.updateIconBadges(updatedBadges);
|
|
||||||
mAppsView.updateIconBadges(updatedBadges);
|
|
||||||
|
|
||||||
PopupContainerWithArrow popup = PopupContainerWithArrow.getOpen(Launcher.this);
|
PopupContainerWithArrow popup = PopupContainerWithArrow.getOpen(Launcher.this);
|
||||||
if (popup != null) {
|
if (popup != null) {
|
||||||
popup.updateNotificationHeader(updatedBadges);
|
popup.updateNotificationHeader(updatedBadges);
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
if (!waitUntilResume(r)) {
|
|
||||||
r.run();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2156,33 +2131,6 @@ public class Launcher extends BaseActivity
|
||||||
return result;
|
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) {
|
public void setOnResumeCallback(OnResumeCallback callback) {
|
||||||
if (mOnResumeCallback != null) {
|
if (mOnResumeCallback != null) {
|
||||||
mOnResumeCallback.onLauncherResume();
|
mOnResumeCallback.onLauncherResume();
|
||||||
|
@ -2190,31 +2138,6 @@ public class Launcher extends BaseActivity
|
||||||
mOnResumeCallback = callback;
|
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.
|
* Implementation of the method from LauncherModel.Callbacks.
|
||||||
*/
|
*/
|
||||||
|
@ -2233,7 +2156,6 @@ public class Launcher extends BaseActivity
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void clearPendingBinds() {
|
public void clearPendingBinds() {
|
||||||
mBindOnResumeCallbacks.clear();
|
|
||||||
if (mPendingExecutor != null) {
|
if (mPendingExecutor != null) {
|
||||||
mPendingExecutor.markCompleted();
|
mPendingExecutor.markCompleted();
|
||||||
mPendingExecutor = null;
|
mPendingExecutor = null;
|
||||||
|
@ -2297,18 +2219,8 @@ public class Launcher extends BaseActivity
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void bindAppsAdded(final ArrayList<Long> newScreens,
|
public void bindAppsAdded(ArrayList<Long> newScreens, ArrayList<ItemInfo> addNotAnimated,
|
||||||
final ArrayList<ItemInfo> addNotAnimated,
|
ArrayList<ItemInfo> addAnimated) {
|
||||||
final ArrayList<ItemInfo> addAnimated) {
|
|
||||||
Runnable r = new Runnable() {
|
|
||||||
public void run() {
|
|
||||||
bindAppsAdded(newScreens, addNotAnimated, addAnimated);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
if (waitUntilResume(r)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Add the new screens
|
// Add the new screens
|
||||||
if (newScreens != null) {
|
if (newScreens != null) {
|
||||||
bindAddScreens(newScreens);
|
bindAddScreens(newScreens);
|
||||||
|
@ -2334,15 +2246,6 @@ public class Launcher extends BaseActivity
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void bindItems(final List<ItemInfo> items, final boolean forceAnimateIcons) {
|
public void bindItems(final List<ItemInfo> 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
|
// Get the list of added items and intersect them with the set of items here
|
||||||
final AnimatorSet anim = LauncherAnimUtils.createAnimatorSet();
|
final AnimatorSet anim = LauncherAnimUtils.createAnimatorSet();
|
||||||
final Collection<Animator> bounceAnims = new ArrayList<>();
|
final Collection<Animator> bounceAnims = new ArrayList<>();
|
||||||
|
@ -2585,7 +2488,7 @@ public class Launcher extends BaseActivity
|
||||||
}
|
}
|
||||||
|
|
||||||
if (((PendingAppWidgetHostView) view).isReinflateIfNeeded()) {
|
if (((PendingAppWidgetHostView) view).isReinflateIfNeeded()) {
|
||||||
view.reinflate();
|
view.reInflate();
|
||||||
}
|
}
|
||||||
|
|
||||||
getModelWriter().updateItemInDatabase(info);
|
getModelWriter().updateItemInDatabase(info);
|
||||||
|
@ -2613,27 +2516,11 @@ public class Launcher extends BaseActivity
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void finishFirstPageBind(final ViewOnDrawExecutor executor) {
|
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) {
|
if (mDragLayer.getAlpha() < 1) {
|
||||||
mDragLayer.animate().alpha(1).withEndAction(onComplete).start();
|
mDragLayer.animate().alpha(1).withEndAction(
|
||||||
} else {
|
executor == null ? null : executor::onLoadAnimationCompleted).start();
|
||||||
onComplete.run();
|
} else if (executor != null) {
|
||||||
|
executor.onLoadAnimationCompleted();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2643,10 +2530,6 @@ public class Launcher extends BaseActivity
|
||||||
* Implementation of the method from LauncherModel.Callbacks.
|
* Implementation of the method from LauncherModel.Callbacks.
|
||||||
*/
|
*/
|
||||||
public void finishBindingItems() {
|
public void finishBindingItems() {
|
||||||
Runnable r = this::finishBindingItems;
|
|
||||||
if (waitUntilResume(r)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
TraceHelper.beginSection("finishBindingItems");
|
TraceHelper.beginSection("finishBindingItems");
|
||||||
mWorkspace.restoreInstanceStateForRemainingPages();
|
mWorkspace.restoreInstanceStateForRemainingPages();
|
||||||
|
|
||||||
|
@ -2687,21 +2570,12 @@ public class Launcher extends BaseActivity
|
||||||
*
|
*
|
||||||
* Implementation of the method from LauncherModel.Callbacks.
|
* Implementation of the method from LauncherModel.Callbacks.
|
||||||
*/
|
*/
|
||||||
public void bindAllApplications(final ArrayList<AppInfo> apps) {
|
public void bindAllApplications(ArrayList<AppInfo> apps) {
|
||||||
Runnable r = new RunnableWithId(RUNNABLE_ID_BIND_APPS) {
|
|
||||||
public void run() {
|
|
||||||
bindAllApplications(apps);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
if (waitUntilResume(r)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (mAppsView != null) {
|
if (mAppsView != null) {
|
||||||
Executor pendingExecutor = getPendingExecutor();
|
Executor pendingExecutor = getPendingExecutor();
|
||||||
if (pendingExecutor != null && !isInState(ALL_APPS)) {
|
if (pendingExecutor != null && !isInState(ALL_APPS)) {
|
||||||
// Wait until the fade in animation has finished before setting all apps list.
|
// Wait until the fade in animation has finished before setting all apps list.
|
||||||
pendingExecutor.execute(r);
|
pendingExecutor.execute(() -> bindAllApplications(apps));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2734,47 +2608,22 @@ public class Launcher extends BaseActivity
|
||||||
*
|
*
|
||||||
* Implementation of the method from LauncherModel.Callbacks.
|
* Implementation of the method from LauncherModel.Callbacks.
|
||||||
*/
|
*/
|
||||||
public void bindAppsAddedOrUpdated(final ArrayList<AppInfo> apps) {
|
@Override
|
||||||
Runnable r = new Runnable() {
|
public void bindAppsAddedOrUpdated(ArrayList<AppInfo> apps) {
|
||||||
public void run() {
|
|
||||||
bindAppsAddedOrUpdated(apps);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
if (waitUntilResume(r)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (mAppsView != null) {
|
if (mAppsView != null) {
|
||||||
mAppsView.addOrUpdateApps(apps);
|
mAppsView.addOrUpdateApps(apps);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void bindPromiseAppProgressUpdated(final PromiseAppInfo app) {
|
public void bindPromiseAppProgressUpdated(PromiseAppInfo app) {
|
||||||
Runnable r = new Runnable() {
|
|
||||||
public void run() {
|
|
||||||
bindPromiseAppProgressUpdated(app);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
if (waitUntilResume(r)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (mAppsView != null) {
|
if (mAppsView != null) {
|
||||||
mAppsView.updatePromiseAppProgress(app);
|
mAppsView.updatePromiseAppProgress(app);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void bindWidgetsRestored(final ArrayList<LauncherAppWidgetInfo> widgets) {
|
public void bindWidgetsRestored(ArrayList<LauncherAppWidgetInfo> widgets) {
|
||||||
Runnable r = new Runnable() {
|
|
||||||
public void run() {
|
|
||||||
bindWidgetsRestored(widgets);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
if (waitUntilResume(r)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
mWorkspace.widgetsRestored(widgets);
|
mWorkspace.widgetsRestored(widgets);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2785,16 +2634,7 @@ public class Launcher extends BaseActivity
|
||||||
* @param updated list of shortcuts which have changed.
|
* @param updated list of shortcuts which have changed.
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void bindShortcutsChanged(final ArrayList<ShortcutInfo> updated, final UserHandle user) {
|
public void bindShortcutsChanged(ArrayList<ShortcutInfo> updated, final UserHandle user) {
|
||||||
Runnable r = new Runnable() {
|
|
||||||
public void run() {
|
|
||||||
bindShortcutsChanged(updated, user);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
if (waitUntilResume(r)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!updated.isEmpty()) {
|
if (!updated.isEmpty()) {
|
||||||
mWorkspace.updateShortcuts(updated);
|
mWorkspace.updateShortcuts(updated);
|
||||||
}
|
}
|
||||||
|
@ -2806,16 +2646,7 @@ public class Launcher extends BaseActivity
|
||||||
* Implementation of the method from LauncherModel.Callbacks.
|
* Implementation of the method from LauncherModel.Callbacks.
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void bindRestoreItemsChange(final HashSet<ItemInfo> updates) {
|
public void bindRestoreItemsChange(HashSet<ItemInfo> updates) {
|
||||||
Runnable r = new Runnable() {
|
|
||||||
public void run() {
|
|
||||||
bindRestoreItemsChange(updates);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
if (waitUntilResume(r)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
mWorkspace.updateRestoreItems(updates);
|
mWorkspace.updateRestoreItems(updates);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2828,29 +2659,12 @@ public class Launcher extends BaseActivity
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void bindWorkspaceComponentsRemoved(final ItemInfoMatcher matcher) {
|
public void bindWorkspaceComponentsRemoved(final ItemInfoMatcher matcher) {
|
||||||
Runnable r = new Runnable() {
|
|
||||||
public void run() {
|
|
||||||
bindWorkspaceComponentsRemoved(matcher);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
if (waitUntilResume(r)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
mWorkspace.removeItemsByMatcher(matcher);
|
mWorkspace.removeItemsByMatcher(matcher);
|
||||||
mDragController.onAppsRemoved(matcher);
|
mDragController.onAppsRemoved(matcher);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void bindAppInfosRemoved(final ArrayList<AppInfo> appInfos) {
|
public void bindAppInfosRemoved(final ArrayList<AppInfo> appInfos) {
|
||||||
Runnable r = new Runnable() {
|
|
||||||
public void run() {
|
|
||||||
bindAppInfosRemoved(appInfos);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
if (waitUntilResume(r)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Update AllApps
|
// Update AllApps
|
||||||
if (mAppsView != null) {
|
if (mAppsView != null) {
|
||||||
mAppsView.removeApps(appInfos);
|
mAppsView.removeApps(appInfos);
|
||||||
|
@ -2860,16 +2674,6 @@ public class Launcher extends BaseActivity
|
||||||
@Override
|
@Override
|
||||||
public void bindAllWidgets(final ArrayList<WidgetListRowEntry> allWidgets) {
|
public void bindAllWidgets(final ArrayList<WidgetListRowEntry> allWidgets) {
|
||||||
mPopupDataProvider.setAllWidgets(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);
|
AbstractFloatingView topView = AbstractFloatingView.getTopOpenView(this);
|
||||||
if (topView != null) {
|
if (topView != null) {
|
||||||
topView.onWidgetsBound();
|
topView.onWidgetsBound();
|
||||||
|
|
|
@ -27,6 +27,7 @@ import android.util.Log;
|
||||||
import com.android.launcher3.compat.LauncherAppsCompat;
|
import com.android.launcher3.compat.LauncherAppsCompat;
|
||||||
import com.android.launcher3.compat.PackageInstallerCompat;
|
import com.android.launcher3.compat.PackageInstallerCompat;
|
||||||
import com.android.launcher3.compat.UserManagerCompat;
|
import com.android.launcher3.compat.UserManagerCompat;
|
||||||
|
import com.android.launcher3.config.FeatureFlags;
|
||||||
import com.android.launcher3.notification.NotificationListener;
|
import com.android.launcher3.notification.NotificationListener;
|
||||||
import com.android.launcher3.util.ConfigMonitor;
|
import com.android.launcher3.util.ConfigMonitor;
|
||||||
import com.android.launcher3.util.Preconditions;
|
import com.android.launcher3.util.Preconditions;
|
||||||
|
@ -39,6 +40,8 @@ import static com.android.launcher3.SettingsActivity.NOTIFICATION_BADGING;
|
||||||
|
|
||||||
public class LauncherAppState {
|
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.
|
// We do not need any synchronization for this variable as its only written on UI thread.
|
||||||
private static LauncherAppState INSTANCE;
|
private static LauncherAppState INSTANCE;
|
||||||
|
|
||||||
|
@ -103,6 +106,10 @@ public class LauncherAppState {
|
||||||
filter.addAction(Intent.ACTION_MANAGED_PROFILE_UNAVAILABLE);
|
filter.addAction(Intent.ACTION_MANAGED_PROFILE_UNAVAILABLE);
|
||||||
filter.addAction(Intent.ACTION_MANAGED_PROFILE_UNLOCKED);
|
filter.addAction(Intent.ACTION_MANAGED_PROFILE_UNLOCKED);
|
||||||
|
|
||||||
|
if (FeatureFlags.IS_DOGFOOD_BUILD) {
|
||||||
|
filter.addAction(ACTION_FORCE_ROLOAD);
|
||||||
|
}
|
||||||
|
|
||||||
mContext.registerReceiver(mModel, filter);
|
mContext.registerReceiver(mModel, filter);
|
||||||
UserManagerCompat.getInstance(mContext).enableAndResetCache();
|
UserManagerCompat.getInstance(mContext).enableAndResetCache();
|
||||||
new ConfigMonitor(mContext).register();
|
new ConfigMonitor(mContext).register();
|
||||||
|
|
|
@ -26,11 +26,14 @@ import android.content.ActivityNotFoundException;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.os.Handler;
|
import android.os.Handler;
|
||||||
|
import android.util.Log;
|
||||||
import android.util.SparseArray;
|
import android.util.SparseArray;
|
||||||
import android.view.LayoutInflater;
|
import android.view.LayoutInflater;
|
||||||
import android.widget.Toast;
|
import android.widget.Toast;
|
||||||
|
|
||||||
import com.android.launcher3.config.FeatureFlags;
|
import com.android.launcher3.config.FeatureFlags;
|
||||||
|
import com.android.launcher3.widget.DeferredAppWidgetHostView;
|
||||||
|
import com.android.launcher3.widget.LauncherAppWidgetHostView;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
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
|
// have been established by this point, and we will end up populating the
|
||||||
// widgets upon bind anyway. See issue 14255011 for more context.
|
// 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
|
@Override
|
||||||
|
@ -178,6 +189,11 @@ public class LauncherAppWidgetHost extends AppWidgetHost {
|
||||||
inflater.inflate(appWidget.initialLayout, lahv);
|
inflater.inflate(appWidget.initialLayout, lahv);
|
||||||
lahv.setAppWidget(0, appWidget);
|
lahv.setAppWidget(0, appWidget);
|
||||||
return lahv;
|
return lahv;
|
||||||
|
} else if ((mFlags & FLAG_LISTENING) == 0) {
|
||||||
|
DeferredAppWidgetHostView view = new DeferredAppWidgetHostView(context);
|
||||||
|
view.setAppWidget(appWidgetId, appWidget);
|
||||||
|
mViews.put(appWidgetId, view);
|
||||||
|
return view;
|
||||||
} else {
|
} else {
|
||||||
try {
|
try {
|
||||||
return super.createView(context, appWidgetId, appWidget);
|
return super.createView(context, appWidgetId, appWidget);
|
||||||
|
|
|
@ -16,6 +16,9 @@
|
||||||
|
|
||||||
package com.android.launcher3;
|
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.BroadcastReceiver;
|
||||||
import android.content.ComponentName;
|
import android.content.ComponentName;
|
||||||
import android.content.ContentProviderOperation;
|
import android.content.ContentProviderOperation;
|
||||||
|
@ -37,6 +40,7 @@ import android.util.Pair;
|
||||||
import com.android.launcher3.compat.LauncherAppsCompat;
|
import com.android.launcher3.compat.LauncherAppsCompat;
|
||||||
import com.android.launcher3.compat.PackageInstallerCompat.PackageInstallInfo;
|
import com.android.launcher3.compat.PackageInstallerCompat.PackageInstallInfo;
|
||||||
import com.android.launcher3.compat.UserManagerCompat;
|
import com.android.launcher3.compat.UserManagerCompat;
|
||||||
|
import com.android.launcher3.config.FeatureFlags;
|
||||||
import com.android.launcher3.graphics.LauncherIcons;
|
import com.android.launcher3.graphics.LauncherIcons;
|
||||||
import com.android.launcher3.model.AddWorkspaceItemsTask;
|
import com.android.launcher3.model.AddWorkspaceItemsTask;
|
||||||
import com.android.launcher3.model.BgDataModel;
|
import com.android.launcher3.model.BgDataModel;
|
||||||
|
@ -135,7 +139,6 @@ public class LauncherModel extends BroadcastReceiver
|
||||||
};
|
};
|
||||||
|
|
||||||
public interface Callbacks {
|
public interface Callbacks {
|
||||||
public boolean setLoadOnResume();
|
|
||||||
public int getCurrentWorkspaceScreen();
|
public int getCurrentWorkspaceScreen();
|
||||||
public void clearPendingBinds();
|
public void clearPendingBinds();
|
||||||
public void startBinding();
|
public void startBinding();
|
||||||
|
@ -405,6 +408,8 @@ public class LauncherModel extends BroadcastReceiver
|
||||||
enqueueModelUpdateTask(new UserLockStateChangedTask(user));
|
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;
|
mModelLoaded = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Do this here because if the launcher activity is running it will be restarted.
|
// Start the loader if launcher is already running, otherwise the loader will run,
|
||||||
// If it's not running startLoaderFromBackground will merely tell it that it needs
|
// the next time launcher starts
|
||||||
// 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() {
|
|
||||||
Callbacks callbacks = getCallback();
|
Callbacks callbacks = getCallback();
|
||||||
if (callbacks != null) {
|
if (callbacks != null) {
|
||||||
// Only actually run the loader if they're not paused.
|
startLoader(callbacks.getCurrentWorkspaceScreen());
|
||||||
if (!callbacks.setLoadOnResume()) {
|
|
||||||
startLoader(callbacks.getCurrentWorkspaceScreen());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -23,6 +23,7 @@ import android.view.View;
|
||||||
import android.view.ViewGroup;
|
import android.view.ViewGroup;
|
||||||
|
|
||||||
import com.android.launcher3.CellLayout.ContainerType;
|
import com.android.launcher3.CellLayout.ContainerType;
|
||||||
|
import com.android.launcher3.widget.LauncherAppWidgetHostView;
|
||||||
|
|
||||||
public class ShortcutAndWidgetContainer extends ViewGroup {
|
public class ShortcutAndWidgetContainer extends ViewGroup {
|
||||||
static final String TAG = "ShortcutAndWidgetContainer";
|
static final String TAG = "ShortcutAndWidgetContainer";
|
||||||
|
|
|
@ -88,8 +88,10 @@ import com.android.launcher3.util.LongArrayMap;
|
||||||
import com.android.launcher3.util.PackageUserKey;
|
import com.android.launcher3.util.PackageUserKey;
|
||||||
import com.android.launcher3.util.Thunk;
|
import com.android.launcher3.util.Thunk;
|
||||||
import com.android.launcher3.util.WallpaperOffsetInterpolator;
|
import com.android.launcher3.util.WallpaperOffsetInterpolator;
|
||||||
|
import com.android.launcher3.widget.LauncherAppWidgetHostView;
|
||||||
import com.android.launcher3.widget.PendingAddShortcutInfo;
|
import com.android.launcher3.widget.PendingAddShortcutInfo;
|
||||||
import com.android.launcher3.widget.PendingAddWidgetInfo;
|
import com.android.launcher3.widget.PendingAddWidgetInfo;
|
||||||
|
import com.android.launcher3.widget.PendingAppWidgetHostView;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
|
@ -3510,7 +3512,7 @@ public class Workspace extends PagedView
|
||||||
return false;
|
return false;
|
||||||
});
|
});
|
||||||
for (PendingAppWidgetHostView view : views) {
|
for (PendingAppWidgetHostView view : views) {
|
||||||
view.reinflate();
|
view.reInflate();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -21,20 +21,17 @@ import com.android.launcher3.AppWidgetResizeFrame;
|
||||||
import com.android.launcher3.BubbleTextView;
|
import com.android.launcher3.BubbleTextView;
|
||||||
import com.android.launcher3.ButtonDropTarget;
|
import com.android.launcher3.ButtonDropTarget;
|
||||||
import com.android.launcher3.CellLayout;
|
import com.android.launcher3.CellLayout;
|
||||||
import com.android.launcher3.DeleteDropTarget;
|
|
||||||
import com.android.launcher3.DropTarget.DragObject;
|
import com.android.launcher3.DropTarget.DragObject;
|
||||||
import com.android.launcher3.FolderInfo;
|
import com.android.launcher3.FolderInfo;
|
||||||
import com.android.launcher3.InfoDropTarget;
|
|
||||||
import com.android.launcher3.ItemInfo;
|
import com.android.launcher3.ItemInfo;
|
||||||
import com.android.launcher3.Launcher;
|
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.LauncherAppWidgetInfo;
|
||||||
import com.android.launcher3.LauncherSettings;
|
import com.android.launcher3.LauncherSettings;
|
||||||
import com.android.launcher3.LauncherSettings.Favorites;
|
import com.android.launcher3.LauncherSettings.Favorites;
|
||||||
import com.android.launcher3.PendingAddItemInfo;
|
import com.android.launcher3.PendingAddItemInfo;
|
||||||
import com.android.launcher3.R;
|
import com.android.launcher3.R;
|
||||||
import com.android.launcher3.ShortcutInfo;
|
import com.android.launcher3.ShortcutInfo;
|
||||||
import com.android.launcher3.UninstallDropTarget;
|
|
||||||
import com.android.launcher3.Workspace;
|
import com.android.launcher3.Workspace;
|
||||||
import com.android.launcher3.dragndrop.DragController.DragListener;
|
import com.android.launcher3.dragndrop.DragController.DragListener;
|
||||||
import com.android.launcher3.dragndrop.DragOptions;
|
import com.android.launcher3.dragndrop.DragOptions;
|
||||||
|
|
|
@ -31,7 +31,7 @@ import android.view.View;
|
||||||
|
|
||||||
import com.android.launcher3.BubbleTextView;
|
import com.android.launcher3.BubbleTextView;
|
||||||
import com.android.launcher3.Launcher;
|
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.R;
|
||||||
import com.android.launcher3.config.FeatureFlags;
|
import com.android.launcher3.config.FeatureFlags;
|
||||||
import com.android.launcher3.folder.FolderIcon;
|
import com.android.launcher3.folder.FolderIcon;
|
||||||
|
|
|
@ -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;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -14,7 +14,7 @@
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package com.android.launcher3;
|
package com.android.launcher3.widget;
|
||||||
|
|
||||||
import android.appwidget.AppWidgetHostView;
|
import android.appwidget.AppWidgetHostView;
|
||||||
import android.appwidget.AppWidgetProviderInfo;
|
import android.appwidget.AppWidgetProviderInfo;
|
||||||
|
@ -37,6 +37,15 @@ import android.widget.AdapterView;
|
||||||
import android.widget.Advanceable;
|
import android.widget.Advanceable;
|
||||||
import android.widget.RemoteViews;
|
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;
|
||||||
import com.android.launcher3.dragndrop.DragLayer.TouchCompleteListener;
|
import com.android.launcher3.dragndrop.DragLayer.TouchCompleteListener;
|
||||||
|
|
||||||
|
@ -59,14 +68,10 @@ public class LauncherAppWidgetHostView extends AppWidgetHostView
|
||||||
|
|
||||||
private final CheckLongPressHelper mLongPressHelper;
|
private final CheckLongPressHelper mLongPressHelper;
|
||||||
private final StylusEventHelper mStylusEventHelper;
|
private final StylusEventHelper mStylusEventHelper;
|
||||||
private final Launcher mLauncher;
|
protected 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;
|
|
||||||
|
|
||||||
@ViewDebug.ExportedProperty(category = "launcher")
|
@ViewDebug.ExportedProperty(category = "launcher")
|
||||||
private int mReinflateStatus;
|
private boolean mReinflateOnConfigChange;
|
||||||
|
|
||||||
private float mSlop;
|
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
|
// 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
|
// (framework issue). On resuming, we ensure that any widgets are inflated for the current
|
||||||
// orientation.
|
// orientation.
|
||||||
if (mReinflateStatus == DONT_REINFLATE && !isSameOrientation()) {
|
mReinflateOnConfigChange = !isSameOrientation();
|
||||||
mReinflateStatus = REINFLATE_ON_RESUME;
|
|
||||||
if (!mLauncher.waitUntilResume(new ReInflateRunnable())) {
|
|
||||||
mReinflateStatus = REINFLATE_ON_CONFIG_CHANGE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean isSameOrientation() {
|
private boolean isSameOrientation() {
|
||||||
|
@ -485,40 +485,20 @@ public class LauncherAppWidgetHostView extends AppWidgetHostView
|
||||||
protected void onConfigurationChanged(Configuration newConfig) {
|
protected void onConfigurationChanged(Configuration newConfig) {
|
||||||
super.onConfigurationChanged(newConfig);
|
super.onConfigurationChanged(newConfig);
|
||||||
|
|
||||||
if (mReinflateStatus == REINFLATE_ON_CONFIG_CHANGE) {
|
// Only reinflate when the final configuration is same as the required configuration
|
||||||
// We are finally in the same orientation
|
if (mReinflateOnConfigChange && isSameOrientation()) {
|
||||||
reinflateIfNecessary();
|
mReinflateOnConfigChange = false;
|
||||||
|
if (isAttachedToWindow()) {
|
||||||
|
reInflate();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void reinflateIfNecessary() {
|
public void reInflate() {
|
||||||
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() {
|
|
||||||
LauncherAppWidgetInfo info = (LauncherAppWidgetInfo) getTag();
|
LauncherAppWidgetInfo info = (LauncherAppWidgetInfo) getTag();
|
||||||
// Remove and rebind the current widget (which was inflated in the wrong
|
// Remove and rebind the current widget (which was inflated in the wrong
|
||||||
// orientation), but don't delete it from the database
|
// orientation), but don't delete it from the database
|
||||||
mLauncher.removeItem(this, info, false /* deleteFromDb */);
|
mLauncher.removeItem(this, info, false /* deleteFromDb */);
|
||||||
mLauncher.bindAppWidget(info);
|
mLauncher.bindAppWidget(info);
|
||||||
}
|
}
|
||||||
|
|
||||||
private class ReInflateRunnable implements Runnable {
|
|
||||||
@Override
|
|
||||||
public void run() {
|
|
||||||
if (mReinflateStatus == REINFLATE_ON_RESUME) {
|
|
||||||
reinflateIfNecessary();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
|
@ -14,7 +14,7 @@
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package com.android.launcher3;
|
package com.android.launcher3.widget;
|
||||||
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.graphics.Bitmap;
|
import android.graphics.Bitmap;
|
||||||
|
@ -32,10 +32,19 @@ import android.view.ContextThemeWrapper;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.view.View.OnClickListener;
|
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.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.graphics.DrawableFactory;
|
||||||
import com.android.launcher3.model.PackageItemInfo;
|
import com.android.launcher3.model.PackageItemInfo;
|
||||||
import com.android.launcher3.util.Themes;
|
import com.android.launcher3.util.Themes;
|
||||||
|
import com.android.launcher3.widget.LauncherAppWidgetHostView;
|
||||||
|
|
||||||
public class PendingAppWidgetHostView extends LauncherAppWidgetHostView
|
public class PendingAppWidgetHostView extends LauncherAppWidgetHostView
|
||||||
implements OnClickListener, ItemInfoUpdateReceiver {
|
implements OnClickListener, ItemInfoUpdateReceiver {
|
||||||
|
@ -48,7 +57,6 @@ public class PendingAppWidgetHostView extends LauncherAppWidgetHostView
|
||||||
private final LauncherAppWidgetInfo mInfo;
|
private final LauncherAppWidgetInfo mInfo;
|
||||||
private final int mStartState;
|
private final int mStartState;
|
||||||
private final boolean mDisabledForSafeMode;
|
private final boolean mDisabledForSafeMode;
|
||||||
private Launcher mLauncher;
|
|
||||||
|
|
||||||
private Bitmap mIcon;
|
private Bitmap mIcon;
|
||||||
|
|
||||||
|
@ -64,7 +72,6 @@ public class PendingAppWidgetHostView extends LauncherAppWidgetHostView
|
||||||
IconCache cache, boolean disabledForSafeMode) {
|
IconCache cache, boolean disabledForSafeMode) {
|
||||||
super(new ContextThemeWrapper(context, R.style.WidgetContainerTheme));
|
super(new ContextThemeWrapper(context, R.style.WidgetContainerTheme));
|
||||||
|
|
||||||
mLauncher = Launcher.getLauncher(context);
|
|
||||||
mInfo = info;
|
mInfo = info;
|
||||||
mStartState = info.restoreStatus;
|
mStartState = info.restoreStatus;
|
||||||
mDisabledForSafeMode = disabledForSafeMode;
|
mDisabledForSafeMode = disabledForSafeMode;
|
|
@ -30,12 +30,12 @@ import android.support.test.runner.AndroidJUnit4;
|
||||||
import android.support.test.uiautomator.UiSelector;
|
import android.support.test.uiautomator.UiSelector;
|
||||||
|
|
||||||
import com.android.launcher3.LauncherAppWidgetHost;
|
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.LauncherAppWidgetInfo;
|
||||||
import com.android.launcher3.LauncherAppWidgetProviderInfo;
|
import com.android.launcher3.LauncherAppWidgetProviderInfo;
|
||||||
import com.android.launcher3.LauncherModel;
|
import com.android.launcher3.LauncherModel;
|
||||||
import com.android.launcher3.LauncherSettings;
|
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.Workspace;
|
||||||
import com.android.launcher3.compat.AppWidgetManagerCompat;
|
import com.android.launcher3.compat.AppWidgetManagerCompat;
|
||||||
import com.android.launcher3.compat.PackageInstallerCompat;
|
import com.android.launcher3.compat.PackageInstallerCompat;
|
||||||
|
|
Loading…
Reference in New Issue