Initial implementation of Shrink-wrap

Change-Id: If73c7f7ca19ca62ff43134f515584354afef8507
This commit is contained in:
Adam Cohen
2013-06-25 12:29:32 -07:00
parent 211667e4c2
commit dcd297f05a
14 changed files with 609 additions and 266 deletions
-5
View File
@@ -46,11 +46,6 @@
launcher:scrollIndicatorPaddingLeft="@dimen/qsb_bar_height"
launcher:scrollIndicatorPaddingRight="@dimen/button_bar_height">
<include android:id="@+id/cell1" layout="@layout/workspace_screen" />
<include android:id="@+id/cell2" layout="@layout/workspace_screen" />
<include android:id="@+id/cell3" layout="@layout/workspace_screen" />
<include android:id="@+id/cell4" layout="@layout/workspace_screen" />
<include android:id="@+id/cell5" layout="@layout/workspace_screen" />
</com.android.launcher3.Workspace>
<include
-6
View File
@@ -63,12 +63,6 @@
launcher:pageSpacing="@dimen/workspace_page_spacing"
launcher:scrollIndicatorPaddingLeft="@dimen/workspace_divider_padding_left"
launcher:scrollIndicatorPaddingRight="@dimen/workspace_divider_padding_right">
<include android:id="@+id/cell1" layout="@layout/workspace_screen" />
<include android:id="@+id/cell2" layout="@layout/workspace_screen" />
<include android:id="@+id/cell3" layout="@layout/workspace_screen" />
<include android:id="@+id/cell4" layout="@layout/workspace_screen" />
<include android:id="@+id/cell5" layout="@layout/workspace_screen" />
</com.android.launcher3.Workspace>
<include layout="@layout/hotseat"
+5 -2
View File
@@ -709,7 +709,10 @@ public class CellLayout extends ViewGroup {
@Override
protected void onAttachedToWindow() {
super.onAttachedToWindow();
mCellInfo.screen = ((ViewGroup) getParent()).indexOfChild(this);
if (getParent() instanceof Workspace) {
Workspace workspace = (Workspace) getParent();
mCellInfo.screenId = workspace.getIdForScreen(this);
}
}
public void setTagToCellInfoForPoint(int touchX, int touchY) {
@@ -3334,7 +3337,7 @@ out: for (int i = x; i < x + spanX - 1 && x < xCount; i++) {
int cellY = -1;
int spanX;
int spanY;
int screen;
long screenId;
long container;
@Override
+3 -3
View File
@@ -1066,7 +1066,7 @@ public class Folder extends LinearLayout implements DragSource, View.OnClickList
Runnable onCompleteRunnable = new Runnable() {
@Override
public void run() {
CellLayout cellLayout = mLauncher.getCellLayout(mInfo.container, mInfo.screen);
CellLayout cellLayout = mLauncher.getCellLayout(mInfo.container, mInfo.screenId);
View child = null;
// Move the item from the folder to the workspace, in the position of the folder
@@ -1075,7 +1075,7 @@ public class Folder extends LinearLayout implements DragSource, View.OnClickList
child = mLauncher.createShortcut(R.layout.application, cellLayout,
finalItem);
LauncherModel.addOrMoveItemInDatabase(mLauncher, finalItem, mInfo.container,
mInfo.screen, mInfo.cellX, mInfo.cellY);
mInfo.screenId, mInfo.cellX, mInfo.cellY);
}
if (getItemCount() <= 1) {
// Remove the folder
@@ -1089,7 +1089,7 @@ public class Folder extends LinearLayout implements DragSource, View.OnClickList
// We add the child after removing the folder to prevent both from existing at
// the same time in the CellLayout.
if (child != null) {
mLauncher.getWorkspace().addInScreen(child, mInfo.container, mInfo.screen,
mLauncher.getWorkspace().addInScreen(child, mInfo.container, mInfo.screenId,
mInfo.cellX, mInfo.cellY, mInfo.spanX, mInfo.spanY);
}
}
+2 -2
View File
@@ -122,10 +122,10 @@ public class Hotseat extends FrameLayout {
fi.spanX = 1;
fi.spanY = 1;
fi.container = LauncherSettings.Favorites.CONTAINER_HOTSEAT;
fi.screen = mAllAppsButtonRank;
fi.screenId = mAllAppsButtonRank;
fi.itemType = LauncherSettings.Favorites.ITEM_TYPE_FOLDER;
fi.title = "All Apps";
LauncherModel.addItemToDatabase(launcher, fi, fi.container, fi.screen, fi.cellX,
LauncherModel.addItemToDatabase(launcher, fi, fi.container, fi.screenId, fi.cellX,
fi.cellY, false);
FolderIcon folder = FolderIcon.fromXml(R.layout.folder_icon, launcher,
getLayout(), fi, iconCache);
@@ -333,6 +333,7 @@ public class InstallShortcutReceiver extends BroadcastReceiver {
return false;
}
// TODO: this needs to be updated to take a screenId instead of a screen index
private static boolean findEmptyCell(Context context, ArrayList<ItemInfo> items, int[] xy,
int screen) {
final int xCount = LauncherModel.getCellCountX();
@@ -344,7 +345,7 @@ public class InstallShortcutReceiver extends BroadcastReceiver {
for (int i = 0; i < items.size(); ++i) {
item = items.get(i);
if (item.container == LauncherSettings.Favorites.CONTAINER_DESKTOP) {
if (item.screen == screen) {
if (item.screenId == screen) {
cellX = item.cellX;
cellY = item.cellY;
spanX = item.spanX;
+4 -4
View File
@@ -55,7 +55,7 @@ class ItemInfo {
/**
* Iindicates the screen in which the shortcut appears.
*/
int screen = -1;
long screenId = -1;
/**
* Indicates the X position of the associated cell.
@@ -111,7 +111,7 @@ class ItemInfo {
cellY = info.cellY;
spanX = info.spanX;
spanY = info.spanY;
screen = info.screen;
screenId = info.screenId;
itemType = info.itemType;
container = info.container;
// tempdebug:
@@ -141,7 +141,7 @@ class ItemInfo {
void onAddToDatabase(ContentValues values) {
values.put(LauncherSettings.BaseLauncherColumns.ITEM_TYPE, itemType);
values.put(LauncherSettings.Favorites.CONTAINER, container);
values.put(LauncherSettings.Favorites.SCREEN, screen);
values.put(LauncherSettings.Favorites.SCREEN, screenId);
values.put(LauncherSettings.Favorites.CELLX, cellX);
values.put(LauncherSettings.Favorites.CELLY, cellY);
values.put(LauncherSettings.Favorites.SPANX, spanX);
@@ -188,7 +188,7 @@ class ItemInfo {
@Override
public String toString() {
return "Item(id=" + this.id + " type=" + this.itemType + " container=" + this.container
+ " screen=" + screen + " cellX=" + cellX + " cellY=" + cellY + " spanX=" + spanX
+ " screen=" + screenId + " cellX=" + cellX + " cellY=" + cellY + " spanX=" + spanX
+ " spanY=" + spanY + " dropPos=" + dropPos + ")";
}
}
+59 -68
View File
@@ -295,7 +295,7 @@ public class Launcher extends Activity
// Holds the page that we need to animate to, and the icon views that we need to animate up
// when we scroll to that page on resume.
private int mNewShortcutAnimatePage = -1;
private long mNewShortcutAnimateScreenId = -1;
private ArrayList<View> mNewShortcutAnimateViews = new ArrayList<View>();
private ImageView mFolderIconImageView;
private Bitmap mFolderIconBitmap;
@@ -324,7 +324,7 @@ public class Launcher extends Activity
int requestCode;
Intent intent;
long container;
int screen;
long screenId;
int cellX;
int cellY;
}
@@ -592,20 +592,20 @@ public class Launcher extends Activity
boolean result = false;
switch (args.requestCode) {
case REQUEST_PICK_APPLICATION:
completeAddApplication(args.intent, args.container, args.screen, args.cellX,
completeAddApplication(args.intent, args.container, args.screenId, args.cellX,
args.cellY);
break;
case REQUEST_PICK_SHORTCUT:
processShortcut(args.intent);
break;
case REQUEST_CREATE_SHORTCUT:
completeAddShortcut(args.intent, args.container, args.screen, args.cellX,
completeAddShortcut(args.intent, args.container, args.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.screen, null, null);
completeAddAppWidget(appWidgetId, args.container, args.screenId, null, null);
result = true;
break;
case REQUEST_PICK_WALLPAPER:
@@ -661,7 +661,7 @@ public class Launcher extends Activity
args.requestCode = requestCode;
args.intent = data;
args.container = mPendingAddInfo.container;
args.screen = mPendingAddInfo.screen;
args.screenId = mPendingAddInfo.screenId;
args.cellX = mPendingAddInfo.cellX;
args.cellY = mPendingAddInfo.cellY;
if (isWorkspaceLocked()) {
@@ -678,7 +678,7 @@ public class Launcher extends Activity
private void completeTwoStageWidgetDrop(final int resultCode, final int appWidgetId) {
CellLayout cellLayout =
(CellLayout) mWorkspace.getChildAt(mPendingAddInfo.screen);
(CellLayout) mWorkspace.getScreenWithId(mPendingAddInfo.screenId);
Runnable onCompleteRunnable = null;
int animationType = 0;
@@ -692,7 +692,7 @@ public class Launcher extends Activity
@Override
public void run() {
completeAddAppWidget(appWidgetId, mPendingAddInfo.container,
mPendingAddInfo.screen, layout, null);
mPendingAddInfo.screenId, layout, null);
exitSpringLoadedDragModeDelayed((resultCode != RESULT_CANCELED), false,
null);
}
@@ -826,22 +826,7 @@ public class Launcher extends Activity
// Add a fullscreen unpadded view to the workspace to the left all other screens.
public void addCustomContentToLeft(View customContent) {
CellLayout customScreen = (CellLayout)
getLayoutInflater().inflate(R.layout.workspace_custom_content, null);
int spanX = customScreen.getCountX();
int spanY = customScreen.getCountY();
CellLayout.LayoutParams lp = new CellLayout.LayoutParams(0, 0, spanX, spanY);
lp.canReorder = false;
customScreen.addViewToCellLayout(customContent, 0, 0, lp, true);
mWorkspace.addView(customScreen, 0);
// Ensure that the current page and default page are maintained.
mWorkspace.incrementNumScreensToLeft();
mWorkspace.setCurrentPage(mWorkspace.getCurrentPage() + 1);
mWorkspace.addCustomContentToLeft(customContent);
}
@Override
@@ -955,11 +940,11 @@ public class Launcher extends Activity
}
final long pendingAddContainer = savedState.getLong(RUNTIME_STATE_PENDING_ADD_CONTAINER, -1);
final int pendingAddScreen = savedState.getInt(RUNTIME_STATE_PENDING_ADD_SCREEN, -1);
final long pendingAddScreen = savedState.getLong(RUNTIME_STATE_PENDING_ADD_SCREEN, -1);
if (pendingAddContainer != ItemInfo.NO_ID && pendingAddScreen > -1) {
mPendingAddInfo.container = pendingAddContainer;
mPendingAddInfo.screen = pendingAddScreen;
mPendingAddInfo.screenId = pendingAddScreen;
mPendingAddInfo.cellX = savedState.getInt(RUNTIME_STATE_PENDING_ADD_CELL_X);
mPendingAddInfo.cellY = savedState.getInt(RUNTIME_STATE_PENDING_ADD_CELL_Y);
mPendingAddInfo.spanX = savedState.getInt(RUNTIME_STATE_PENDING_ADD_SPAN_X);
@@ -969,7 +954,6 @@ public class Launcher extends Activity
mRestoring = true;
}
boolean renameFolder = savedState.getBoolean(RUNTIME_STATE_PENDING_FOLDER_RENAME, false);
if (renameFolder) {
long id = savedState.getLong(RUNTIME_STATE_PENDING_FOLDER_RENAME_ID);
@@ -977,7 +961,6 @@ public class Launcher extends Activity
mRestoring = true;
}
// Restore the AppsCustomize tab
if (mAppsCustomizeTabHost != null) {
String curTab = savedState.getString("apps_customize_currentTab");
@@ -1086,9 +1069,9 @@ public class Launcher extends Activity
* @param data The intent describing the application.
* @param cellInfo The position on screen where to create the shortcut.
*/
void completeAddApplication(Intent data, long container, int screen, int cellX, int cellY) {
void completeAddApplication(Intent data, long container, long screenId, int cellX, int cellY) {
final int[] cellXY = mTmpAddItemCellCoordinates;
final CellLayout layout = getCellLayout(container, screen);
final CellLayout layout = getCellLayout(container, screenId);
// First we check if we already know the exact location where we want to add this item.
if (cellX >= 0 && cellY >= 0) {
@@ -1105,7 +1088,7 @@ public class Launcher extends Activity
info.setActivity(data.getComponent(), Intent.FLAG_ACTIVITY_NEW_TASK |
Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED);
info.container = ItemInfo.NO_ID;
mWorkspace.addApplicationShortcut(info, layout, container, screen, cellXY[0], cellXY[1],
mWorkspace.addApplicationShortcut(info, layout, container, screenId, cellXY[0], cellXY[1],
isWorkspaceLocked(), cellX, cellY);
} else {
Log.e(TAG, "Couldn't find ActivityInfo for selected application: " + data);
@@ -1118,11 +1101,11 @@ public class Launcher extends Activity
* @param data The intent describing the shortcut.
* @param cellInfo The position on screen where to create the shortcut.
*/
private void completeAddShortcut(Intent data, long container, int screen, int cellX,
private void completeAddShortcut(Intent data, long container, long screenId, int cellX,
int cellY) {
int[] cellXY = mTmpAddItemCellCoordinates;
int[] touchXY = mPendingAddInfo.dropPos;
CellLayout layout = getCellLayout(container, screen);
CellLayout layout = getCellLayout(container, screenId);
boolean foundCellSpan = false;
@@ -1162,11 +1145,10 @@ public class Launcher extends Activity
return;
}
int adjustedScreen = screen - getWorkspace().mNumPagesToLeft;
LauncherModel.addItemToDatabase(this, info, container, adjustedScreen, cellXY[0], cellXY[1], false);
LauncherModel.addItemToDatabase(this, info, container, screenId, cellXY[0], cellXY[1], false);
if (!mRestoring) {
mWorkspace.addInScreen(view, container, screen, cellXY[0], cellXY[1], 1, 1,
mWorkspace.addInScreen(view, container, screenId, cellXY[0], cellXY[1], 1, 1,
isWorkspaceLocked());
}
}
@@ -1204,14 +1186,14 @@ public class Launcher extends Activity
* @param appWidgetId The app widget id
* @param cellInfo The position on screen where to create the widget.
*/
private void completeAddAppWidget(final int appWidgetId, long container, int screen,
private void completeAddAppWidget(final int appWidgetId, long container, long screenId,
AppWidgetHostView hostView, AppWidgetProviderInfo appWidgetInfo) {
if (appWidgetInfo == null) {
appWidgetInfo = mAppWidgetManager.getAppWidgetInfo(appWidgetId);
}
// Calculate the grid spans needed to fit this widget
CellLayout layout = getCellLayout(container, screen);
CellLayout layout = getCellLayout(container, screenId);
int[] minSpanXY = getMinSpanForWidget(this, appWidgetInfo);
int[] spanXY = getSpanForWidget(this, appWidgetInfo);
@@ -1263,9 +1245,8 @@ public class Launcher extends Activity
launcherInfo.minSpanX = mPendingAddInfo.minSpanX;
launcherInfo.minSpanY = mPendingAddInfo.minSpanY;
int adjustedScreen = screen - getWorkspace().mNumPagesToLeft;
LauncherModel.addItemToDatabase(this, launcherInfo,
container, adjustedScreen, cellXY[0], cellXY[1], false);
container, screenId, cellXY[0], cellXY[1], false);
if (!mRestoring) {
if (hostView == null) {
@@ -1281,7 +1262,7 @@ public class Launcher extends Activity
launcherInfo.hostView.setVisibility(View.VISIBLE);
launcherInfo.notifyWidgetSizeChanged(this);
mWorkspace.addInScreen(launcherInfo.hostView, container, screen, cellXY[0], cellXY[1],
mWorkspace.addInScreen(launcherInfo.hostView, container, screenId, cellXY[0], cellXY[1],
launcherInfo.spanX, launcherInfo.spanY, isWorkspaceLocked());
addWidgetToAutoAdvanceIfNeeded(launcherInfo.hostView, appWidgetInfo);
@@ -1560,10 +1541,10 @@ public class Launcher extends Activity
// this state is reflected.
closeFolder();
if (mPendingAddInfo.container != ItemInfo.NO_ID && mPendingAddInfo.screen > -1 &&
if (mPendingAddInfo.container != ItemInfo.NO_ID && mPendingAddInfo.screenId > -1 &&
mWaitingForResult) {
outState.putLong(RUNTIME_STATE_PENDING_ADD_CONTAINER, mPendingAddInfo.container);
outState.putInt(RUNTIME_STATE_PENDING_ADD_SCREEN, mPendingAddInfo.screen);
outState.putLong(RUNTIME_STATE_PENDING_ADD_SCREEN, mPendingAddInfo.screenId);
outState.putInt(RUNTIME_STATE_PENDING_ADD_CELL_X, mPendingAddInfo.cellX);
outState.putInt(RUNTIME_STATE_PENDING_ADD_CELL_Y, mPendingAddInfo.cellY);
outState.putInt(RUNTIME_STATE_PENDING_ADD_SPAN_X, mPendingAddInfo.spanX);
@@ -1789,7 +1770,7 @@ public class Launcher extends Activity
private void resetAddInfo() {
mPendingAddInfo.container = ItemInfo.NO_ID;
mPendingAddInfo.screen = -1;
mPendingAddInfo.screenId = -1;
mPendingAddInfo.cellX = mPendingAddInfo.cellY = -1;
mPendingAddInfo.spanX = mPendingAddInfo.spanY = -1;
mPendingAddInfo.minSpanX = mPendingAddInfo.minSpanY = -1;
@@ -1808,7 +1789,7 @@ public class Launcher extends Activity
startActivityForResultSafely(intent, REQUEST_CREATE_APPWIDGET);
} else {
// Otherwise just add it
completeAddAppWidget(appWidgetId, info.container, info.screen, boundWidget,
completeAddAppWidget(appWidgetId, info.container, info.screenId, boundWidget,
appWidgetInfo);
// Exit spring loaded mode if necessary after adding the widget
exitSpringLoadedDragModeDelayed(true, false, null);
@@ -1819,15 +1800,15 @@ public class Launcher extends Activity
* Process a shortcut drop.
*
* @param componentName The name of the component
* @param screen The screen where it should be added
* @param screenId The ID of the screen where it should be added
* @param cell The cell it should be added to, optional
* @param position The location on the screen where it was dropped, optional
*/
void processShortcutFromDrop(ComponentName componentName, long container, int screen,
void processShortcutFromDrop(ComponentName componentName, long container, long screenId,
int[] cell, int[] loc) {
resetAddInfo();
mPendingAddInfo.container = container;
mPendingAddInfo.screen = screen;
mPendingAddInfo.screenId = screenId;
mPendingAddInfo.dropPos = loc;
if (cell != null) {
@@ -1844,15 +1825,15 @@ public class Launcher extends Activity
* Process a widget drop.
*
* @param info The PendingAppWidgetInfo of the widget being added.
* @param screen The screen where it should be added
* @param screenId The ID of the screen where it should be added
* @param cell The cell it should be added to, optional
* @param position The location on the screen where it was dropped, optional
*/
void addAppWidgetFromDrop(PendingAddWidgetInfo info, long container, int screen,
void addAppWidgetFromDrop(PendingAddWidgetInfo info, long container, long screenId,
int[] cell, int[] span, int[] loc) {
resetAddInfo();
mPendingAddInfo.container = info.container = container;
mPendingAddInfo.screen = info.screen = screen;
mPendingAddInfo.screenId = info.screenId = screenId;
mPendingAddInfo.dropPos = loc;
mPendingAddInfo.minSpanX = info.minSpanX;
mPendingAddInfo.minSpanY = info.minSpanY;
@@ -1921,20 +1902,20 @@ public class Launcher extends Activity
startActivityForResult(intent, REQUEST_PICK_WALLPAPER);
}
FolderIcon addFolder(CellLayout layout, long container, final int screen, int cellX,
FolderIcon addFolder(CellLayout layout, long container, final long screenId, int cellX,
int cellY) {
final FolderInfo folderInfo = new FolderInfo();
folderInfo.title = getText(R.string.folder_name);
// Update the model
LauncherModel.addItemToDatabase(Launcher.this, folderInfo, container, screen, cellX, cellY,
LauncherModel.addItemToDatabase(Launcher.this, folderInfo, container, screenId, cellX, cellY,
false);
sFolders.put(folderInfo.id, folderInfo);
// Create the view
FolderIcon newFolder =
FolderIcon.fromXml(R.layout.folder_icon, this, layout, folderInfo, mIconCache);
mWorkspace.addInScreen(newFolder, container, screen, cellX, cellY, 1, 1,
mWorkspace.addInScreen(newFolder, container, screenId, cellX, cellY, 1, 1,
isWorkspaceLocked());
return newFolder;
}
@@ -2231,7 +2212,7 @@ public class Launcher extends Activity
// it is actually opened. There have been a few instances where this gets out of sync.
if (info.opened && openFolder == null) {
Log.d(TAG, "Folder info marked as open, but associated folder is not open. Screen: "
+ info.screen + " (" + info.cellX + ", " + info.cellY + ")");
+ info.screenId + " (" + info.cellX + ", " + info.cellY + ")");
info.opened = false;
}
@@ -2469,7 +2450,7 @@ public class Launcher extends Activity
/**
* Returns the CellLayout of the specified container at the specified screen.
*/
CellLayout getCellLayout(long container, int screen) {
CellLayout getCellLayout(long container, long screenId) {
if (container == LauncherSettings.Favorites.CONTAINER_HOTSEAT) {
if (mHotseat != null) {
return mHotseat.getLayout();
@@ -2477,7 +2458,7 @@ public class Launcher extends Activity
return null;
}
} else {
return (CellLayout) mWorkspace.getChildAt(screen);
return (CellLayout) mWorkspace.getScreenWithId(screenId);
}
}
@@ -3440,7 +3421,7 @@ public class Launcher extends Activity
mOnResumeCallbacks.clear();
final Workspace workspace = mWorkspace;
mNewShortcutAnimatePage = -1;
mNewShortcutAnimateScreenId = -1;
mNewShortcutAnimateViews.clear();
mWorkspace.clearDropTargets();
int count = workspace.getChildCount();
@@ -3455,6 +3436,15 @@ public class Launcher extends Activity
}
}
@Override
public void bindScreens(ArrayList<Long> orderedScreenIds) {
int count = orderedScreenIds.size();
for (int i = 0; i < count; i++) {
mWorkspace.insertNewWorkspaceScreenOnBind(orderedScreenIds.get(i));
}
mWorkspace.addExtraEmptyScreen();
}
/**
* Bind the items start-end from the list.
*
@@ -3489,8 +3479,9 @@ public class Launcher extends Activity
ShortcutInfo info = (ShortcutInfo) item;
String uri = info.intent.toUri(0).toString();
View shortcut = createShortcut(info);
workspace.addInScreen(shortcut, item.container, item.screen, item.cellX,
item.cellY, 1, 1, false);
workspace.addInScreenFromBind(shortcut, item.container, item.screenId, item.cellX,
item.cellY, 1, 1);
boolean animateIconUp = false;
synchronized (newApps) {
if (newApps.contains(uri)) {
@@ -3502,7 +3493,7 @@ public class Launcher extends Activity
shortcut.setAlpha(0f);
shortcut.setScaleX(0f);
shortcut.setScaleY(0f);
mNewShortcutAnimatePage = item.screen;
mNewShortcutAnimateScreenId = item.screenId;
if (!mNewShortcutAnimateViews.contains(shortcut)) {
mNewShortcutAnimateViews.add(shortcut);
}
@@ -3512,8 +3503,8 @@ public class Launcher extends Activity
FolderIcon newFolder = FolderIcon.fromXml(R.layout.folder_icon, this,
(ViewGroup) workspace.getChildAt(workspace.getCurrentPage()),
(FolderInfo) item, mIconCache);
workspace.addInScreen(newFolder, item.container, item.screen, item.cellX,
item.cellY, 1, 1, false);
workspace.addInScreenFromBind(newFolder, item.container, item.screenId, item.cellX,
item.cellY, 1, 1);
break;
}
}
@@ -3567,7 +3558,7 @@ public class Launcher extends Activity
item.hostView.setTag(item);
item.onBindAppWidget(this);
workspace.addInScreen(item.hostView, item.container, item.screen, item.cellX,
workspace.addInScreen(item.hostView, item.container, item.screenId, item.cellX,
item.cellY, item.spanX, item.spanY, false);
addWidgetToAutoAdvanceIfNeeded(item.hostView, appWidgetInfo);
@@ -3625,13 +3616,13 @@ public class Launcher extends Activity
}
};
boolean willSnapPage = mNewShortcutAnimatePage > -1 &&
mNewShortcutAnimatePage != mWorkspace.getCurrentPage();
boolean willSnapPage = mNewShortcutAnimateScreenId > -1 &&
mNewShortcutAnimateScreenId != mWorkspace.getCurrentPage();
if (canRunNewAppsAnimation()) {
// If the user has not interacted recently, then either snap to the new page to show
// the new-apps animation or just run them if they are to appear on the current page
if (willSnapPage) {
mWorkspace.snapToPage(mNewShortcutAnimatePage, newAppsRunnable);
mWorkspace.snapToScreenId(mNewShortcutAnimateScreenId, newAppsRunnable);
} else {
runNewAppsAnimation(false);
}
@@ -3715,7 +3706,7 @@ public class Launcher extends Activity
}
// Clean up
mNewShortcutAnimatePage = -1;
mNewShortcutAnimateScreenId = -1;
mNewShortcutAnimateViews.clear();
new Thread("clearNewAppsThread") {
public void run() {
+212 -71
View File
@@ -48,14 +48,13 @@ import android.os.RemoteException;
import android.os.SystemClock;
import android.util.Log;
import com.android.launcher3.R;
import com.android.launcher3.InstallWidgetReceiver.WidgetMimeTypeHandlerData;
import java.lang.ref.WeakReference;
import java.net.URISyntaxException;
import java.text.Collator;
import java.util.Arrays;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
@@ -63,6 +62,7 @@ import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
import java.util.TreeMap;
/**
* Maintains in-memory state of the Launcher. It is expected that there should be only one
@@ -138,6 +138,10 @@ public class LauncherModel extends BroadcastReceiver {
// sBgDbIconCache is the set of ItemInfos that need to have their icons updated in the database
static final HashMap<Object, byte[]> sBgDbIconCache = new HashMap<Object, byte[]>();
// sBgWorkspaceScreens is the ordered set of workspace screens.
static final ArrayList<Long> sBgWorkspaceScreens = new ArrayList<Long>();
// </ only access in worker thread >
private IconCache mIconCache;
@@ -153,6 +157,7 @@ public class LauncherModel extends BroadcastReceiver {
public int getCurrentWorkspaceScreen();
public void startBinding();
public void bindItems(ArrayList<ItemInfo> shortcuts, int start, int end);
public void bindScreens(ArrayList<Long> orderedScreenIds);
public void bindFolders(HashMap<Long,FolderInfo> folders);
public void finishBindingItems(boolean upgradePath);
public void bindAppWidget(LauncherAppWidgetInfo info);
@@ -257,13 +262,13 @@ public class LauncherModel extends BroadcastReceiver {
* <container, screen, cellX, cellY>
*/
static void addOrMoveItemInDatabase(Context context, ItemInfo item, long container,
int screen, int cellX, int cellY) {
long screenId, int cellX, int cellY) {
if (item.container == ItemInfo.NO_ID) {
// From all apps
addItemToDatabase(context, item, container, screen, cellX, cellY, false);
addItemToDatabase(context, item, container, screenId, cellX, cellY, false);
} else {
// From somewhere else
moveItemInDatabase(context, item, container, screen, cellX, cellY);
moveItemInDatabase(context, item, container, screenId, cellX, cellY);
}
}
@@ -280,7 +285,7 @@ public class LauncherModel extends BroadcastReceiver {
modelShortcut.id == shortcut.id &&
modelShortcut.itemType == shortcut.itemType &&
modelShortcut.container == shortcut.container &&
modelShortcut.screen == shortcut.screen &&
modelShortcut.screenId == shortcut.screenId &&
modelShortcut.cellX == shortcut.cellX &&
modelShortcut.cellY == shortcut.cellY &&
modelShortcut.spanX == shortcut.spanX &&
@@ -444,10 +449,10 @@ public class LauncherModel extends BroadcastReceiver {
* Move an item in the DB to a new <container, screen, cellX, cellY>
*/
static void moveItemInDatabase(Context context, final ItemInfo item, final long container,
final int screen, final int cellX, final int cellY) {
final long screenId, final int cellX, final int cellY) {
String transaction = "DbDebug Modify item (" + item.title + ") in db, id: " + item.id +
" (" + item.container + ", " + item.screen + ", " + item.cellX + ", " + item.cellY +
") --> " + "(" + container + ", " + screen + ", " + cellX + ", " + cellY + ")";
" (" + item.container + ", " + item.screenId + ", " + item.cellX + ", " + item.cellY +
") --> " + "(" + container + ", " + screenId + ", " + cellX + ", " + cellY + ")";
Launcher.sDumpLogs.add(transaction);
Log.d(TAG, transaction);
item.container = container;
@@ -456,18 +461,18 @@ public class LauncherModel extends BroadcastReceiver {
// We store hotseat items in canonical form which is this orientation invariant position
// in the hotseat
if (context instanceof Launcher && screen < 0 &&
if (context instanceof Launcher && screenId < 0 &&
container == LauncherSettings.Favorites.CONTAINER_HOTSEAT) {
item.screen = ((Launcher) context).getHotseat().getOrderInHotseat(cellX, cellY);
item.screenId = ((Launcher) context).getHotseat().getOrderInHotseat(cellX, cellY);
} else {
item.screen = screen;
item.screenId = screenId;
}
final ContentValues values = new ContentValues();
values.put(LauncherSettings.Favorites.CONTAINER, item.container);
values.put(LauncherSettings.Favorites.CELLX, item.cellX);
values.put(LauncherSettings.Favorites.CELLY, item.cellY);
values.put(LauncherSettings.Favorites.SCREEN, item.screen);
values.put(LauncherSettings.Favorites.SCREEN, item.screenId);
updateItemInDatabaseHelper(context, values, item, "moveItemInDatabase");
}
@@ -485,7 +490,7 @@ public class LauncherModel extends BroadcastReceiver {
for (int i = 0; i < count; i++) {
ItemInfo item = items.get(i);
String transaction = "DbDebug Modify item (" + item.title + ") in db, id: "
+ item.id + " (" + item.container + ", " + item.screen + ", " + item.cellX
+ item.id + " (" + item.container + ", " + item.screenId + ", " + item.cellX
+ ", " + item.cellY + ") --> " + "(" + container + ", " + screen + ", "
+ item.cellX + ", " + item.cellY + ")";
Launcher.sDumpLogs.add(transaction);
@@ -495,17 +500,17 @@ public class LauncherModel extends BroadcastReceiver {
// in the hotseat
if (context instanceof Launcher && screen < 0 &&
container == LauncherSettings.Favorites.CONTAINER_HOTSEAT) {
item.screen = ((Launcher) context).getHotseat().getOrderInHotseat(item.cellX,
item.screenId = ((Launcher) context).getHotseat().getOrderInHotseat(item.cellX,
item.cellY);
} else {
item.screen = screen;
item.screenId = screen;
}
final ContentValues values = new ContentValues();
values.put(LauncherSettings.Favorites.CONTAINER, item.container);
values.put(LauncherSettings.Favorites.CELLX, item.cellX);
values.put(LauncherSettings.Favorites.CELLY, item.cellY);
values.put(LauncherSettings.Favorites.SCREEN, item.screen);
values.put(LauncherSettings.Favorites.SCREEN, item.screenId);
contentValues.add(values);
}
@@ -516,10 +521,10 @@ public class LauncherModel extends BroadcastReceiver {
* Move and/or resize item in the DB to a new <container, screen, cellX, cellY, spanX, spanY>
*/
static void modifyItemInDatabase(Context context, final ItemInfo item, final long container,
final int screen, final int cellX, final int cellY, final int spanX, final int spanY) {
final long screenId, final int cellX, final int cellY, final int spanX, final int spanY) {
String transaction = "DbDebug Modify item (" + item.title + ") in db, id: " + item.id +
" (" + item.container + ", " + item.screen + ", " + item.cellX + ", " + item.cellY +
") --> " + "(" + container + ", " + screen + ", " + cellX + ", " + cellY + ")";
" (" + item.container + ", " + item.screenId + ", " + item.cellX + ", " + item.cellY +
") --> " + "(" + container + ", " + screenId + ", " + cellX + ", " + cellY + ")";
Launcher.sDumpLogs.add(transaction);
Log.d(TAG, transaction);
item.cellX = cellX;
@@ -529,11 +534,11 @@ public class LauncherModel extends BroadcastReceiver {
// We store hotseat items in canonical form which is this orientation invariant position
// in the hotseat
if (context instanceof Launcher && screen < 0 &&
if (context instanceof Launcher && screenId < 0 &&
container == LauncherSettings.Favorites.CONTAINER_HOTSEAT) {
item.screen = ((Launcher) context).getHotseat().getOrderInHotseat(cellX, cellY);
item.screenId = ((Launcher) context).getHotseat().getOrderInHotseat(cellX, cellY);
} else {
item.screen = screen;
item.screenId = screenId;
}
final ContentValues values = new ContentValues();
@@ -542,7 +547,7 @@ public class LauncherModel extends BroadcastReceiver {
values.put(LauncherSettings.Favorites.CELLY, item.cellY);
values.put(LauncherSettings.Favorites.SPANX, item.spanX);
values.put(LauncherSettings.Favorites.SPANY, item.spanY);
values.put(LauncherSettings.Favorites.SCREEN, item.screen);
values.put(LauncherSettings.Favorites.SCREEN, item.screenId);
updateItemInDatabaseHelper(context, values, item, "modifyItemInDatabase");
}
@@ -604,7 +609,7 @@ public class LauncherModel extends BroadcastReceiver {
item.spanY = c.getInt(spanYIndex);
item.container = c.getInt(containerIndex);
item.itemType = c.getInt(itemTypeIndex);
item.screen = c.getInt(screenIndex);
item.screenId = c.getInt(screenIndex);
items.add(item);
}
@@ -646,7 +651,7 @@ public class LauncherModel extends BroadcastReceiver {
folderInfo.title = c.getString(titleIndex);
folderInfo.id = id;
folderInfo.container = c.getInt(containerIndex);
folderInfo.screen = c.getInt(screenIndex);
folderInfo.screenId = c.getInt(screenIndex);
folderInfo.cellX = c.getInt(cellXIndex);
folderInfo.cellY = c.getInt(cellYIndex);
@@ -664,17 +669,17 @@ public class LauncherModel extends BroadcastReceiver {
* cellY fields of the item. Also assigns an ID to the item.
*/
static void addItemToDatabase(Context context, final ItemInfo item, final long container,
final int screen, final int cellX, final int cellY, final boolean notify) {
final long screenId, final int cellX, final int cellY, final boolean notify) {
item.container = container;
item.cellX = cellX;
item.cellY = cellY;
// We store hotseat items in canonical form which is this orientation invariant position
// in the hotseat
if (context instanceof Launcher && screen < 0 &&
if (context instanceof Launcher && screenId < 0 &&
container == LauncherSettings.Favorites.CONTAINER_HOTSEAT) {
item.screen = ((Launcher) context).getHotseat().getOrderInHotseat(cellX, cellY);
item.screenId = ((Launcher) context).getHotseat().getOrderInHotseat(cellX, cellY);
} else {
item.screen = screen;
item.screenId = screenId;
}
final ContentValues values = new ContentValues();
@@ -682,14 +687,14 @@ public class LauncherModel extends BroadcastReceiver {
item.onAddToDatabase(values);
LauncherAppState app = LauncherAppState.getInstance();
item.id = app.getLauncherProvider().generateNewId();
item.id = app.getLauncherProvider().generateNewItemId();
values.put(LauncherSettings.Favorites._ID, item.id);
item.updateValuesWithCoordinates(values, item.cellX, item.cellY);
Runnable r = new Runnable() {
public void run() {
String transaction = "DbDebug Add item (" + item.title + ") to db, id: "
+ item.id + " (" + container + ", " + screen + ", " + cellX + ", "
+ item.id + " (" + container + ", " + screenId + ", " + cellX + ", "
+ cellY + ")";
Launcher.sDumpLogs.add(transaction);
Log.d(TAG, transaction);
@@ -734,9 +739,9 @@ public class LauncherModel extends BroadcastReceiver {
* Creates a new unique child id, for a given cell span across all layouts.
*/
static int getCellLayoutChildId(
long container, int screen, int localCellX, int localCellY, int spanX, int spanY) {
long container, long screen, int localCellX, int localCellY, int spanX, int spanY) {
return (((int) container & 0xFF) << 24)
| (screen & 0xFF) << 16 | (localCellX & 0xFF) << 8 | (localCellY & 0xFF);
| ((int) screen & 0xFF) << 16 | (localCellX & 0xFF) << 8 | (localCellY & 0xFF);
}
static int getCellCountX() {
@@ -768,7 +773,7 @@ public class LauncherModel extends BroadcastReceiver {
Runnable r = new Runnable() {
public void run() {
String transaction = "DbDebug Delete item (" + item.title + ") from db, id: "
+ item.id + " (" + item.container + ", " + item.screen + ", " + item.cellX +
+ item.id + " (" + item.container + ", " + item.screenId + ", " + item.cellX +
", " + item.cellY + ")";
Launcher.sDumpLogs.add(transaction);
Log.d(TAG, transaction);
@@ -808,6 +813,48 @@ public class LauncherModel extends BroadcastReceiver {
runOnWorkerThread(r);
}
/**
* Update the order of the workspace screens in the database. The array list contains
* a list of screen ids in the order that they should appear.
*/
static void updateWorkspaceScreenOrder(Context context, final ArrayList<Long> screens) {
final ContentResolver cr = context.getContentResolver();
final Uri uri = LauncherSettings.WorkspaceScreens.CONTENT_URI;
// Remove any negative screen ids -- these aren't persisted
Iterator<Long> iter = screens.iterator();
while (iter.hasNext()) {
long id = iter.next();
if (id < 0) {
iter.remove();
}
}
Runnable r = new Runnable() {
@Override
public void run() {
final ArrayList<Long> screensCopy = new ArrayList<Long>();
// Clear the table
cr.delete(uri, null, null);
int count = screens.size();
ContentValues[] values = new ContentValues[count];
for (int i = 0; i < count; i++) {
ContentValues v = new ContentValues();
long screenId = screens.get(i);
v.put(LauncherSettings.WorkspaceScreens._ID, screenId);
v.put(LauncherSettings.WorkspaceScreens.SCREEN_RANK, i);
screensCopy.add(screenId);
values[i] = v;
}
cr.bulkInsert(uri, values);
sBgWorkspaceScreens.clear();
sBgWorkspaceScreens.addAll(screensCopy);
}
};
runOnWorkerThread(r);
}
/**
* Remove the contents of the specified folder from the database
*/
@@ -1219,7 +1266,6 @@ public class LauncherModel extends BroadcastReceiver {
}
}
// Update the saved icons if necessary
if (DEBUG_LOADERS) Log.d(TAG, "Comparing loaded icons to database icons");
synchronized (sBgLock) {
@@ -1280,23 +1326,23 @@ public class LauncherModel extends BroadcastReceiver {
}
// check & update map of what's occupied; used to discard overlapping/invalid items
private boolean checkItemPlacement(ItemInfo occupied[][][], ItemInfo item) {
int containerIndex = item.screen;
private boolean checkItemPlacement(HashMap<Long, ItemInfo[][]> occupied, ItemInfo item) {
long containerIndex = item.screenId;
if (item.container == LauncherSettings.Favorites.CONTAINER_HOTSEAT) {
// Return early if we detect that an item is under the hotseat button
if (mCallbacks == null || mCallbacks.get().isAllAppsButtonRank(item.screen)) {
return false;
}
// We use the last index to refer to the hotseat and the screen as the rank, so
// test and update the occupied state accordingly
if (occupied[Launcher.SCREEN_COUNT][item.screen][0] != null) {
Log.e(TAG, "Error loading shortcut into hotseat " + item
+ " into position (" + item.screen + ":" + item.cellX + "," + item.cellY
+ ") occupied by " + occupied[Launcher.SCREEN_COUNT][item.screen][0]);
return false;
if (occupied.containsKey(LauncherSettings.Favorites.CONTAINER_HOTSEAT)) {
if (occupied.get(LauncherSettings.Favorites.CONTAINER_HOTSEAT)
[(int) item.screenId][0] != null) {
Log.e(TAG, "Error loading shortcut into hotseat " + item
+ " into position (" + item.screenId + ":" + item.cellX + ","
+ item.cellY + ") occupied by "
+ occupied.get(LauncherSettings.Favorites.CONTAINER_HOTSEAT)
[(int) item.screenId][0]);
return false;
}
} else {
occupied[Launcher.SCREEN_COUNT][item.screen][0] = item;
ItemInfo[][] items = new ItemInfo[mCellCountX + 1][mCellCountY + 1];
items[(int) item.screenId][0] = item;
occupied.put((long) LauncherSettings.Favorites.CONTAINER_HOTSEAT, items);
return true;
}
} else if (item.container != LauncherSettings.Favorites.CONTAINER_DESKTOP) {
@@ -1304,22 +1350,28 @@ public class LauncherModel extends BroadcastReceiver {
return true;
}
if (!occupied.containsKey(item.screenId)) {
ItemInfo[][] items = new ItemInfo[mCellCountX + 1][mCellCountY + 1];
occupied.put(item.screenId, items);
}
ItemInfo[][] screens = occupied.get(item.screenId);
// Check if any workspace icons overlap with each other
for (int x = item.cellX; x < (item.cellX+item.spanX); x++) {
for (int y = item.cellY; y < (item.cellY+item.spanY); y++) {
if (occupied[containerIndex][x][y] != null) {
if (screens[x][y] != null) {
Log.e(TAG, "Error loading shortcut " + item
+ " into cell (" + containerIndex + "-" + item.screen + ":"
+ " into cell (" + containerIndex + "-" + item.screenId + ":"
+ x + "," + y
+ ") occupied by "
+ occupied[containerIndex][x][y]);
+ screens[x][y]);
return false;
}
}
}
for (int x = item.cellX; x < (item.cellX+item.spanX); x++) {
for (int y = item.cellY; y < (item.cellY+item.spanY); y++) {
occupied[containerIndex][x][y] = item;
screens[x][y] = item;
}
}
@@ -1348,6 +1400,7 @@ public class LauncherModel extends BroadcastReceiver {
sBgFolders.clear();
sBgItemsIdMap.clear();
sBgDbIconCache.clear();
sBgWorkspaceScreens.clear();
final ArrayList<Long> itemsToRemove = new ArrayList<Long>();
@@ -1356,8 +1409,7 @@ public class LauncherModel extends BroadcastReceiver {
// +1 for the hotseat (it can be larger than the workspace)
// Load workspace in reverse order to ensure that latest items are loaded first (and
// before any earlier duplicates)
final ItemInfo occupied[][][] =
new ItemInfo[Launcher.SCREEN_COUNT + 1][mCellCountX + 1][mCellCountY + 1];
final HashMap<Long, ItemInfo[][]> occupied = new HashMap<Long, ItemInfo[][]>();
try {
final int idIndex = c.getColumnIndexOrThrow(LauncherSettings.Favorites._ID);
@@ -1439,7 +1491,7 @@ public class LauncherModel extends BroadcastReceiver {
info.id = c.getLong(idIndex);
container = c.getInt(containerIndex);
info.container = container;
info.screen = c.getInt(screenIndex);
info.screenId = c.getInt(screenIndex);
info.cellX = c.getInt(cellXIndex);
info.cellY = c.getInt(cellYIndex);
// check & update map of what's occupied
@@ -1461,7 +1513,7 @@ public class LauncherModel extends BroadcastReceiver {
}
if (container != LauncherSettings.Favorites.CONTAINER_HOTSEAT &&
loadOldDb) {
info.screen = permuteScreens(info.screen);
info.screenId = permuteScreens(info.screenId);
}
sBgItemsIdMap.put(info.id, info);
@@ -1488,7 +1540,7 @@ public class LauncherModel extends BroadcastReceiver {
folderInfo.id = id;
container = c.getInt(containerIndex);
folderInfo.container = container;
folderInfo.screen = c.getInt(screenIndex);
folderInfo.screenId = c.getInt(screenIndex);
folderInfo.cellX = c.getInt(cellXIndex);
folderInfo.cellY = c.getInt(cellYIndex);
@@ -1504,7 +1556,7 @@ public class LauncherModel extends BroadcastReceiver {
}
if (container != LauncherSettings.Favorites.CONTAINER_HOTSEAT &&
loadOldDb) {
folderInfo.screen = permuteScreens(folderInfo.screen);
folderInfo.screenId = permuteScreens(folderInfo.screenId);
}
sBgItemsIdMap.put(folderInfo.id, folderInfo);
@@ -1530,7 +1582,7 @@ public class LauncherModel extends BroadcastReceiver {
appWidgetInfo = new LauncherAppWidgetInfo(appWidgetId,
provider.provider);
appWidgetInfo.id = id;
appWidgetInfo.screen = c.getInt(screenIndex);
appWidgetInfo.screenId = c.getInt(screenIndex);
appWidgetInfo.cellX = c.getInt(cellXIndex);
appWidgetInfo.cellY = c.getInt(cellYIndex);
appWidgetInfo.spanX = c.getInt(spanXIndex);
@@ -1548,7 +1600,8 @@ public class LauncherModel extends BroadcastReceiver {
}
if (container != LauncherSettings.Favorites.CONTAINER_HOTSEAT &&
loadOldDb) {
appWidgetInfo.screen = permuteScreens(appWidgetInfo.screen);
appWidgetInfo.screenId =
permuteScreens(appWidgetInfo.screenId);
}
appWidgetInfo.container = c.getInt(containerIndex);
@@ -1587,17 +1640,86 @@ public class LauncherModel extends BroadcastReceiver {
}
}
if (loadOldDb) {
long maxScreenId = 0;
// If we're importing we use the old screen order.
for (ItemInfo item: sBgItemsIdMap.values()) {
long screenId = item.screenId;
if (item.container == LauncherSettings.Favorites.CONTAINER_DESKTOP &&
!sBgWorkspaceScreens.contains(screenId)) {
sBgWorkspaceScreens.add(screenId);
if (screenId > maxScreenId) {
maxScreenId = screenId;
}
}
}
Collections.sort(sBgWorkspaceScreens);
mApp.getLauncherProvider().updateMaxScreenId(maxScreenId);
updateWorkspaceScreenOrder(context, sBgWorkspaceScreens);
} else {
Uri screensUri = LauncherSettings.WorkspaceScreens.CONTENT_URI;
final Cursor sc = contentResolver.query(screensUri, null, null, null, null);
TreeMap<Integer, Long> orderedScreens = new TreeMap<Integer, Long>();
try {
final int idIndex = sc.getColumnIndexOrThrow(
LauncherSettings.WorkspaceScreens._ID);
final int rankIndex = sc.getColumnIndexOrThrow(
LauncherSettings.WorkspaceScreens.SCREEN_RANK);
while (sc.moveToNext()) {
try {
long screenId = sc.getLong(idIndex);
int rank = sc.getInt(rankIndex);
orderedScreens.put(rank, screenId);
} catch (Exception e) {
Log.w(TAG, "Desktop items loading interrupted:", e);
}
}
} finally {
sc.close();
}
Iterator<Integer> iter = orderedScreens.keySet().iterator();
while (iter.hasNext()) {
sBgWorkspaceScreens.add(orderedScreens.get(iter.next()));
}
// Remove any empty screens
ArrayList<Long> unusedScreens = new ArrayList<Long>();
unusedScreens.addAll(sBgWorkspaceScreens);
for (ItemInfo item: sBgItemsIdMap.values()) {
long screenId = item.screenId;
if (item.container == LauncherSettings.Favorites.CONTAINER_DESKTOP &&
unusedScreens.contains(screenId)) {
unusedScreens.remove(screenId);
}
}
// If there are any empty screens remove them, and update.
if (unusedScreens.size() != 0) {
sBgWorkspaceScreens.removeAll(unusedScreens);
updateWorkspaceScreenOrder(context, sBgWorkspaceScreens);
}
}
if (DEBUG_LOADERS) {
Log.d(TAG, "loaded workspace in " + (SystemClock.uptimeMillis()-t) + "ms");
Log.d(TAG, "workspace layout: ");
Iterator<Long> iter = occupied.keySet().iterator();
int nScreens = occupied.size();
for (int y = 0; y < mCellCountY; y++) {
String line = "";
for (int s = 0; s < Launcher.SCREEN_COUNT; s++) {
for (int s = 0; s < nScreens; s++) {
long screenId = iter.next();
if (s > 0) {
line += " | ";
}
for (int x = 0; x < mCellCountX; x++) {
line += ((occupied[s][x][y] != null) ? "#" : ".");
line += ((occupied.get(screenId)[x][y] != null) ? "#" : ".");
}
}
Log.d(TAG, "[ " + line + " ]");
@@ -1608,7 +1730,7 @@ public class LauncherModel extends BroadcastReceiver {
// We rearrange the screens from the old launcher
// 12345 -> 34512
private int permuteScreens(int screen) {
private long permuteScreens(long screen) {
if (screen >= 2) {
return screen - 2;
} else {
@@ -1649,7 +1771,7 @@ public class LauncherModel extends BroadcastReceiver {
});
for (ItemInfo info : allWorkspaceItems) {
if (info.container == LauncherSettings.Favorites.CONTAINER_DESKTOP) {
if (info.screen == currentScreen) {
if (info.screenId == currentScreen) {
currentScreenItems.add(info);
itemsOnScreen.add(info.id);
} else {
@@ -1683,7 +1805,7 @@ public class LauncherModel extends BroadcastReceiver {
for (LauncherAppWidgetInfo widget : appWidgets) {
if (widget == null) continue;
if (widget.container == LauncherSettings.Favorites.CONTAINER_DESKTOP &&
widget.screen == currentScreen) {
widget.screenId == currentScreen) {
currentScreenWidgets.add(widget);
} else {
otherScreenWidgets.add(widget);
@@ -1708,7 +1830,7 @@ public class LauncherModel extends BroadcastReceiver {
FolderInfo folder = folders.get(id);
if (info == null || folder == null) continue;
if (info.container == LauncherSettings.Favorites.CONTAINER_DESKTOP &&
info.screen == currentScreen) {
info.screenId == currentScreen) {
currentScreenFolders.put(id, folder);
} else {
otherScreenFolders.put(id, folder);
@@ -1727,15 +1849,30 @@ public class LauncherModel extends BroadcastReceiver {
int cellCountY = LauncherModel.getCellCountY();
int screenOffset = cellCountX * cellCountY;
int containerOffset = screenOffset * (Launcher.SCREEN_COUNT + 1); // +1 hotseat
long lr = (lhs.container * containerOffset + lhs.screen * screenOffset +
long lr = (lhs.container * containerOffset + lhs.screenId * screenOffset +
lhs.cellY * cellCountX + lhs.cellX);
long rr = (rhs.container * containerOffset + rhs.screen * screenOffset +
long rr = (rhs.container * containerOffset + rhs.screenId * screenOffset +
rhs.cellY * cellCountX + rhs.cellX);
return (int) (lr - rr);
}
});
}
private void bindWorkspaceScreens(final Callbacks oldCallbacks,
final ArrayList<Long> orderedScreens) {
final Runnable r = new Runnable() {
@Override
public void run() {
Callbacks callbacks = tryGetCallbacks(oldCallbacks);
if (callbacks != null) {
callbacks.bindScreens(orderedScreens);
}
}
};
runOnMainThread(r, MAIN_THREAD_BINDING_RUNNABLE);
}
private void bindWorkspaceItems(final Callbacks oldCallbacks,
final ArrayList<ItemInfo> workspaceItems,
final ArrayList<LauncherAppWidgetInfo> appWidgets,
@@ -1830,11 +1967,13 @@ public class LauncherModel extends BroadcastReceiver {
new ArrayList<LauncherAppWidgetInfo>();
HashMap<Long, FolderInfo> folders = new HashMap<Long, FolderInfo>();
HashMap<Long, ItemInfo> itemsIdMap = new HashMap<Long, ItemInfo>();
ArrayList<Long> orderedScreenIds = new ArrayList<Long>();
synchronized (sBgLock) {
workspaceItems.addAll(sBgWorkspaceItems);
appWidgets.addAll(sBgAppWidgets);
folders.putAll(sBgFolders);
itemsIdMap.putAll(sBgItemsIdMap);
orderedScreenIds.addAll(sBgWorkspaceScreens);
}
ArrayList<ItemInfo> currentWorkspaceItems = new ArrayList<ItemInfo>();
@@ -1867,6 +2006,8 @@ public class LauncherModel extends BroadcastReceiver {
};
runOnMainThread(r, MAIN_THREAD_BINDING_RUNNABLE);
bindWorkspaceScreens(oldCallbacks, orderedScreenIds);
// Load items on the current page
bindWorkspaceItems(oldCallbacks, currentWorkspaceItems, currentAppWidgets,
currentFolders, null);
+101 -23
View File
@@ -66,12 +66,13 @@ public class LauncherProvider extends ContentProvider {
private static final String DATABASE_NAME = "launcher.db";
private static final int DATABASE_VERSION = 12;
private static final int DATABASE_VERSION = 13;
static final String OLD_AUTHORITY = "com.android.launcher2.settings";
static final String AUTHORITY = "com.android.launcher3.settings";
static final String TABLE_FAVORITES = "favorites";
static final String TABLE_WORKSPACE_SCREENS = "workspaceScreens";
static final String PARAMETER_NOTIFY = "notify";
static final String DB_CREATED_BUT_DEFAULT_WORKSPACE_NOT_LOADED =
"DB_CREATED_BUT_DEFAULT_WORKSPACE_NOT_LOADED";
@@ -90,6 +91,7 @@ public class LauncherProvider extends ContentProvider {
Uri.parse("content://" + AUTHORITY + "/appWidgetReset");
private DatabaseHelper mOpenHelper;
private static boolean sLoadOldDb;
@Override
public boolean onCreate() {
@@ -202,8 +204,18 @@ public class LauncherProvider extends ContentProvider {
}
}
public long generateNewId() {
return mOpenHelper.generateNewId();
public long generateNewItemId() {
return mOpenHelper.generateNewItemId();
}
public long generateNewScreenId() {
return mOpenHelper.generateNewScreenId();
}
// This is only required one time while loading the workspace during the
// upgrade path, and should never be called from anywhere else.
public void updateMaxScreenId(long maxScreenId) {
mOpenHelper.updateMaxScreenId(maxScreenId);
}
/**
@@ -213,7 +225,9 @@ public class LauncherProvider extends ContentProvider {
String spKey = LauncherAppState.getSharedPreferencesKey();
SharedPreferences sp = getContext().getSharedPreferences(spKey, Context.MODE_PRIVATE);
boolean loadOldDb = false;
boolean loadOldDb = false || sLoadOldDb;
sLoadOldDb = false;
if (sp.getBoolean(DB_CREATED_BUT_DEFAULT_WORKSPACE_NOT_LOADED, false)) {
SharedPreferences.Editor editor = sp.edit();
@@ -263,7 +277,8 @@ public class LauncherProvider extends ContentProvider {
private final Context mContext;
private final AppWidgetHost mAppWidgetHost;
private long mMaxId = -1;
private long mMaxItemId = -1;
private long mMaxScreenId = -1;
DatabaseHelper(Context context) {
super(context, DATABASE_NAME, null, DATABASE_VERSION);
@@ -272,8 +287,11 @@ public class LauncherProvider extends ContentProvider {
// In the case where neither onCreate nor onUpgrade gets called, we read the maxId from
// the DB here
if (mMaxId == -1) {
mMaxId = initializeMaxId(getWritableDatabase());
if (mMaxItemId == -1) {
mMaxItemId = initializeMaxItemId(getWritableDatabase());
}
if (mMaxScreenId == -1) {
mMaxScreenId = initializeMaxScreenId(getWritableDatabase());
}
}
@@ -292,7 +310,8 @@ public class LauncherProvider extends ContentProvider {
public void onCreate(SQLiteDatabase db) {
if (LOGD) Log.d(TAG, "creating new launcher database");
mMaxId = 1;
mMaxItemId = 1;
mMaxScreenId = 0;
db.execSQL("CREATE TABLE favorites (" +
"_id INTEGER PRIMARY KEY," +
@@ -314,6 +333,7 @@ public class LauncherProvider extends ContentProvider {
"uri TEXT," +
"displayMode INTEGER" +
");");
addWorkspacesTable(db);
// Database was just created, so wipe any previous widgets
if (mAppWidgetHost != null) {
@@ -327,6 +347,13 @@ public class LauncherProvider extends ContentProvider {
}
}
private void addWorkspacesTable(SQLiteDatabase db) {
db.execSQL("CREATE TABLE " + TABLE_WORKSPACE_SCREENS + " (" +
LauncherSettings.WorkspaceScreens._ID + " INTEGER," +
LauncherSettings.WorkspaceScreens.SCREEN_RANK + " INTEGER" +
");");
}
private void setFlagToLoadDefaultWorkspaceLater() {
String spKey = LauncherAppState.getSharedPreferencesKey();
SharedPreferences sp = mContext.getSharedPreferences(spKey, Context.MODE_PRIVATE);
@@ -504,8 +531,8 @@ public class LauncherProvider extends ContentProvider {
if (version < 9) {
// The max id is not yet set at this point (onUpgrade is triggered in the ctor
// before it gets a change to get set, so we need to read it here when we use it)
if (mMaxId == -1) {
mMaxId = initializeMaxId(db);
if (mMaxItemId == -1) {
mMaxItemId = initializeMaxItemId(db);
}
// Add default hotseat icons
@@ -524,9 +551,24 @@ public class LauncherProvider extends ContentProvider {
version = 12;
}
if (version < 13) {
// With the new shrink-wrapped and re-orderable workspaces, it makes sense
// to persist workspace screens and their relative order.
mMaxScreenId = 0;
// This will never happen in the wild, but when we switch to using workspace
// screen ids, redo the import from old launcher.
sLoadOldDb = true;
addWorkspacesTable(db);
version = 13;
}
if (version != DATABASE_VERSION) {
Log.w(TAG, "Destroying all old data.");
db.execSQL("DROP TABLE IF EXISTS " + TABLE_FAVORITES);
db.execSQL("DROP TABLE IF EXISTS " + TABLE_WORKSPACE_SCREENS);
onCreate(db);
}
}
@@ -672,15 +714,15 @@ public class LauncherProvider extends ContentProvider {
// constructor from the worker thread; however, this doesn't extend until after the
// constructor is called, and we only pass a reference to LauncherProvider to LauncherApp
// after that point
public long generateNewId() {
if (mMaxId < 0) {
throw new RuntimeException("Error: max id was not initialized");
public long generateNewItemId() {
if (mMaxItemId < 0) {
throw new RuntimeException("Error: max item id was not initialized");
}
mMaxId += 1;
return mMaxId;
mMaxItemId += 1;
return mMaxItemId;
}
private long initializeMaxId(SQLiteDatabase db) {
private long initializeMaxItemId(SQLiteDatabase db) {
Cursor c = db.rawQuery("SELECT MAX(_id) FROM favorites", null);
// get the result
@@ -694,7 +736,44 @@ public class LauncherProvider extends ContentProvider {
}
if (id == -1) {
throw new RuntimeException("Error: could not query max id");
throw new RuntimeException("Error: could not query max item id");
}
return id;
}
// Generates a new ID to use for an workspace screen in your database. This method
// should be only called from the main UI thread. As an exception, we do call it when we
// call the constructor from the worker thread; however, this doesn't extend until after the
// constructor is called, and we only pass a reference to LauncherProvider to LauncherApp
// after that point
public long generateNewScreenId() {
if (mMaxScreenId < 0) {
throw new RuntimeException("Error: max screen id was not initialized");
}
mMaxScreenId += 1;
return mMaxScreenId;
}
public void updateMaxScreenId(long maxScreenId) {
mMaxScreenId = maxScreenId;
}
private long initializeMaxScreenId(SQLiteDatabase db) {
Cursor c = db.rawQuery("SELECT MAX(" + LauncherSettings.WorkspaceScreens._ID + ") FROM " + TABLE_WORKSPACE_SCREENS, null);
// get the result
final int maxIdIndex = 0;
long id = -1;
if (c != null && c.moveToNext()) {
id = c.getLong(maxIdIndex);
}
if (c != null) {
c.close();
}
if (id == -1) {
throw new RuntimeException("Error: could not query max screen id");
}
return id;
@@ -959,7 +1038,7 @@ public class LauncherProvider extends ContentProvider {
cn = new ComponentName(packages[0], className);
info = packageManager.getActivityInfo(cn, 0);
}
id = generateNewId();
id = generateNewItemId();
intent.setComponent(cn);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK |
Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED);
@@ -968,7 +1047,7 @@ public class LauncherProvider extends ContentProvider {
values.put(Favorites.ITEM_TYPE, Favorites.ITEM_TYPE_APPLICATION);
values.put(Favorites.SPANX, 1);
values.put(Favorites.SPANY, 1);
values.put(Favorites._ID, generateNewId());
values.put(Favorites._ID, generateNewItemId());
if (dbInsertAndCheck(this, db, TABLE_FAVORITES, null, values) < 0) {
return -1;
}
@@ -983,7 +1062,7 @@ public class LauncherProvider extends ContentProvider {
values.put(Favorites.ITEM_TYPE, Favorites.ITEM_TYPE_FOLDER);
values.put(Favorites.SPANX, 1);
values.put(Favorites.SPANY, 1);
long id = generateNewId();
long id = generateNewItemId();
values.put(Favorites._ID, id);
if (dbInsertAndCheck(this, db, TABLE_FAVORITES, null, values) <= 0) {
return -1;
@@ -1088,7 +1167,6 @@ public class LauncherProvider extends ContentProvider {
return false;
}
private boolean addAppWidget(SQLiteDatabase db, ContentValues values, ComponentName cn,
int spanX, int spanY, Bundle extras) {
boolean allocatedAppWidgets = false;
@@ -1101,7 +1179,7 @@ public class LauncherProvider extends ContentProvider {
values.put(Favorites.SPANX, spanX);
values.put(Favorites.SPANY, spanY);
values.put(Favorites.APPWIDGET_ID, appWidgetId);
values.put(Favorites._ID, generateNewId());
values.put(Favorites._ID, generateNewItemId());
dbInsertAndCheck(this, db, TABLE_FAVORITES, null, values);
allocatedAppWidgets = true;
@@ -1146,7 +1224,7 @@ public class LauncherProvider extends ContentProvider {
return -1;
}
long id = generateNewId();
long id = generateNewItemId();
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
values.put(Favorites.INTENT, intent.toUri(0));
values.put(Favorites.TITLE, r.getString(titleResId));
@@ -90,6 +90,26 @@ class LauncherSettings {
static final String ICON = "icon";
}
/**
* Workspace Screens.
*
* Tracks the order of workspace screens.
*/
static final class WorkspaceScreens implements BaseColumns {
/**
* The content:// style URL for this table
*/
static final Uri CONTENT_URI = Uri.parse("content://" +
LauncherProvider.AUTHORITY + "/" + LauncherProvider.TABLE_WORKSPACE_SCREENS +
"?" + LauncherProvider.PARAMETER_NOTIFY + "=true");
/**
* The rank of this screen -- ie. how it is ordered relative to the other screens.
* <P>Type: INTEGER</P>
*/
static final String SCREEN_RANK = "screenRank";
}
/**
* Favorites.
*/
+2 -2
View File
@@ -491,7 +491,7 @@ public abstract class PagedView extends ViewGroup implements ViewGroup.OnHierarc
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
if (!mIsDataReady) {
if (!mIsDataReady || getChildCount() == 0) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
return;
}
@@ -650,7 +650,7 @@ public abstract class PagedView extends ViewGroup implements ViewGroup.OnHierarc
@Override
protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
if (!mIsDataReady) {
if (!mIsDataReady || getChildCount() == 0) {
return;
}
+1 -1
View File
@@ -145,7 +145,7 @@ class ShortcutInfo extends ItemInfo {
@Override
public String toString() {
return "ShortcutInfo(title=" + title.toString() + "intent=" + intent + "id=" + this.id
+ " type=" + this.itemType + " container=" + this.container + " screen=" + screen
+ " type=" + this.itemType + " container=" + this.container + " screen=" + screenId
+ " cellX=" + cellX + " cellY=" + cellY + " spanX=" + spanX + " spanY=" + spanY
+ " dropPos=" + dropPos + ")";
}
+198 -78
View File
@@ -60,6 +60,7 @@ import com.android.launcher3.LauncherSettings.Favorites;
import java.net.URISyntaxException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
@@ -105,9 +106,15 @@ public class Workspace extends SmoothPagedView
private IBinder mWindowToken;
private static final float WALLPAPER_SCREENS_SPAN = 2f;
public int mNumPagesToLeft = 0;
private int mDefaultPage;
// The screen id used for the empty screen always present to the right.
private final static long EXTRA_EMPTY_SCREEN_ID = -201;
private final static long CUSTOM_CONTENT_SCREEN_ID = -301;
private HashMap<Long, CellLayout> mWorkspaceScreens = new HashMap<Long, CellLayout>();
private ArrayList<Long> mScreenOrder = new ArrayList<Long>();
/**
* CellInfo for the cell that is currently being dragged
*/
@@ -254,6 +261,7 @@ public class Workspace extends SmoothPagedView
private float[] mNewBackgroundAlphas;
private float[] mNewAlphas;
private float[] mNewRotationYs;
private int mLastChildCount = -1;
private float mTransitionProgress;
private final Runnable mBindPages = new Runnable() {
@@ -375,6 +383,7 @@ public class Workspace extends SmoothPagedView
return size;
}
}
public Rect estimateItemPosition(CellLayout cl, ItemInfo pendingInfo,
int hCell, int vCell, int hSpan, int vSpan) {
Rect r = new Rect();
@@ -402,13 +411,6 @@ public class Workspace extends SmoothPagedView
UninstallShortcutReceiver.disableAndFlushUninstallQueue(getContext());
}
// Just a hack so that if a custom content screen is added to the left, we adjust the
// default screen accordingly so that it stays the same.
void incrementNumScreensToLeft() {
mDefaultPage++;
mNumPagesToLeft++;
}
/**
* Initializes various states for this workspace.
*/
@@ -489,19 +491,131 @@ public class Workspace extends SmoothPagedView
return mTouchState != TOUCH_STATE_REST;
}
/**
* Adds the specified child in the specified screen. The position and dimension of
* the child are defined by x, y, spanX and spanY.
*
* @param child The child to add in one of the workspace's screens.
* @param screen The screen in which to add the child.
* @param x The X position of the child in the screen's grid.
* @param y The Y position of the child in the screen's grid.
* @param spanX The number of cells spanned horizontally by the child.
* @param spanY The number of cells spanned vertically by the child.
*/
void addInScreen(View child, long container, int screen, int x, int y, int spanX, int spanY) {
addInScreen(child, container, screen, x, y, spanX, spanY, false);
public long insertNewWorkspaceScreen(long screenId) {
return insertNewWorkspaceScreen(screenId, true);
}
public long insertNewWorkspaceScreenOnBind(long screenId) {
return insertNewWorkspaceScreen(screenId, false);
}
// If screen id is -1, this indicates there is no screen assigned, so we generate
// a new screen id.
public long insertNewWorkspaceScreen(long screenId, boolean updateDb) {
CellLayout newScreen = (CellLayout)
mLauncher.getLayoutInflater().inflate(R.layout.workspace_screen, null);
addView(newScreen, getChildCount());
mWorkspaceScreens.put(screenId, newScreen);
mScreenOrder.add(screenId);
if (updateDb) {
// On bind we don't need to update the screens in the database.
LauncherModel.updateWorkspaceScreenOrder(mLauncher, mScreenOrder);
}
return screenId;
}
public void addCustomContentToLeft(View customContent) {
CellLayout customScreen = (CellLayout)
mLauncher.getLayoutInflater().inflate(R.layout.workspace_custom_content, null);
int spanX = customScreen.getCountX();
int spanY = customScreen.getCountY();
CellLayout.LayoutParams lp = new CellLayout.LayoutParams(0, 0, spanX, spanY);
lp.canReorder = false;
customScreen.addViewToCellLayout(customContent, 0, 0, lp, true);
addView(customScreen, 0);
mWorkspaceScreens.put(CUSTOM_CONTENT_SCREEN_ID, customScreen);
mScreenOrder.add(0, CUSTOM_CONTENT_SCREEN_ID);
// Ensure that the current page and default page are maintained.
mDefaultPage++;
setCurrentPage(getCurrentPage() + 1);
}
public long commitExtraEmptyScreen() {
CellLayout cl = mWorkspaceScreens.get(EXTRA_EMPTY_SCREEN_ID);
mScreenOrder.remove(EXTRA_EMPTY_SCREEN_ID);
long newId = LauncherAppState.getInstance().getLauncherProvider().generateNewScreenId();
mWorkspaceScreens.put(newId, cl);
mScreenOrder.add(newId);
addExtraEmptyScreen();
return newId;
}
public void addExtraEmptyScreen() {
insertNewWorkspaceScreen(EXTRA_EMPTY_SCREEN_ID, false);
}
public CellLayout getScreenWithId(long screenId) {
CellLayout layout = mWorkspaceScreens.get(screenId);
return layout;
}
public long getIdForScreen(CellLayout layout) {
Iterator<Long> iter = mWorkspaceScreens.keySet().iterator();
while (iter.hasNext()) {
long id = iter.next();
if (mWorkspaceScreens.get(id) == layout) {
return id;
}
}
return -1;
}
public int getPageIndexForScreenId(long screenId) {
return indexOfChild(mWorkspaceScreens.get(screenId));
}
public long getScreenIdForPageIndex(int index) {
return mScreenOrder.get(index);
}
public void stripEmptyScreens() {
ArrayList<Long> removeScreens = new ArrayList<Long>();
for (Long id: mWorkspaceScreens.keySet()) {
CellLayout cl = mWorkspaceScreens.get(id);
if (id != EXTRA_EMPTY_SCREEN_ID && cl.getShortcutsAndWidgets().getChildCount() == 0) {
removeScreens.add(id);
}
}
int pageShift = 0;
for (Long id: removeScreens) {
CellLayout cl = mWorkspaceScreens.get(id);
mWorkspaceScreens.remove(id);
mScreenOrder.remove(id);
if (indexOfChild(cl) < mCurrentPage) {
pageShift++;
}
removeView(cl);
}
setCurrentPage(mCurrentPage - pageShift);
}
// See implementation for parameter definition.
void addInScreen(View child, long container, long screenId,
int x, int y, int spanX, int spanY) {
addInScreen(child, container, screenId, x, y, spanX, spanY, false, false);
}
// At bind time, we use the rank (screenId) to compute x and y for hotseat items.
// See implementation for parameter definition.
void addInScreenFromBind(View child, long container, long screenId, int x, int y,
int spanX, int spanY) {
addInScreen(child, container, screenId, x, y, spanX, spanY, false, true);
}
// See implementation for parameter definition.
void addInScreen(View child, long container, long screenId, int x, int y, int spanX, int spanY,
boolean insert) {
addInScreen(child, container, screenId, x, y, spanX, spanY, insert, false);
}
/**
@@ -509,23 +623,30 @@ public class Workspace extends SmoothPagedView
* the child are defined by x, y, spanX and spanY.
*
* @param child The child to add in one of the workspace's screens.
* @param screen The screen in which to add the child.
* @param screenId The screen in which to add the child.
* @param x The X position of the child in the screen's grid.
* @param y The Y position of the child in the screen's grid.
* @param spanX The number of cells spanned horizontally by the child.
* @param spanY The number of cells spanned vertically by the child.
* @param insert When true, the child is inserted at the beginning of the children list.
* @param computeXYFromRank When true, we use the rank (stored in screenId) to compute
* the x and y position in which to place hotseat items. Otherwise
* we use the x and y position to compute the rank.
*/
void addInScreen(View child, long container, int screen, int x, int y, int spanX, int spanY,
boolean insert) {
void addInScreen(View child, long container, long screenId, int x, int y, int spanX, int spanY,
boolean insert, boolean computeXYFromRank) {
if (container == LauncherSettings.Favorites.CONTAINER_DESKTOP) {
if (screen < 0 || screen >= getChildCount()) {
Log.e(TAG, "The screen must be >= 0 and < " + getChildCount()
+ " (was " + screen + "); skipping child");
if (getScreenWithId(screenId) == null) {
Log.e(TAG, "Skipping child, screenId " + screenId + " not found");
return;
}
}
// If an item is added to the extra empty screen, we convert it to a real
if (screenId == EXTRA_EMPTY_SCREEN_ID) {
screenId = commitExtraEmptyScreen();
}
final CellLayout layout;
if (container == LauncherSettings.Favorites.CONTAINER_HOTSEAT) {
layout = mLauncher.getHotseat().getLayout();
@@ -536,21 +657,18 @@ public class Workspace extends SmoothPagedView
((FolderIcon) child).setTextVisible(false);
}
if (screen < 0) {
screen = mLauncher.getHotseat().getOrderInHotseat(x, y);
if (computeXYFromRank) {
x = mLauncher.getHotseat().getCellXFromOrder((int) screenId);
y = mLauncher.getHotseat().getCellYFromOrder((int) screenId);
} else {
// Note: We do this to ensure that the hotseat is always laid out in the orientation
// of the hotseat in order regardless of which orientation they were added
x = mLauncher.getHotseat().getCellXFromOrder(screen);
y = mLauncher.getHotseat().getCellYFromOrder(screen);
screenId = mLauncher.getHotseat().getOrderInHotseat(x, y);
}
} else {
// Show folder title if not in the hotseat
if (child instanceof FolderIcon) {
((FolderIcon) child).setTextVisible(true);
}
layout = (CellLayout) getChildAt(screen);
layout = getScreenWithId(screenId);
child.setOnKeyListener(new IconKeyEventListener());
}
@@ -571,7 +689,7 @@ public class Workspace extends SmoothPagedView
}
// Get the canonical child id to uniquely represent this view in this screen
int childId = LauncherModel.getCellLayoutChildId(container, screen, x, y, spanX, spanY);
int childId = LauncherModel.getCellLayoutChildId(container, screenId, x, y, spanX, spanY);
boolean markCellsAsOccupied = !(child instanceof Folder);
if (!layout.addViewToCellLayout(child, insert ? 0 : -1, childId, lp, markCellsAsOccupied)) {
// TODO: This branch occurs when the workspace is adding views
@@ -912,7 +1030,8 @@ public class Workspace extends SmoothPagedView
private void syncWallpaperOffsetWithScroll() {
final boolean enableWallpaperEffects = isHardwareAccelerated();
if (enableWallpaperEffects) {
mWallpaperOffset.setFinalX(wallpaperOffsetForCurrentScroll());
// TODO: figure out what to do about parallax, for now disable it
//mWallpaperOffset.setFinalX(wallpaperOffsetForCurrentScroll());
}
}
@@ -968,6 +1087,10 @@ public class Workspace extends SmoothPagedView
snapToPage(whichPage, SLOW_PAGE_SNAP_ANIMATION_DURATION);
}
protected void snapToScreenId(long screenId, Runnable r) {
snapToPage(getPageIndexForScreenId(screenId), r);
}
private void computeWallpaperScrollRatio(int page) {
// Here, we determine what the desired scroll would be with and without a layout scale,
// and compute a ratio between the two. This allows us to adjust the wallpaper offset
@@ -1558,7 +1681,7 @@ public class Workspace extends SmoothPagedView
private void initAnimationArrays() {
final int childCount = getChildCount();
if (mOldTranslationXs != null) return;
if (mLastChildCount == childCount) return;
mOldTranslationXs = new float[childCount];
mOldTranslationYs = new float[childCount];
mOldScaleXs = new float[childCount];
@@ -1958,16 +2081,15 @@ public class Workspace extends SmoothPagedView
showScrollingIndicator(false);
}
void addApplicationShortcut(ShortcutInfo info, CellLayout target, long container, int screen,
void addApplicationShortcut(ShortcutInfo info, CellLayout target, long container, long screenId,
int cellX, int cellY, boolean insertAtFirst, int intersectX, int intersectY) {
View view = mLauncher.createShortcut(R.layout.application, target, (ShortcutInfo) info);
final int[] cellXY = new int[2];
target.findCellForSpanThatIntersects(cellXY, 1, 1, intersectX, intersectY);
addInScreen(view, container, screen, cellXY[0], cellXY[1], 1, 1, insertAtFirst);
addInScreen(view, container, screenId, cellXY[0], cellXY[1], 1, 1, insertAtFirst);
int adjustedScreen = screen - mNumPagesToLeft;
LauncherModel.addOrMoveItemInDatabase(mLauncher, info, container, adjustedScreen, cellXY[0],
LauncherModel.addOrMoveItemInDatabase(mLauncher, info, container, screenId, cellXY[0],
cellXY[1]);
}
@@ -2122,7 +2244,7 @@ public class Workspace extends SmoothPagedView
if (v == null || hasntMoved || !mCreateUserFolderOnDrop) return false;
mCreateUserFolderOnDrop = false;
final int screen = (targetCell == null) ? mDragInfo.screen : indexOfChild(target);
final long screenId = (targetCell == null) ? mDragInfo.screenId : getIdForScreen(target);
boolean aboveShortcut = (v.getTag() instanceof ShortcutInfo);
boolean willBecomeShortcut = (newView.getTag() instanceof ShortcutInfo);
@@ -2140,7 +2262,7 @@ public class Workspace extends SmoothPagedView
target.removeView(v);
FolderIcon fi =
mLauncher.addFolder(target, container, screen, targetCell[0], targetCell[1]);
mLauncher.addFolder(target, container, screenId, targetCell[0], targetCell[1]);
destInfo.cellX = -1;
destInfo.cellY = -1;
sourceInfo.cellX = -1;
@@ -2215,8 +2337,8 @@ public class Workspace extends SmoothPagedView
long container = hasMovedIntoHotseat ?
LauncherSettings.Favorites.CONTAINER_HOTSEAT :
LauncherSettings.Favorites.CONTAINER_DESKTOP;
int screen = (mTargetCell[0] < 0) ?
mDragInfo.screen : indexOfChild(dropTargetLayout);
long screenId = (mTargetCell[0] < 0) ?
mDragInfo.screenId : getIdForScreen(dropTargetLayout);
int spanX = mDragInfo != null ? mDragInfo.spanX : 1;
int spanY = mDragInfo != null ? mDragInfo.spanY : 1;
// First we find the cell nearest to point at which the item is
@@ -2267,9 +2389,9 @@ public class Workspace extends SmoothPagedView
resultSpan[1]);
}
if (mCurrentPage != screen && !hasMovedIntoHotseat) {
snapScreen = screen;
snapToPage(screen);
if (getScreenIdForPageIndex(mCurrentPage) != screenId && !hasMovedIntoHotseat) {
snapScreen = getPageIndexForScreenId(screenId);
snapToPage(snapScreen);
}
if (foundCell) {
@@ -2277,7 +2399,7 @@ public class Workspace extends SmoothPagedView
if (hasMovedLayouts) {
// Reparent the view
getParentCellLayoutForView(cell).removeView(cell);
addInScreen(cell, container, screen, mTargetCell[0], mTargetCell[1],
addInScreen(cell, container, screenId, mTargetCell[0], mTargetCell[1],
info.spanX, info.spanY);
}
@@ -2288,7 +2410,7 @@ public class Workspace extends SmoothPagedView
lp.cellHSpan = item.spanX;
lp.cellVSpan = item.spanY;
lp.isLockedToGrid = true;
cell.setId(LauncherModel.getCellLayoutChildId(container, mDragInfo.screen,
cell.setId(LauncherModel.getCellLayoutChildId(container, mDragInfo.screenId,
mTargetCell[0], mTargetCell[1], mDragInfo.spanX, mDragInfo.spanY));
if (container != LauncherSettings.Favorites.CONTAINER_HOTSEAT &&
@@ -2319,10 +2441,7 @@ public class Workspace extends SmoothPagedView
}
}
//TODO: This is a hack on top of a hack, but items aren't being saved
// to the correct screen due to the extra screen.
int adjustedScreen = screen - mNumPagesToLeft;
LauncherModel.moveItemInDatabase(mLauncher, info, container, adjustedScreen, lp.cellX,
LauncherModel.moveItemInDatabase(mLauncher, info, container, screenId, lp.cellX,
lp.cellY);
} else {
// If we can't find a drop location, we return the item to its original position
@@ -2369,22 +2488,22 @@ public class Workspace extends SmoothPagedView
}
}
public void setFinalScrollForPageChange(int screen) {
if (screen >= 0) {
public void setFinalScrollForPageChange(int pageIndex) {
CellLayout cl = (CellLayout) getChildAt(pageIndex);
if (cl != null) {
mSavedScrollX = getScrollX();
CellLayout cl = (CellLayout) getChildAt(screen);
mSavedTranslationX = cl.getTranslationX();
mSavedRotationY = cl.getRotationY();
final int newX = getChildOffset(screen) - getRelativeChildOffset(screen);
final int newX = getChildOffset(pageIndex) - getRelativeChildOffset(pageIndex);
setScrollX(newX);
cl.setTranslationX(0f);
cl.setRotationY(0f);
}
}
public void resetFinalScrollForPageChange(int screen) {
if (screen >= 0) {
CellLayout cl = (CellLayout) getChildAt(screen);
public void resetFinalScrollForPageChange(int pageIndex) {
if (pageIndex >= 0) {
CellLayout cl = (CellLayout) getChildAt(pageIndex);
setScrollX(mSavedScrollX);
cl.setTranslationX(mSavedTranslationX);
cl.setRotationY(mSavedRotationY);
@@ -3047,10 +3166,11 @@ public class Workspace extends SmoothPagedView
final long container = mLauncher.isHotseatLayout(cellLayout) ?
LauncherSettings.Favorites.CONTAINER_HOTSEAT :
LauncherSettings.Favorites.CONTAINER_DESKTOP;
final int screen = indexOfChild(cellLayout);
if (!mLauncher.isHotseatLayout(cellLayout) && screen != mCurrentPage
final long screenId = getIdForScreen(cellLayout);
if (!mLauncher.isHotseatLayout(cellLayout)
&& screenId != getScreenIdForPageIndex(mCurrentPage)
&& mState != State.SPRING_LOADED) {
snapToPage(screen);
snapToScreenId(screenId, null);
}
if (info instanceof PendingAddItemInfo) {
@@ -3101,11 +3221,11 @@ public class Workspace extends SmoothPagedView
span[0] = item.spanX;
span[1] = item.spanY;
mLauncher.addAppWidgetFromDrop((PendingAddWidgetInfo) pendingInfo,
container, screen, mTargetCell, span, null);
container, screenId, mTargetCell, span, null);
break;
case LauncherSettings.Favorites.ITEM_TYPE_SHORTCUT:
mLauncher.processShortcutFromDrop(pendingInfo.componentName,
container, screen, mTargetCell, null);
container, screenId, mTargetCell, null);
break;
default:
throw new IllegalStateException("Unknown item type: " +
@@ -3177,14 +3297,13 @@ public class Workspace extends SmoothPagedView
} else {
cellLayout.findCellForSpan(mTargetCell, 1, 1);
}
addInScreen(view, container, screen, mTargetCell[0], mTargetCell[1], info.spanX,
addInScreen(view, container, screenId, mTargetCell[0], mTargetCell[1], info.spanX,
info.spanY, insertAtFirst);
cellLayout.onDropChild(view);
CellLayout.LayoutParams lp = (CellLayout.LayoutParams) view.getLayoutParams();
cellLayout.getShortcutsAndWidgets().measureChild(view);
int adjustedScreen = screen - mNumPagesToLeft;
LauncherModel.addOrMoveItemInDatabase(mLauncher, info, container, adjustedScreen,
LauncherModel.addOrMoveItemInDatabase(mLauncher, info, container, screenId,
lp.cellX, lp.cellY);
if (d.dragView != null) {
@@ -3400,7 +3519,7 @@ public class Workspace extends SmoothPagedView
if (mLauncher.isHotseatLayout(target)) {
cellLayout = mLauncher.getHotseat().getLayout();
} else {
cellLayout = (CellLayout) getChildAt(mDragInfo.screen);
cellLayout = getScreenWithId(mDragInfo.screenId);
}
cellLayout.onDropChild(mDragInfo.cell);
}
@@ -3410,6 +3529,8 @@ public class Workspace extends SmoothPagedView
mDragOutline = null;
mDragInfo = null;
stripEmptyScreens();
// Hide the scrolling indicator after you pick up an item
hideScrollingIndicator(false);
}
@@ -3417,11 +3538,11 @@ public class Workspace extends SmoothPagedView
void updateItemLocationsInDatabase(CellLayout cl) {
int count = cl.getShortcutsAndWidgets().getChildCount();
int screen = indexOfChild(cl);
long screenId = getIdForScreen(cl);
int container = Favorites.CONTAINER_DESKTOP;
if (mLauncher.isHotseatLayout(cl)) {
screen = -1;
screenId = -1;
container = Favorites.CONTAINER_HOTSEAT;
}
@@ -3431,8 +3552,7 @@ public class Workspace extends SmoothPagedView
// Null check required as the AllApps button doesn't have an item info
if (info != null && info.requiresDbUpdate) {
info.requiresDbUpdate = false;
int adjustedScreen = screen - mNumPagesToLeft;
LauncherModel.modifyItemInDatabase(mLauncher, info, container, adjustedScreen, info.cellX,
LauncherModel.modifyItemInDatabase(mLauncher, info, container, screenId, info.cellX,
info.cellY, info.spanX, info.spanY);
}
}
@@ -3512,11 +3632,11 @@ public class Workspace extends SmoothPagedView
void saveWorkspaceScreenToDb(CellLayout cl) {
int count = cl.getShortcutsAndWidgets().getChildCount();
int screen = indexOfChild(cl);
long screenId = getIdForScreen(cl);
int container = Favorites.CONTAINER_DESKTOP;
if (mLauncher.isHotseatLayout(cl)) {
screen = -1;
screenId = -1;
container = Favorites.CONTAINER_HOTSEAT;
}
@@ -3525,7 +3645,7 @@ public class Workspace extends SmoothPagedView
ItemInfo info = (ItemInfo) v.getTag();
// Null check required as the AllApps button doesn't have an item info
if (info != null) {
LauncherModel.addItemToDatabase(mLauncher, info, container, screen, info.cellX,
LauncherModel.addItemToDatabase(mLauncher, info, container, screenId, info.cellX,
info.cellY, false);
}
if (v instanceof FolderIcon) {