Merge "Adding support for app widgets in the InstallQueue" into ub-launcher3-master
This commit is contained in:
@@ -16,6 +16,8 @@
|
||||
|
||||
package com.android.launcher3;
|
||||
|
||||
import android.appwidget.AppWidgetManager;
|
||||
import android.appwidget.AppWidgetProviderInfo;
|
||||
import android.content.BroadcastReceiver;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
@@ -67,6 +69,7 @@ public class InstallShortcutReceiver extends BroadcastReceiver {
|
||||
|
||||
private static final String APP_SHORTCUT_TYPE_KEY = "isAppShortcut";
|
||||
private static final String DEEPSHORTCUT_TYPE_KEY = "isDeepShortcut";
|
||||
private static final String APP_WIDGET_TYPE_KEY = "isAppWidget";
|
||||
private static final String USER_HANDLE_KEY = "userHandle";
|
||||
|
||||
// The set of shortcuts that are pending install
|
||||
@@ -200,13 +203,17 @@ public class InstallShortcutReceiver extends BroadcastReceiver {
|
||||
|
||||
public static ShortcutInfo fromShortcutIntent(Context context, Intent data) {
|
||||
PendingInstallShortcutInfo info = createPendingInfo(context, data);
|
||||
return info == null ? null : info.getShortcutInfo();
|
||||
return info == null ? null : (ShortcutInfo) info.getItemInfo();
|
||||
}
|
||||
|
||||
public static void queueShortcut(ShortcutInfoCompat info, Context context) {
|
||||
queuePendingShortcutInfo(new PendingInstallShortcutInfo(info, context), context);
|
||||
}
|
||||
|
||||
public static void queueWidget(AppWidgetProviderInfo info, int widgetId, Context context) {
|
||||
queuePendingShortcutInfo(new PendingInstallShortcutInfo(info, widgetId, context), context);
|
||||
}
|
||||
|
||||
public static HashSet<ShortcutKey> getPendingShortcuts(Context context) {
|
||||
HashSet<ShortcutKey> result = new HashSet<>();
|
||||
|
||||
@@ -276,6 +283,7 @@ public class InstallShortcutReceiver extends BroadcastReceiver {
|
||||
|
||||
final LauncherActivityInfoCompat activityInfo;
|
||||
final ShortcutInfoCompat shortcutInfo;
|
||||
final AppWidgetProviderInfo providerInfo;
|
||||
|
||||
final Intent data;
|
||||
final Context mContext;
|
||||
@@ -287,25 +295,30 @@ public class InstallShortcutReceiver extends BroadcastReceiver {
|
||||
* Initializes a PendingInstallShortcutInfo received from a different app.
|
||||
*/
|
||||
public PendingInstallShortcutInfo(Intent data, UserHandleCompat user, Context context) {
|
||||
activityInfo = null;
|
||||
shortcutInfo = null;
|
||||
providerInfo = null;
|
||||
|
||||
this.data = data;
|
||||
this.user = user;
|
||||
mContext = context;
|
||||
|
||||
launchIntent = data.getParcelableExtra(Intent.EXTRA_SHORTCUT_INTENT);
|
||||
label = data.getStringExtra(Intent.EXTRA_SHORTCUT_NAME);
|
||||
activityInfo = null;
|
||||
shortcutInfo = null;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes a PendingInstallShortcutInfo to represent a launcher target.
|
||||
*/
|
||||
public PendingInstallShortcutInfo(LauncherActivityInfoCompat info, Context context) {
|
||||
this.data = null;
|
||||
mContext = context;
|
||||
activityInfo = info;
|
||||
shortcutInfo = null;
|
||||
providerInfo = null;
|
||||
|
||||
data = null;
|
||||
user = info.getUser();
|
||||
mContext = context;
|
||||
|
||||
launchIntent = AppInfo.makeLaunchIntent(context, info, user);
|
||||
label = info.getLabel().toString();
|
||||
@@ -315,16 +328,36 @@ public class InstallShortcutReceiver extends BroadcastReceiver {
|
||||
* Initializes a PendingInstallShortcutInfo to represent a launcher target.
|
||||
*/
|
||||
public PendingInstallShortcutInfo(ShortcutInfoCompat info, Context context) {
|
||||
this.data = null;
|
||||
shortcutInfo = info;
|
||||
mContext = context;
|
||||
activityInfo = null;
|
||||
shortcutInfo = info;
|
||||
providerInfo = null;
|
||||
|
||||
data = null;
|
||||
mContext = context;
|
||||
user = info.getUserHandle();
|
||||
|
||||
launchIntent = info.makeIntent(context);
|
||||
label = info.getShortLabel().toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes a PendingInstallShortcutInfo to represent a launcher target.
|
||||
*/
|
||||
public PendingInstallShortcutInfo(
|
||||
AppWidgetProviderInfo info, int widgetId, Context context) {
|
||||
activityInfo = null;
|
||||
shortcutInfo = null;
|
||||
providerInfo = info;
|
||||
|
||||
data = null;
|
||||
mContext = context;
|
||||
user = UserHandleCompat.fromUser(info.getProfile());
|
||||
|
||||
launchIntent = new Intent().setComponent(info.provider)
|
||||
.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, widgetId);
|
||||
label = info.label;
|
||||
}
|
||||
|
||||
public String encodeToString() {
|
||||
try {
|
||||
if (activityInfo != null) {
|
||||
@@ -347,6 +380,16 @@ public class InstallShortcutReceiver extends BroadcastReceiver {
|
||||
.key(USER_HANDLE_KEY).value(UserManagerCompat.getInstance(mContext)
|
||||
.getSerialNumberForUser(user))
|
||||
.endObject().toString();
|
||||
} else if (providerInfo != null) {
|
||||
// If it a launcher target, we only need component name, and user to
|
||||
// recreate this.
|
||||
return new JSONStringer()
|
||||
.object()
|
||||
.key(LAUNCH_INTENT_KEY).value(launchIntent.toUri(0))
|
||||
.key(APP_WIDGET_TYPE_KEY).value(true)
|
||||
.key(USER_HANDLE_KEY).value(UserManagerCompat.getInstance(mContext)
|
||||
.getSerialNumberForUser(user))
|
||||
.endObject().toString();
|
||||
}
|
||||
|
||||
if (launchIntent.getAction() == null) {
|
||||
@@ -388,11 +431,24 @@ public class InstallShortcutReceiver extends BroadcastReceiver {
|
||||
}
|
||||
}
|
||||
|
||||
public ShortcutInfo getShortcutInfo() {
|
||||
public ItemInfo getItemInfo() {
|
||||
if (activityInfo != null) {
|
||||
return new ShortcutInfo(activityInfo, mContext);
|
||||
} else if (shortcutInfo != null) {
|
||||
return new ShortcutInfo(shortcutInfo, mContext);
|
||||
} else if (providerInfo != null) {
|
||||
LauncherAppWidgetProviderInfo info = LauncherAppWidgetProviderInfo
|
||||
.fromProviderInfo(mContext, providerInfo);
|
||||
LauncherAppWidgetInfo widgetInfo = new LauncherAppWidgetInfo(
|
||||
launchIntent.getIntExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, 0),
|
||||
info.provider);
|
||||
InvariantDeviceProfile idp = LauncherAppState.getInstance()
|
||||
.getInvariantDeviceProfile();
|
||||
widgetInfo.minSpanX = info.minSpanX;
|
||||
widgetInfo.minSpanY = info.minSpanY;
|
||||
widgetInfo.spanX = Math.min(info.spanX, idp.numColumns);
|
||||
widgetInfo.spanY = Math.min(info.spanY, idp.numRows);
|
||||
return widgetInfo;
|
||||
} else {
|
||||
return LauncherAppState.getInstance().getModel().infoFromShortcutIntent(mContext, data);
|
||||
}
|
||||
@@ -425,6 +481,16 @@ public class InstallShortcutReceiver extends BroadcastReceiver {
|
||||
} else {
|
||||
return new PendingInstallShortcutInfo(si.get(0), context);
|
||||
}
|
||||
} else if (decoder.optBoolean(APP_WIDGET_TYPE_KEY)) {
|
||||
int widgetId = decoder.launcherIntent
|
||||
.getIntExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, 0);
|
||||
AppWidgetProviderInfo info = AppWidgetManager.getInstance(context)
|
||||
.getAppWidgetInfo(widgetId);
|
||||
if (info == null || !info.provider.equals(decoder.launcherIntent.getComponent()) ||
|
||||
!info.getProfile().equals(decoder.user.getUser())) {
|
||||
return null;
|
||||
}
|
||||
return new PendingInstallShortcutInfo(info, widgetId, context);
|
||||
}
|
||||
|
||||
Intent data = new Intent();
|
||||
@@ -523,7 +589,7 @@ public class InstallShortcutReceiver extends BroadcastReceiver {
|
||||
}
|
||||
|
||||
// Generate a shortcut info to add into the model
|
||||
installQueue.add(pendingInfo.getShortcutInfo());
|
||||
installQueue.add(pendingInfo.getItemInfo());
|
||||
}
|
||||
return installQueue;
|
||||
}
|
||||
|
||||
@@ -3295,25 +3295,25 @@ public class Launcher extends Activity
|
||||
* Implementation of the method from LauncherModel.Callbacks.
|
||||
*/
|
||||
@Override
|
||||
public void bindItems(final ArrayList<ItemInfo> shortcuts, final int start, final int end,
|
||||
public void bindItems(final ArrayList<ItemInfo> items, final int start, final int end,
|
||||
final boolean forceAnimateIcons) {
|
||||
Runnable r = new Runnable() {
|
||||
public void run() {
|
||||
bindItems(shortcuts, start, end, forceAnimateIcons);
|
||||
bindItems(items, start, end, forceAnimateIcons);
|
||||
}
|
||||
};
|
||||
if (waitUntilResume(r)) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Get the list of added shortcuts and intersect them with the set of shortcuts here
|
||||
// Get the list of added items and intersect them with the set of items here
|
||||
final AnimatorSet anim = LauncherAnimUtils.createAnimatorSet();
|
||||
final Collection<Animator> bounceAnims = new ArrayList<Animator>();
|
||||
final boolean animateIcons = forceAnimateIcons && canRunNewAppsAnimation();
|
||||
Workspace workspace = mWorkspace;
|
||||
long newShortcutsScreenId = -1;
|
||||
long newItemsScreenId = -1;
|
||||
for (int i = start; i < end; i++) {
|
||||
final ItemInfo item = shortcuts.get(i);
|
||||
final ItemInfo item = items.get(i);
|
||||
|
||||
// Short circuit if we are loading dock items for a configuration which has no dock
|
||||
if (item.container == LauncherSettings.Favorites.CONTAINER_HOTSEAT &&
|
||||
@@ -3325,15 +3325,33 @@ public class Launcher extends Activity
|
||||
switch (item.itemType) {
|
||||
case LauncherSettings.Favorites.ITEM_TYPE_APPLICATION:
|
||||
case LauncherSettings.Favorites.ITEM_TYPE_SHORTCUT:
|
||||
case LauncherSettings.Favorites.ITEM_TYPE_DEEP_SHORTCUT:
|
||||
case LauncherSettings.Favorites.ITEM_TYPE_DEEP_SHORTCUT: {
|
||||
ShortcutInfo info = (ShortcutInfo) item;
|
||||
view = createShortcut(info);
|
||||
break;
|
||||
case LauncherSettings.Favorites.ITEM_TYPE_FOLDER:
|
||||
}
|
||||
case LauncherSettings.Favorites.ITEM_TYPE_FOLDER: {
|
||||
view = FolderIcon.fromXml(R.layout.folder_icon, this,
|
||||
(ViewGroup) workspace.getChildAt(workspace.getCurrentPage()),
|
||||
(FolderInfo) item, mIconCache);
|
||||
break;
|
||||
}
|
||||
case LauncherSettings.Favorites.ITEM_TYPE_APPWIDGET: {
|
||||
LauncherAppWidgetInfo info = (LauncherAppWidgetInfo) item;
|
||||
if (mIsSafeModeEnabled) {
|
||||
view = new PendingAppWidgetHostView(this, info, mIconCache, true);
|
||||
} else {
|
||||
LauncherAppWidgetProviderInfo providerInfo =
|
||||
mAppWidgetManager.getLauncherAppWidgetInfo(info.appWidgetId);
|
||||
if (providerInfo == null) {
|
||||
deleteWidgetInfo(info);
|
||||
continue;
|
||||
}
|
||||
view = mAppWidgetHost.createView(this, info.appWidgetId, providerInfo);
|
||||
}
|
||||
prepareAppWidget((AppWidgetHostView) view, info);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
throw new RuntimeException("Invalid Item Type");
|
||||
}
|
||||
@@ -3364,22 +3382,22 @@ public class Launcher extends Activity
|
||||
view.setScaleX(0f);
|
||||
view.setScaleY(0f);
|
||||
bounceAnims.add(createNewAppBounceAnimation(view, i));
|
||||
newShortcutsScreenId = item.screenId;
|
||||
newItemsScreenId = item.screenId;
|
||||
}
|
||||
}
|
||||
|
||||
if (animateIcons) {
|
||||
// Animate to the correct page
|
||||
if (newShortcutsScreenId > -1) {
|
||||
if (newItemsScreenId > -1) {
|
||||
long currentScreenId = mWorkspace.getScreenIdForPageIndex(mWorkspace.getNextPage());
|
||||
final int newScreenIndex = mWorkspace.getPageIndexForScreenId(newShortcutsScreenId);
|
||||
final int newScreenIndex = mWorkspace.getPageIndexForScreenId(newItemsScreenId);
|
||||
final Runnable startBounceAnimRunnable = new Runnable() {
|
||||
public void run() {
|
||||
anim.playTogether(bounceAnims);
|
||||
anim.start();
|
||||
}
|
||||
};
|
||||
if (newShortcutsScreenId != currentScreenId) {
|
||||
if (newItemsScreenId != currentScreenId) {
|
||||
// We post the animation slightly delayed to prevent slowdowns
|
||||
// when we are loading right after we return to launcher.
|
||||
mWorkspace.postDelayed(new Runnable() {
|
||||
|
||||
@@ -26,6 +26,7 @@ import com.android.launcher3.FolderInfo;
|
||||
import com.android.launcher3.InvariantDeviceProfile;
|
||||
import com.android.launcher3.ItemInfo;
|
||||
import com.android.launcher3.LauncherAppState;
|
||||
import com.android.launcher3.LauncherAppWidgetInfo;
|
||||
import com.android.launcher3.LauncherModel;
|
||||
import com.android.launcher3.LauncherModel.CallbackTask;
|
||||
import com.android.launcher3.LauncherModel.Callbacks;
|
||||
@@ -60,8 +61,8 @@ public class AddWorkspaceItemsTask extends ExtendedModelTask {
|
||||
}
|
||||
Context context = app.getContext();
|
||||
|
||||
final ArrayList<ItemInfo> addedShortcutsFinal = new ArrayList<ItemInfo>();
|
||||
final ArrayList<Long> addedWorkspaceScreensFinal = new ArrayList<Long>();
|
||||
final ArrayList<ItemInfo> addedItemsFinal = new ArrayList<>();
|
||||
final ArrayList<Long> addedWorkspaceScreensFinal = new ArrayList<>();
|
||||
|
||||
// Get the list of workspace screens. We need to append to this list and
|
||||
// can not use sBgWorkspaceScreens because loadWorkspace() may not have been
|
||||
@@ -77,13 +78,14 @@ public class AddWorkspaceItemsTask extends ExtendedModelTask {
|
||||
}
|
||||
|
||||
// Find appropriate space for the item.
|
||||
Pair<Long, int[]> coords = findSpaceForItem(
|
||||
app, dataModel, workspaceScreens, addedWorkspaceScreensFinal, 1, 1);
|
||||
Pair<Long, int[]> coords = findSpaceForItem(app, dataModel, workspaceScreens,
|
||||
addedWorkspaceScreensFinal, item.spanX, item.spanY);
|
||||
long screenId = coords.first;
|
||||
int[] cordinates = coords.second;
|
||||
|
||||
ItemInfo itemInfo;
|
||||
if (item instanceof ShortcutInfo || item instanceof FolderInfo) {
|
||||
if (item instanceof ShortcutInfo || item instanceof FolderInfo ||
|
||||
item instanceof LauncherAppWidgetInfo) {
|
||||
itemInfo = item;
|
||||
} else if (item instanceof AppInfo) {
|
||||
itemInfo = ((AppInfo) item).makeShortcut();
|
||||
@@ -95,23 +97,23 @@ public class AddWorkspaceItemsTask extends ExtendedModelTask {
|
||||
addItemToDatabase(context, itemInfo, screenId, cordinates);
|
||||
|
||||
// Save the ShortcutInfo for binding in the workspace
|
||||
addedShortcutsFinal.add(itemInfo);
|
||||
addedItemsFinal.add(itemInfo);
|
||||
}
|
||||
}
|
||||
|
||||
// Update the workspace screens
|
||||
updateScreens(context, workspaceScreens);
|
||||
|
||||
if (!addedShortcutsFinal.isEmpty()) {
|
||||
if (!addedItemsFinal.isEmpty()) {
|
||||
scheduleCallbackTask(new CallbackTask() {
|
||||
@Override
|
||||
public void execute(Callbacks callbacks) {
|
||||
final ArrayList<ItemInfo> addAnimated = new ArrayList<ItemInfo>();
|
||||
final ArrayList<ItemInfo> addNotAnimated = new ArrayList<ItemInfo>();
|
||||
if (!addedShortcutsFinal.isEmpty()) {
|
||||
ItemInfo info = addedShortcutsFinal.get(addedShortcutsFinal.size() - 1);
|
||||
if (!addedItemsFinal.isEmpty()) {
|
||||
ItemInfo info = addedItemsFinal.get(addedItemsFinal.size() - 1);
|
||||
long lastScreenId = info.screenId;
|
||||
for (ItemInfo i : addedShortcutsFinal) {
|
||||
for (ItemInfo i : addedItemsFinal) {
|
||||
if (i.screenId == lastScreenId) {
|
||||
addAnimated.add(i);
|
||||
} else {
|
||||
|
||||
Reference in New Issue
Block a user