Merge "Fix crash when launcher dies while configuring a widget / shortcut" into ub-now-nova

This commit is contained in:
Adam Cohen
2014-05-20 22:26:49 +00:00
committed by Android (Google) Code Review
2 changed files with 99 additions and 48 deletions
+95 -48
View File
@@ -360,8 +360,7 @@ public class Launcher extends Activity
}
};
private static ArrayList<PendingAddArguments> sPendingAddList
= new ArrayList<PendingAddArguments>();
private static PendingAddArguments sPendingAddItem;
public static boolean sForceEnableRotation = isPropertyEnabled(FORCE_ENABLE_ROTATION_PROPERTY);
@@ -372,6 +371,7 @@ public class Launcher extends Activity
long screenId;
int cellX;
int cellY;
int appWidgetId;
}
private Stats mStats;
@@ -736,28 +736,23 @@ public class Launcher extends Activity
* Returns whether we should delay spring loaded mode -- for shortcuts and widgets that have
* a configuration step, this allows the proper animations to run after other transitions.
*/
private boolean completeAdd(PendingAddArguments args) {
boolean result = false;
private long completeAdd(PendingAddArguments args) {
long screenId = ensurePendingDropLayoutExists(args.screenId);
switch (args.requestCode) {
case REQUEST_PICK_SHORTCUT:
processShortcut(args.intent);
break;
case REQUEST_CREATE_SHORTCUT:
completeAddShortcut(args.intent, args.container, args.screenId, args.cellX,
completeAddShortcut(args.intent, args.container, screenId, args.cellX,
args.cellY);
result = true;
break;
case REQUEST_CREATE_APPWIDGET:
int appWidgetId = args.intent.getIntExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, -1);
completeAddAppWidget(appWidgetId, args.container, args.screenId, null, null);
result = true;
completeAddAppWidget(args.appWidgetId, args.container, screenId, null, null);
break;
}
// Before adding this resetAddInfo(), after a shortcut was added to a workspace screen,
// if you turned the screen off and then back while in All Apps, Launcher would not
// return to the workspace. Clearing mAddInfo.container here fixes this issue
resetAddInfo();
return result;
return screenId;
}
@Override
@@ -765,7 +760,7 @@ public class Launcher extends Activity
final int requestCode, final int resultCode, final Intent data) {
// Reset the startActivity waiting flag
setWaitingForResult(false);
int pendingAddWidgetId = mPendingAddWidgetId;
final int pendingAddWidgetId = mPendingAddWidgetId;
mPendingAddWidgetId = -1;
Runnable exitSpringLoaded = new Runnable() {
@@ -798,6 +793,7 @@ public class Launcher extends Activity
boolean isWidgetDrop = (requestCode == REQUEST_PICK_APPWIDGET ||
requestCode == REQUEST_CREATE_APPWIDGET);
final boolean workspaceLocked = isWorkspaceLocked();
// We have special handling for widgets
if (isWidgetDrop) {
final int appWidgetId;
@@ -810,33 +806,46 @@ public class Launcher extends Activity
}
final int result;
final Runnable onComplete;
if (appWidgetId < 0 || resultCode == RESULT_CANCELED) {
Log.e(TAG, "Error: appWidgetId (EXTRA_APPWIDGET_ID) was not returned from the \\" +
"widget configuration activity.");
Log.e(TAG, "Error: appWidgetId (EXTRA_APPWIDGET_ID) was not " +
"returned from the widget configuration activity.");
result = RESULT_CANCELED;
completeTwoStageWidgetDrop(result, appWidgetId);
onComplete = new Runnable() {
final Runnable onComplete = new Runnable() {
@Override
public void run() {
exitSpringLoadedDragModeDelayed(false, 0, null);
}
};
if (workspaceLocked) {
// No need to remove the empty screen if we're mid-binding, as the
// the bind will not add the empty screen.
mWorkspace.postDelayed(onComplete, ON_ACTIVITY_RESULT_ANIMATION_DELAY);
} else {
mWorkspace.removeExtraEmptyScreenDelayed(true, onComplete,
ON_ACTIVITY_RESULT_ANIMATION_DELAY, false);
}
} else {
result = resultCode;
final CellLayout dropLayout =
(CellLayout) mWorkspace.getScreenWithId(mPendingAddInfo.screenId);
dropLayout.setDropPending(true);
onComplete = new Runnable() {
@Override
public void run() {
completeTwoStageWidgetDrop(result, appWidgetId);
dropLayout.setDropPending(false);
}
};
if (!workspaceLocked) {
mPendingAddInfo.screenId = ensurePendingDropLayoutExists(mPendingAddInfo.screenId);
final CellLayout dropLayout = mWorkspace.getScreenWithId(mPendingAddInfo.screenId);
dropLayout.setDropPending(true);
final Runnable onComplete = new Runnable() {
@Override
public void run() {
completeTwoStageWidgetDrop(resultCode, appWidgetId);
dropLayout.setDropPending(false);
}
};
mWorkspace.removeExtraEmptyScreenDelayed(true, onComplete,
ON_ACTIVITY_RESULT_ANIMATION_DELAY, false);
} else {
PendingAddArguments args = preparePendingAddArgs(requestCode, data, appWidgetId,
mPendingAddInfo);
sPendingAddItem = args;
}
}
mWorkspace.removeExtraEmptyScreenDelayed(true, onComplete, ON_ACTIVITY_RESULT_ANIMATION_DELAY,
false);
return;
}
@@ -846,20 +855,15 @@ public class Launcher extends Activity
// For example, the user would PICK_SHORTCUT for "Music playlist", and we
// launch over to the Music app to actually CREATE_SHORTCUT.
if (resultCode == RESULT_OK && mPendingAddInfo.container != ItemInfo.NO_ID) {
final PendingAddArguments args = new PendingAddArguments();
args.requestCode = requestCode;
args.intent = data;
args.container = mPendingAddInfo.container;
args.screenId = mPendingAddInfo.screenId;
args.cellX = mPendingAddInfo.cellX;
args.cellY = mPendingAddInfo.cellY;
final PendingAddArguments args = preparePendingAddArgs(requestCode, data, -1,
mPendingAddInfo);
if (isWorkspaceLocked()) {
sPendingAddList.add(args);
sPendingAddItem = args;
} else {
completeAdd(args);
mWorkspace.removeExtraEmptyScreenDelayed(true, exitSpringLoaded,
ON_ACTIVITY_RESULT_ANIMATION_DELAY, false);
}
mWorkspace.removeExtraEmptyScreenDelayed(true, exitSpringLoaded,
ON_ACTIVITY_RESULT_ANIMATION_DELAY, false);
} else if (resultCode == RESULT_CANCELED) {
mWorkspace.removeExtraEmptyScreenDelayed(true, exitSpringLoaded,
ON_ACTIVITY_RESULT_ANIMATION_DELAY, false);
@@ -867,6 +871,38 @@ public class Launcher extends Activity
mDragLayer.clearAnimatedView();
}
private PendingAddArguments preparePendingAddArgs(int requestCode, Intent data, int
appWidgetId, ItemInfo info) {
PendingAddArguments args = new PendingAddArguments();
args.requestCode = requestCode;
args.intent = data;
args.container = info.container;
args.screenId = info.screenId;
args.cellX = info.cellX;
args.cellY = info.cellY;
args.appWidgetId = appWidgetId;
return args;
}
/**
* Check to see if a given screen id exists. If not, create it at the end, return the new id.
*
* @param screenId the screen id to check
* @return the new screen, or screenId if it exists
*/
private long ensurePendingDropLayoutExists(long screenId) {
CellLayout dropLayout =
(CellLayout) mWorkspace.getScreenWithId(screenId);
if (dropLayout == null) {
// it's possible that the add screen was removed because it was
// empty and a re-bind occurred
mWorkspace.addExtraEmptyScreen();
return mWorkspace.commitExtraEmptyScreen();
} else {
return screenId;
}
}
private void completeTwoStageWidgetDrop(final int resultCode, final int appWidgetId) {
CellLayout cellLayout =
(CellLayout) mWorkspace.getScreenWithId(mPendingAddInfo.screenId);
@@ -4169,13 +4205,6 @@ public class Launcher extends Activity
mWorkspace.restoreInstanceStateForRemainingPages();
// If we received the result of any pending adds while the loader was running (e.g. the
// widget configuration forced an orientation change), process them now.
for (int i = 0; i < sPendingAddList.size(); i++) {
completeAdd(sPendingAddList.get(i));
}
sPendingAddList.clear();
// Update the market app icon as necessary (the other icons will be managed in response to
// package changes in bindSearchablesChanged()
if (!DISABLE_MARKET_BUTTON) {
@@ -4183,6 +4212,24 @@ public class Launcher extends Activity
}
setWorkspaceLoading(false);
// If we received the result of any pending adds while the loader was running (e.g. the
// widget configuration forced an orientation change), process them now.
if (sPendingAddItem != null) {
final long screenId = completeAdd(sPendingAddItem);
// TODO: this moves the user to the page where the pending item was added. Ideally,
// the screen would be guaranteed to exist after bind, and the page would be set through
// the workspace restore process.
mWorkspace.post(new Runnable() {
@Override
public void run() {
mWorkspace.snapToScreenId(screenId);
}
});
sPendingAddItem = null;
}
if (upgradePath) {
mWorkspace.getUniqueComponents(true, null);
mIntentsOnWorkspaceFromUpgradePath = mWorkspace.getUniqueComponents(true, null);
+4
View File
@@ -1294,6 +1294,10 @@ public class Workspace extends SmoothPagedView
snapToPage(whichPage, duration);
}
public void snapToScreenId(long screenId) {
snapToScreenId(screenId, null);
}
protected void snapToScreenId(long screenId, Runnable r) {
snapToPage(getPageIndexForScreenId(screenId), r);
}