Merge "Adding accessibility controls" into ub-launcher3-almonte

This commit is contained in:
Sunny Goyal
2015-01-17 01:58:01 +00:00
committed by Android (Google) Code Review
18 changed files with 499 additions and 364 deletions
+1 -1
View File
@@ -38,7 +38,7 @@
android:id="@+id/delete_target_text"
style="@style/DropTargetButton"
android:drawableStart="@drawable/remove_target_selector"
android:text="@string/delete_zone_label_workspace" />
android:text="@string/delete_target_label" />
</FrameLayout>
<FrameLayout
-4
View File
@@ -4,8 +4,4 @@
<!-- DragController -->
<integer name="config_flingToDeleteMinVelocity">-1000</integer>
<!-- Camera distance for the overscroll effect. We use a higher value here because the
workspace screens run nearly flush to the edge of the screen-->
<integer name="config_cameraDistance">14000</integer>
</resources>
-3
View File
@@ -10,9 +10,6 @@
<!-- Whether or not the drop targets drop down as opposed to fade in -->
<bool name="config_useDropTargetDownTransition">false</bool>
<!-- Camera distance for the overscroll effect -->
<integer name="config_cameraDistance">18000</integer>
<!-- Hotseat -->
<bool name="hotseat_transpose_layout_with_orientation">false</bool>
</resources>
+6 -8
View File
@@ -36,11 +36,6 @@
<!-- Fade/zoom in/out duration & scale in the AllApps transition.
Note: This should be less than the workspaceShrinkTime as they happen together. -->
<integer name="config_appsCustomizeRevealTime">220</integer>
<integer name="config_appsCustomizeZoomInTime">350</integer>
<integer name="config_appsCustomizeZoomOutTime">600</integer>
<integer name="config_appsCustomizeZoomScaleFactor">7</integer>
<integer name="config_appsCustomizeFadeInTime">250</integer>
<integer name="config_appsCustomizeFadeOutTime">200</integer>
<integer name="config_appsCustomizeWorkspaceShrinkTime">300</integer>
<integer name="config_appsCustomizeConcealTime">250</integer>
@@ -90,9 +85,6 @@
<integer name="config_dragFadeOutAlpha">80</integer>
<integer name="config_dragFadeOutDuration">250</integer>
<!-- Camera distance for the overscroll effect -->
<integer name="config_cameraDistance">8000</integer>
<!-- Hotseat -->
<bool name="hotseat_transpose_layout_with_orientation">true</bool>
@@ -106,4 +98,10 @@
<!-- Name of a subclass of com.android.launcher3.BuildInfo used to
get build information. Can be empty. -->
<string name="build_info_class" translatable="false"></string>
<!-- Accessibility actions -->
<item type="id" name="action_remove" />
<item type="id" name="action_uninstall" />
<item type="id" name="action_info" />
<item type="id" name="action_add_to_workspace" />
</resources>
+4 -3
View File
@@ -118,9 +118,6 @@ s -->
<!-- Label for button in all applications label to go back home (to the workspace / desktop)
for accessibilty (spoken when the button gets focus). -->
<string name="all_apps_home_button_label">Home</string>
<!-- Label for trash icon on workspace. Meant to communicate the idea of removing the
icon/widget from the home screen, but not permanently. [CHAR_LIMIT=30] -->
<string name="delete_zone_label_workspace">Remove</string>
<!-- Label for trash icon in All Apps. The icon/widget will become completely unavailable on the
device. [CHAR_LIMIT=30]-->
<string name="delete_zone_label_all_apps">Uninstall</string>
@@ -304,4 +301,8 @@ s -->
<string name="abandoned_promise_explanation">The app for this icon isn\'t installed.
You can remove it, or search for the app and install it manually.
</string>
<!-- Strings for accessibility actions -->
<!-- Accessibility action to add an app to workspace. [CHAR_LIMIT=30] -->
<string name="action_add_to_workspace">Add To Workspace</string>
</resources>
+18 -18
View File
@@ -49,7 +49,15 @@ public class BubbleTextView extends TextView {
private static final int SHADOW_SMALL_COLOUR = 0xCC000000;
static final float PADDING_V = 3.0f;
private HolographicOutlineHelper mOutlineHelper;
private final Drawable mBackground;
private final CheckLongPressHelper mLongPressHelper;
private final HolographicOutlineHelper mOutlineHelper;
// TODO: Remove custom background handling code, as no instance of BubbleTextView use any
// background.
private boolean mBackgroundSizeChanged;
private Bitmap mPressedBackground;
private float mSlop;
@@ -58,14 +66,8 @@ public class BubbleTextView extends TextView {
private final boolean mCustomShadowsEnabled;
private boolean mIsTextVisible;
// TODO: Remove custom background handling code, as no instance of BubbleTextView use any
// background.
private boolean mBackgroundSizeChanged;
private final Drawable mBackground;
private boolean mStayPressed;
private boolean mIgnorePressedStateChange;
private CheckLongPressHelper mLongPressHelper;
public BubbleTextView(Context context) {
this(context, null, 0);
@@ -90,7 +92,14 @@ public class BubbleTextView extends TextView {
} else {
mBackground = null;
}
init();
mLongPressHelper = new CheckLongPressHelper(this);
mOutlineHelper = HolographicOutlineHelper.obtain(getContext());
if (mCustomShadowsEnabled) {
setShadowLayer(SHADOW_LARGE_RADIUS, 0.0f, SHADOW_Y_OFFSET, SHADOW_LARGE_COLOUR);
}
setAccessibilityDelegate(LauncherAppState.getInstance().getAccessibilityDelegate());
}
public void onFinishInflate() {
@@ -102,15 +111,6 @@ public class BubbleTextView extends TextView {
setTextSize(TypedValue.COMPLEX_UNIT_PX, grid.iconTextSizePx);
}
private void init() {
mLongPressHelper = new CheckLongPressHelper(this);
mOutlineHelper = HolographicOutlineHelper.obtain(getContext());
if (mCustomShadowsEnabled) {
setShadowLayer(SHADOW_LARGE_RADIUS, 0.0f, SHADOW_Y_OFFSET, SHADOW_LARGE_COLOUR);
}
}
public void applyFromShortcutInfo(ShortcutInfo info, IconCache iconCache,
boolean setDefaultPadding) {
applyFromShortcutInfo(info, iconCache, setDefaultPadding, false);
@@ -328,7 +328,7 @@ public class BubbleTextView extends TextView {
Drawable top = getCompoundDrawables()[1];
if (top instanceof PreloadIconDrawable) {
((PreloadIconDrawable) top).applyTheme(getPreloaderTheme());
((PreloadIconDrawable) top).applyPreloaderTheme(getPreloaderTheme());
}
mSlop = ViewConfiguration.get(getContext()).getScaledTouchSlop();
}
+4 -4
View File
@@ -2981,11 +2981,11 @@ public class CellLayout extends ViewGroup {
static boolean findVacantCell(int[] vacant, int spanX, int spanY,
int xCount, int yCount, boolean[][] occupied) {
for (int y = 0; y < yCount; y++) {
for (int x = 0; x < xCount; x++) {
for (int y = 0; (y + spanY) <= yCount; y++) {
for (int x = 0; (x + spanX) <= xCount; x++) {
boolean available = !occupied[x][y];
out: for (int i = x; i < x + spanX - 1 && x < xCount; i++) {
for (int j = y; j < y + spanY - 1 && y < yCount; j++) {
out: for (int i = x; i < x + spanX; i++) {
for (int j = y; j < y + spanY; j++) {
available = available && !occupied[i][j];
if (!available) break out;
}
+53 -40
View File
@@ -19,6 +19,7 @@ package com.android.launcher3;
import android.animation.TimeInterpolator;
import android.animation.ValueAnimator;
import android.animation.ValueAnimator.AnimatorUpdateListener;
import android.annotation.TargetApi;
import android.content.ComponentName;
import android.content.Context;
import android.content.res.ColorStateList;
@@ -115,15 +116,6 @@ public class DeleteDropTarget extends ButtonDropTarget {
private boolean isDragSourceWorkspaceOrFolder(DragObject d) {
return (d.dragSource instanceof Workspace) || (d.dragSource instanceof Folder);
}
private boolean isWorkspaceOrFolderApplication(DragObject d) {
return isDragSourceWorkspaceOrFolder(d) && (d.dragInfo instanceof ShortcutInfo);
}
private boolean isWorkspaceOrFolderWidget(DragObject d) {
return isDragSourceWorkspaceOrFolder(d) && (d.dragInfo instanceof LauncherAppWidgetInfo);
}
private boolean isWorkspaceFolder(DragObject d) {
return (d.dragSource instanceof Workspace) && (d.dragInfo instanceof FolderInfo);
}
private void setHoverColor() {
if (mCurrentDrawable != null) {
@@ -177,6 +169,7 @@ public class DeleteDropTarget extends ButtonDropTarget {
return false;
}
@TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR2)
@Override
public void onDragStart(DragSource source, Object info, int dragAction) {
boolean isVisible = true;
@@ -284,7 +277,8 @@ public class DeleteDropTarget extends ButtonDropTarget {
}
private boolean isUninstallFromWorkspace(DragObject d) {
if (LauncherAppState.isDisableAllApps() && isWorkspaceOrFolderApplication(d)) {
if (LauncherAppState.isDisableAllApps() && isDragSourceWorkspaceOrFolder(d)
&& (d.dragInfo instanceof ShortcutInfo)) {
ShortcutInfo shortcut = (ShortcutInfo) d.dragInfo;
// Only allow manifest shortcuts to initiate an un-install.
return !InstallShortcutReceiver.isValidShortcutLaunchIntent(shortcut.intent);
@@ -297,10 +291,7 @@ public class DeleteDropTarget extends ButtonDropTarget {
boolean wasWaitingForUninstall = mWaitingForUninstall;
mWaitingForUninstall = false;
if (isAllAppsApplication(d.dragSource, item)) {
// Uninstall the application if it is being dragged from AppsCustomize
AppInfo appInfo = (AppInfo) item;
mLauncher.startApplicationUninstallActivity(appInfo.componentName, appInfo.flags,
appInfo.user);
uninstallApp(mLauncher, (AppInfo) item);
} else if (isUninstallFromWorkspace(d)) {
ShortcutInfo shortcut = (ShortcutInfo) item;
if (shortcut.intent != null && shortcut.intent.getComponent() != null) {
@@ -329,32 +320,8 @@ public class DeleteDropTarget extends ButtonDropTarget {
mLauncher.addOnResumeCallback(checkIfUninstallWasSuccess);
}
}
} else if (isWorkspaceOrFolderApplication(d)) {
LauncherModel.deleteItemFromDatabase(mLauncher, item);
} else if (isWorkspaceFolder(d)) {
// Remove the folder from the workspace and delete the contents from launcher model
FolderInfo folderInfo = (FolderInfo) item;
mLauncher.removeFolder(folderInfo);
LauncherModel.deleteFolderContentsFromDatabase(mLauncher, folderInfo);
} else if (isWorkspaceOrFolderWidget(d)) {
// Remove the widget from the workspace
mLauncher.removeAppWidget((LauncherAppWidgetInfo) item);
LauncherModel.deleteItemFromDatabase(mLauncher, item);
final LauncherAppWidgetInfo launcherAppWidgetInfo = (LauncherAppWidgetInfo) item;
final LauncherAppWidgetHost appWidgetHost = mLauncher.getAppWidgetHost();
if (appWidgetHost != null && !launcherAppWidgetInfo.isCustomWidget()
&& launcherAppWidgetInfo.isWidgetIdValid()) {
// Deleting an app widget ID is a void call but writes to disk before returning
// to the caller...
new AsyncTask<Void, Void, Void>() {
public Void doInBackground(Void ... args) {
appWidgetHost.deleteAppWidgetId(launcherAppWidgetInfo.appWidgetId);
return null;
}
}.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, (Void) null);
}
} else if (isDragSourceWorkspaceOrFolder(d)) {
removeWorkspaceOrFolderItem(mLauncher, item, null);
}
if (wasWaitingForUninstall && !mWaitingForUninstall) {
if (d.dragSource instanceof Folder) {
@@ -365,6 +332,52 @@ public class DeleteDropTarget extends ButtonDropTarget {
}
}
public static void uninstallApp(Launcher launcher, AppInfo info) {
launcher.startApplicationUninstallActivity(info.componentName, info.flags, info.user);
}
/**
* Removes the item from the workspace. If the view is not null, it also removes the view.
* @return true if the item was removed.
*/
public static boolean removeWorkspaceOrFolderItem(Launcher launcher, ItemInfo item, View view) {
if (item instanceof ShortcutInfo) {
LauncherModel.deleteItemFromDatabase(launcher, item);
} else if (item instanceof FolderInfo) {
FolderInfo folder = (FolderInfo) item;
launcher.removeFolder(folder);
LauncherModel.deleteFolderContentsFromDatabase(launcher, folder);
} else if (item instanceof LauncherAppWidgetInfo) {
final LauncherAppWidgetInfo widget = (LauncherAppWidgetInfo) item;
// Remove the widget from the workspace
launcher.removeAppWidget(widget);
LauncherModel.deleteItemFromDatabase(launcher, widget);
final LauncherAppWidgetHost appWidgetHost = launcher.getAppWidgetHost();
if (appWidgetHost != null && !widget.isCustomWidget()
&& widget.isWidgetIdValid()) {
// Deleting an app widget ID is a void call but writes to disk before returning
// to the caller...
new AsyncTask<Void, Void, Void>() {
public Void doInBackground(Void ... args) {
appWidgetHost.deleteAppWidgetId(widget.appWidgetId);
return null;
}
}.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, (Void) null);
}
} else {
return false;
}
if (view != null) {
launcher.getWorkspace().removeWorkspaceItem(view);
launcher.getWorkspace().stripEmptyScreens();
}
return true;
}
public void onDrop(DragObject d) {
animateToTrashAndCompleteDrop(d);
}
@@ -127,6 +127,7 @@ public class FolderIcon extends FrameLayout implements FolderListener {
private void init() {
mLongPressHelper = new CheckLongPressHelper(this);
setAccessibilityDelegate(LauncherAppState.getInstance().getAccessibilityDelegate());
}
public boolean isDropEnabled() {
+17 -13
View File
@@ -76,28 +76,32 @@ public class InfoDropTarget extends ButtonDropTarget {
// acceptDrop is called just before onDrop. We do the work here, rather than
// in onDrop, because it allows us to reject the drop (by returning false)
// so that the object being dragged isn't removed from the drag source.
startDetailsActivityForInfo(d.dragInfo, mLauncher);
// There is no post-drop animation, so clean up the DragView now
d.deferDragViewCleanupPostAnimation = false;
return false;
}
public static void startDetailsActivityForInfo(Object info, Launcher launcher) {
ComponentName componentName = null;
if (d.dragInfo instanceof AppInfo) {
componentName = ((AppInfo) d.dragInfo).componentName;
} else if (d.dragInfo instanceof ShortcutInfo) {
componentName = ((ShortcutInfo) d.dragInfo).intent.getComponent();
} else if (d.dragInfo instanceof PendingAddItemInfo) {
componentName = ((PendingAddItemInfo) d.dragInfo).componentName;
if (info instanceof AppInfo) {
componentName = ((AppInfo) info).componentName;
} else if (info instanceof ShortcutInfo) {
componentName = ((ShortcutInfo) info).intent.getComponent();
} else if (info instanceof PendingAddItemInfo) {
componentName = ((PendingAddItemInfo) info).componentName;
}
final UserHandleCompat user;
if (d.dragInfo instanceof ItemInfo) {
user = ((ItemInfo) d.dragInfo).user;
if (info instanceof ItemInfo) {
user = ((ItemInfo) info).user;
} else {
user = UserHandleCompat.myUserHandle();
}
if (componentName != null) {
mLauncher.startApplicationDetailsActivity(componentName, user);
launcher.startApplicationDetailsActivity(componentName, user);
}
// There is no post-drop animation, so clean up the DragView now
d.deferDragViewCleanupPostAnimation = false;
return false;
}
@Override
+41 -30
View File
@@ -162,7 +162,6 @@ public class Launcher extends Activity
static final String EXTRA_SHORTCUT_DUPLICATE = "duplicate";
static final int SCREEN_COUNT = 5;
static final int DEFAULT_SCREEN = 2;
// To turn on these properties, type
// adb shell setprop log.tag.PROPERTY_NAME [VERBOSE | SUPPRESS]
@@ -232,7 +231,6 @@ public class Launcher extends Activity
private static final int ACTIVITY_START_DELAY = 1000;
private static final Object sLock = new Object();
private static int sScreen = DEFAULT_SCREEN;
private HashMap<Integer, Integer> mItemIdToViewId = new HashMap<Integer, Integer>();
private static final AtomicInteger sNextGeneratedId = new AtomicInteger(1);
@@ -675,18 +673,7 @@ public class Launcher extends Activity
return !mModel.isLoadingWorkspace();
}
static int getScreen() {
synchronized (sLock) {
return sScreen;
}
}
static void setScreen(int screen) {
synchronized (sLock) {
sScreen = screen;
}
}
@TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR1)
public static int generateViewId() {
if (Build.VERSION.SDK_INT >= 17) {
return View.generateViewId();
@@ -1594,7 +1581,6 @@ public class Launcher extends Activity
* Add a widget to the workspace.
*
* @param appWidgetId The app widget id
* @param cellInfo The position on screen where to create the widget.
*/
private void completeAddAppWidget(int appWidgetId, long container, long screenId,
AppWidgetHostView hostView, LauncherAppWidgetProviderInfo appWidgetInfo) {
@@ -2294,20 +2280,39 @@ public class Launcher extends Activity
closeFolder();
mWorkspace.moveToCustomContentScreen(animate);
}
public void addPendingItem(PendingAddItemInfo info, long container, long screenId,
int[] cell, int spanX, int spanY) {
switch (info.itemType) {
case LauncherSettings.Favorites.ITEM_TYPE_CUSTOM_APPWIDGET:
case LauncherSettings.Favorites.ITEM_TYPE_APPWIDGET:
int span[] = new int[2];
span[0] = spanX;
span[1] = spanY;
addAppWidgetFromDrop((PendingAddWidgetInfo) info,
container, screenId, cell, span);
break;
case LauncherSettings.Favorites.ITEM_TYPE_SHORTCUT:
processShortcutFromDrop(info.componentName, container, screenId, cell);
break;
default:
throw new IllegalStateException("Unknown item type: " + info.itemType);
}
}
/**
* Process a shortcut drop.
*
* @param componentName The name of the component
* @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, long screenId,
int[] cell, int[] loc) {
private void processShortcutFromDrop(ComponentName componentName, long container, long screenId,
int[] cell) {
resetAddInfo();
mPendingAddInfo.container = container;
mPendingAddInfo.screenId = screenId;
mPendingAddInfo.dropPos = loc;
mPendingAddInfo.dropPos = null;
if (cell != null) {
mPendingAddInfo.cellX = cell[0];
@@ -2325,14 +2330,13 @@ public class Launcher extends Activity
* @param info The PendingAppWidgetInfo of the widget being 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, long screenId,
int[] cell, int[] span, int[] loc) {
private void addAppWidgetFromDrop(PendingAddWidgetInfo info, long container, long screenId,
int[] cell, int[] span) {
resetAddInfo();
mPendingAddInfo.container = info.container = container;
mPendingAddInfo.screenId = info.screenId = screenId;
mPendingAddInfo.dropPos = loc;
mPendingAddInfo.dropPos = null;
mPendingAddInfo.minSpanX = info.minSpanX;
mPendingAddInfo.minSpanY = info.minSpanY;
@@ -3291,6 +3295,7 @@ public class Launcher extends Activity
showAppsCustomizeHelper(animated, springLoaded, contentType);
}
@TargetApi(Build.VERSION_CODES.LOLLIPOP)
private void showAppsCustomizeHelper(final boolean animated, final boolean springLoaded,
final AppsCustomizePagedView.ContentType contentType) {
if (mStateAnimation != null) {
@@ -3303,13 +3308,10 @@ public class Launcher extends Activity
final Resources res = getResources();
final int duration = res.getInteger(R.integer.config_appsCustomizeZoomInTime);
final int fadeDuration = res.getInteger(R.integer.config_appsCustomizeFadeInTime);
final int revealDuration = res.getInteger(R.integer.config_appsCustomizeRevealTime);
final int itemsAlphaStagger =
res.getInteger(R.integer.config_appsCustomizeItemsAlphaStagger);
final float scale = (float) res.getInteger(R.integer.config_appsCustomizeZoomScaleFactor);
final View fromView = mWorkspace;
final AppsCustomizeTabHost toView = mAppsCustomizeTabHost;
@@ -3536,14 +3538,10 @@ public class Launcher extends Activity
boolean material = Utilities.isLmpOrAbove();
Resources res = getResources();
final int duration = res.getInteger(R.integer.config_appsCustomizeZoomOutTime);
final int fadeOutDuration = res.getInteger(R.integer.config_appsCustomizeFadeOutTime);
final int revealDuration = res.getInteger(R.integer.config_appsCustomizeConcealTime);
final int itemsAlphaStagger =
res.getInteger(R.integer.config_appsCustomizeItemsAlphaStagger);
final float scaleFactor = (float)
res.getInteger(R.integer.config_appsCustomizeZoomScaleFactor);
final View fromView = mAppsCustomizeTabHost;
final View toView = mWorkspace;
Animator workspaceAnim = null;
@@ -4139,6 +4137,19 @@ public class Launcher extends Activity
}
}
@Override
public void bindAddPendingItem(final PendingAddItemInfo info, final long container,
final long screenId, final int[] cell, final int spanX, final int spanY) {
showWorkspace(true, new Runnable() {
@Override
public void run() {
mWorkspace.snapToPage(mWorkspace.getPageIndexForScreenId(screenId));
addPendingItem(info, container, screenId, cell, spanX, spanY);
}
});
}
private boolean shouldShowWeightWatcher() {
String spKey = LauncherAppState.getSharedPreferencesKey();
SharedPreferences sp = getSharedPreferences(spKey, Context.MODE_PRIVATE);
@@ -0,0 +1,109 @@
package com.android.launcher3;
import android.annotation.TargetApi;
import android.os.Build;
import android.os.Bundle;
import android.util.SparseArray;
import android.view.View;
import android.view.View.AccessibilityDelegate;
import android.view.accessibility.AccessibilityNodeInfo;
import android.view.accessibility.AccessibilityNodeInfo.AccessibilityAction;
import com.android.launcher3.LauncherModel.ScreenPosProvider;
import java.util.ArrayList;
@TargetApi(Build.VERSION_CODES.LOLLIPOP)
public class LauncherAccessibilityDelegate extends AccessibilityDelegate {
public static final int REMOVE = R.id.action_remove;
public static final int INFO = R.id.action_info;
public static final int UNINSTALL = R.id.action_uninstall;
public static final int ADD_TO_WORKSPACE = R.id.action_add_to_workspace;
private final SparseArray<AccessibilityAction> mActions =
new SparseArray<AccessibilityAction>();
private final Launcher mLauncher;
public LauncherAccessibilityDelegate(Launcher launcher) {
mLauncher = launcher;
mActions.put(REMOVE, new AccessibilityAction(REMOVE,
launcher.getText(R.string.delete_target_label)));
mActions.put(INFO, new AccessibilityAction(INFO,
launcher.getText(R.string.info_target_label)));
mActions.put(UNINSTALL, new AccessibilityAction(UNINSTALL,
launcher.getText(R.string.delete_target_uninstall_label)));
mActions.put(ADD_TO_WORKSPACE, new AccessibilityAction(ADD_TO_WORKSPACE,
launcher.getText(R.string.action_add_to_workspace)));
}
@Override
public void onInitializeAccessibilityNodeInfo(View host, AccessibilityNodeInfo info) {
super.onInitializeAccessibilityNodeInfo(host, info);
if (!(host.getTag() instanceof ItemInfo)) return;
ItemInfo item = (ItemInfo) host.getTag();
if ((item instanceof ShortcutInfo)
|| (item instanceof LauncherAppWidgetInfo)
|| (item instanceof FolderInfo)) {
// Workspace shortcut / widget
info.addAction(mActions.get(REMOVE));
} else if ((item instanceof AppInfo) || (item instanceof PendingAddItemInfo)) {
// App or Widget from customization tray
if (item instanceof AppInfo) {
info.addAction(mActions.get(UNINSTALL));
}
info.addAction(mActions.get(INFO));
info.addAction(mActions.get(ADD_TO_WORKSPACE));
}
}
@Override
public boolean performAccessibilityAction(View host, int action, Bundle args) {
if ((host.getTag() instanceof ItemInfo)
&& performAction(host, (ItemInfo) host.getTag(), action)) {
return true;
}
return super.performAccessibilityAction(host, action, args);
}
public boolean performAction(View host, ItemInfo item, int action) {
if (action == REMOVE) {
return DeleteDropTarget.removeWorkspaceOrFolderItem(mLauncher, item, host);
} else if (action == INFO) {
InfoDropTarget.startDetailsActivityForInfo(item, mLauncher);
return true;
} else if (action == UNINSTALL) {
DeleteDropTarget.uninstallApp(mLauncher, (AppInfo) item);
return true;
} else if (action == ADD_TO_WORKSPACE) {
final int preferredPage = mLauncher.getWorkspace().getCurrentPage();
final ScreenPosProvider screenProvider = new ScreenPosProvider() {
@Override
public int getScreenIndex(ArrayList<Long> screenIDs) {
return preferredPage;
}
};
if (item instanceof AppInfo) {
final ArrayList<ItemInfo> addShortcuts = new ArrayList<ItemInfo>();
addShortcuts.add(((AppInfo) item).makeShortcut());
mLauncher.showWorkspace(true, new Runnable() {
@Override
public void run() {
mLauncher.getModel().addAndBindAddedWorkspaceApps(
mLauncher, addShortcuts, screenProvider, 0, true);
}
});
return true;
} else if (item instanceof PendingAddItemInfo) {
mLauncher.getModel().addAndBindPendingItem(
mLauncher, (PendingAddItemInfo) item, screenProvider, 0);
return true;
}
}
return false;
}
}
@@ -32,10 +32,13 @@ import android.os.Handler;
import android.util.DisplayMetrics;
import android.util.Log;
import android.view.Display;
import android.view.View.AccessibilityDelegate;
import android.view.WindowManager;
import com.android.launcher3.compat.LauncherAppsCompat;
import com.android.launcher3.compat.PackageInstallerCompat;
import com.android.launcher3.compat.PackageInstallerCompat.PackageInstallInfo;
import java.lang.ref.WeakReference;
import java.util.ArrayList;
@@ -62,6 +65,7 @@ public class LauncherAppState implements DeviceProfile.DeviceProfileCallbacks {
private static LauncherAppState INSTANCE;
private DynamicGrid mDynamicGrid;
private AccessibilityDelegate mAccessibilityDelegate;
public static LauncherAppState getInstance() {
if (INSTANCE == null) {
@@ -162,9 +166,15 @@ public class LauncherAppState implements DeviceProfile.DeviceProfileCallbacks {
LauncherModel setLauncher(Launcher launcher) {
mModel.initialize(launcher);
mAccessibilityDelegate = ((launcher != null) && Utilities.isLmpOrAbove()) ?
new LauncherAccessibilityDelegate(launcher) : null;
return mModel;
}
AccessibilityDelegate getAccessibilityDelegate() {
return mAccessibilityDelegate;
}
public IconCache getIconCache() {
return mIconCache;
}
@@ -48,6 +48,7 @@ public class LauncherAppWidgetHostView extends AppWidgetHostView implements Touc
mLongPressHelper = new CheckLongPressHelper(this);
mInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
mDragLayer = ((Launcher) context).getDragLayer();
setAccessibilityDelegate(LauncherAppState.getInstance().getAccessibilityDelegate());
}
@Override
+215 -191
View File
@@ -29,7 +29,6 @@ import android.content.Intent;
import android.content.Intent.ShortcutIconResource;
import android.content.IntentFilter;
import android.content.SharedPreferences;
import android.content.pm.LauncherApps.Callback;
import android.content.pm.PackageManager;
import android.content.pm.ProviderInfo;
import android.content.pm.ResolveInfo;
@@ -38,6 +37,7 @@ import android.content.res.Resources;
import android.database.Cursor;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Rect;
import android.net.Uri;
import android.os.Environment;
import android.os.Handler;
@@ -49,6 +49,7 @@ import android.os.SystemClock;
import android.provider.BaseColumns;
import android.text.TextUtils;
import android.util.Log;
import android.util.LongSparseArray;
import android.util.Pair;
import com.android.launcher3.compat.AppWidgetManagerCompat;
@@ -108,7 +109,6 @@ public class LauncherModel extends BroadcastReceiver
private DeferredHandler mHandler = new DeferredHandler();
private LoaderTask mLoaderTask;
private boolean mIsLoaderTaskRunning;
private volatile boolean mFlushingWorkerThread;
/**
* Maintain a set of packages per user, for which we added a shortcut on the workspace.
@@ -219,12 +219,18 @@ public class LauncherModel extends BroadcastReceiver
public boolean isAllAppsButtonRank(int rank);
public void onPageBoundSynchronously(int page);
public void dumpLogsToLocalData();
public void bindAddPendingItem(PendingAddItemInfo info, long container, long screenId,
int[] cell, int spanX, int spanY);
}
public interface ItemInfoFilter {
public boolean filterItem(ItemInfo parent, ItemInfo info, ComponentName cn);
}
public interface ScreenPosProvider {
int getScreenIndex(ArrayList<Long> screenIDs);
}
LauncherModel(LauncherAppState app, IconCache iconCache, AppFilter appFilter) {
Context context = app.getContext();
@@ -287,67 +293,6 @@ public class LauncherModel extends BroadcastReceiver
return mOldContentProviderExists && !launcher.isLauncherPreinstalled() ;
}
static boolean findNextAvailableIconSpaceInScreen(ArrayList<ItemInfo> items, int[] xy,
long screen) {
LauncherAppState app = LauncherAppState.getInstance();
DeviceProfile grid = app.getDynamicGrid().getDeviceProfile();
final int xCount = (int) grid.numColumns;
final int yCount = (int) grid.numRows;
boolean[][] occupied = new boolean[xCount][yCount];
int cellX, cellY, spanX, spanY;
for (int i = 0; i < items.size(); ++i) {
final ItemInfo item = items.get(i);
if (item.container == LauncherSettings.Favorites.CONTAINER_DESKTOP) {
if (item.screenId == screen) {
cellX = item.cellX;
cellY = item.cellY;
spanX = item.spanX;
spanY = item.spanY;
for (int x = cellX; 0 <= x && x < cellX + spanX && x < xCount; x++) {
for (int y = cellY; 0 <= y && y < cellY + spanY && y < yCount; y++) {
occupied[x][y] = true;
}
}
}
}
}
return CellLayout.findVacantCell(xy, 1, 1, xCount, yCount, occupied);
}
static Pair<Long, int[]> findNextAvailableIconSpace(Context context, String name,
Intent launchIntent,
int firstScreenIndex,
ArrayList<Long> workspaceScreens) {
// Lock on the app so that we don't try and get the items while apps are being added
LauncherAppState app = LauncherAppState.getInstance();
LauncherModel model = app.getModel();
boolean found = false;
synchronized (app) {
if (sWorkerThread.getThreadId() != Process.myTid()) {
// Flush the LauncherModel worker thread, so that if we just did another
// processInstallShortcut, we give it time for its shortcut to get added to the
// database (getItemsInLocalCoordinates reads the database)
model.flushWorkerThread();
}
final ArrayList<ItemInfo> items = LauncherModel.getItemsInLocalCoordinates(context);
// Try adding to the workspace screens incrementally, starting at the default or center
// screen and alternating between +1, -1, +2, -2, etc. (using ~ ceil(i/2f)*(-1)^(i-1))
firstScreenIndex = Math.min(firstScreenIndex, workspaceScreens.size());
int count = workspaceScreens.size();
for (int screen = firstScreenIndex; screen < count && !found; screen++) {
int[] tmpCoordinates = new int[2];
if (findNextAvailableIconSpaceInScreen(items, tmpCoordinates,
workspaceScreens.get(screen))) {
// Update the Launcher db
return new Pair<Long, int[]>(workspaceScreens.get(screen), tmpCoordinates);
}
}
}
return null;
}
public void setPackageState(final ArrayList<PackageInstallInfo> installInfo) {
// Process the updated package state
Runnable r = new Runnable() {
@@ -402,11 +347,196 @@ public class LauncherModel extends BroadcastReceiver
public void addAndBindAddedWorkspaceApps(final Context context,
final ArrayList<ItemInfo> workspaceApps) {
final Callbacks callbacks = getCallback();
addAndBindAddedWorkspaceApps(context, workspaceApps,
new ScreenPosProvider() {
if (workspaceApps == null) {
throw new RuntimeException("workspaceApps and allAppsApps must not be null");
@Override
public int getScreenIndex(ArrayList<Long> screenIDs) {
return screenIDs.isEmpty() ? 0 : 1;
}
}, 1, false);
}
private static boolean findNextAvailableIconSpaceInScreen(ArrayList<Rect> occupiedPos,
int[] xy, int spanX, int spanY) {
LauncherAppState app = LauncherAppState.getInstance();
DeviceProfile grid = app.getDynamicGrid().getDeviceProfile();
final int xCount = (int) grid.numColumns;
final int yCount = (int) grid.numRows;
boolean[][] occupied = new boolean[xCount][yCount];
if (occupiedPos != null) {
for (Rect r : occupiedPos) {
for (int x = r.left; 0 <= x && x < r.right && x < xCount; x++) {
for (int y = r.top; 0 <= y && y < r.bottom && y < yCount; y++) {
occupied[x][y] = true;
}
}
}
}
return CellLayout.findVacantCell(xy, spanX, spanY, xCount, yCount, occupied);
}
/**
* Find a position on the screen for the given size or adds a new screen.
* @return screenId and the coordinates for the item.
*/
private static Pair<Long, int[]> findSpaceForItem(
Context context,
ScreenPosProvider preferredScreen,
int fallbackStartScreen,
ArrayList<Long> workspaceScreens,
ArrayList<Long> addedWorkspaceScreensFinal,
int spanX, int spanY) {
// Load position of items which are on the desktop. We can't use sBgItemsIdMap because
// loadWorkspace() may not have been called.
final ContentResolver cr = context.getContentResolver();
Cursor c = cr.query(LauncherSettings.Favorites.CONTENT_URI,
new String[] {
LauncherSettings.Favorites.SCREEN,
LauncherSettings.Favorites.CELLX,
LauncherSettings.Favorites.CELLY,
LauncherSettings.Favorites.SPANX,
LauncherSettings.Favorites.SPANY,
LauncherSettings.Favorites.CONTAINER
},
"container=?",
new String[] { Integer.toString(LauncherSettings.Favorites.CONTAINER_DESKTOP) },
null);
final int screenIndex = c.getColumnIndexOrThrow(LauncherSettings.Favorites.SCREEN);
final int cellXIndex = c.getColumnIndexOrThrow(LauncherSettings.Favorites.CELLX);
final int cellYIndex = c.getColumnIndexOrThrow(LauncherSettings.Favorites.CELLY);
final int spanXIndex = c.getColumnIndexOrThrow(LauncherSettings.Favorites.SPANX);
final int spanYIndex = c.getColumnIndexOrThrow(LauncherSettings.Favorites.SPANY);
LongSparseArray<ArrayList<Rect>> screenItems = new LongSparseArray<ArrayList<Rect>>();
try {
while (c.moveToNext()) {
Rect rect = new Rect();
rect.left = c.getInt(cellXIndex);
rect.top = c.getInt(cellYIndex);
rect.right = rect.left + Math.max(1, c.getInt(spanXIndex));
rect.bottom = rect.top + Math.max(1, c.getInt(spanYIndex));
long screenId = c.getInt(screenIndex);
ArrayList<Rect> items = screenItems.get(screenId);
if (items == null) {
items = new ArrayList<Rect>();
screenItems.put(screenId, items);
}
items.add(rect);
}
} catch (Exception e) {
screenItems.clear();
} finally {
c.close();
}
// Find appropriate space for the item.
long screenId = 0;
int[] cordinates = new int[2];
boolean found = false;
int screenCount = workspaceScreens.size();
// First check the preferred screen.
int preferredScreenIndex = preferredScreen.getScreenIndex(workspaceScreens);
if (preferredScreenIndex < screenCount) {
screenId = workspaceScreens.get(preferredScreenIndex);
found = findNextAvailableIconSpaceInScreen(
screenItems.get(screenId), cordinates, spanX, spanY);
}
if (!found) {
// Search on any of the screens.
for (int screen = fallbackStartScreen; screen < screenCount; screen++) {
screenId = workspaceScreens.get(screen);
if (findNextAvailableIconSpaceInScreen(
screenItems.get(screenId), cordinates, spanX, spanY)) {
// We found a space for it
found = true;
break;
}
}
}
if (!found) {
// Still no position found. Add a new screen to the end.
screenId = LauncherAppState.getLauncherProvider().generateNewScreenId();
// Save the screen id for binding in the workspace
workspaceScreens.add(screenId);
addedWorkspaceScreensFinal.add(screenId);
// If we still can't find an empty space, then God help us all!!!
if (!findNextAvailableIconSpaceInScreen(
screenItems.get(screenId), cordinates, spanX, spanY)) {
throw new RuntimeException("Can't find space to add the item");
}
}
return Pair.create(screenId, cordinates);
}
/**
* Adds the provided items to the workspace.
* @param preferredScreen the screen where we should try to add the app first
* @param fallbackStartScreen the screen to start search for empty space if
* preferredScreen is not available.
*/
public void addAndBindPendingItem(
final Context context,
final PendingAddItemInfo addInfo,
final ScreenPosProvider preferredScreen,
final int fallbackStartScreen) {
final Callbacks callbacks = getCallback();
// Process the newly added applications and add them to the database first
Runnable r = new Runnable() {
public void run() {
final ArrayList<Long> addedWorkspaceScreensFinal = new ArrayList<Long>();
ArrayList<Long> workspaceScreens = new ArrayList<Long>();
TreeMap<Integer, Long> orderedScreens = loadWorkspaceScreensDb(context);
for (Integer i : orderedScreens.keySet()) {
long screenId = orderedScreens.get(i);
workspaceScreens.add(screenId);
}
// Find appropriate space for the item.
Pair<Long, int[]> coords = findSpaceForItem(context, preferredScreen,
fallbackStartScreen, workspaceScreens, addedWorkspaceScreensFinal,
addInfo.spanX,
addInfo.spanY);
final long screenId = coords.first;
final int[] cordinates = coords.second;
// Update the workspace screens
updateWorkspaceScreenOrder(context, workspaceScreens);
runOnMainThread(new Runnable() {
public void run() {
Callbacks cb = getCallback();
if (callbacks == cb && cb != null) {
cb.bindAddScreens(addedWorkspaceScreensFinal);
cb.bindAddPendingItem(addInfo,
LauncherSettings.Favorites.CONTAINER_DESKTOP,
screenId, cordinates, addInfo.spanX, addInfo.spanY);
}
}
});
}
};
runOnWorkerThread(r);
}
/**
* Adds the provided items to the workspace.
* @param preferredScreen the screen where we should try to add the app first
* @param fallbackStartScreen the screen to start search for empty space if
* preferredScreen is not available.
*/
public void addAndBindAddedWorkspaceApps(final Context context,
final ArrayList<ItemInfo> workspaceApps,
final ScreenPosProvider preferredScreen,
final int fallbackStartScreen,
final boolean allowDuplicate) {
final Callbacks callbacks = getCallback();
if (workspaceApps.isEmpty()) {
return;
}
@@ -427,53 +557,27 @@ public class LauncherModel extends BroadcastReceiver
}
synchronized(sBgLock) {
Iterator<ItemInfo> iter = workspaceApps.iterator();
while (iter.hasNext()) {
ItemInfo a = iter.next();
final String name = a.title.toString();
final Intent launchIntent = a.getIntent();
// Short-circuit this logic if the icon exists somewhere on the workspace
if (shortcutExists(context, name, launchIntent, a.user)) {
continue;
}
// Add this icon to the db, creating a new page if necessary. If there
// is only the empty page then we just add items to the first page.
// Otherwise, we add them to the next pages.
int startSearchPageIndex = workspaceScreens.isEmpty() ? 0 : 1;
Pair<Long, int[]> coords = LauncherModel.findNextAvailableIconSpace(context,
name, launchIntent, startSearchPageIndex, workspaceScreens);
if (coords == null) {
LauncherProvider lp = LauncherAppState.getLauncherProvider();
// If we can't find a valid position, then just add a new screen.
// This takes time so we need to re-queue the add until the new
// page is added. Create as many screens as necessary to satisfy
// the startSearchPageIndex.
int numPagesToAdd = Math.max(1, startSearchPageIndex + 1 -
workspaceScreens.size());
while (numPagesToAdd > 0) {
long screenId = lp.generateNewScreenId();
// Save the screen id for binding in the workspace
workspaceScreens.add(screenId);
addedWorkspaceScreensFinal.add(screenId);
numPagesToAdd--;
for (ItemInfo item : workspaceApps) {
if (!allowDuplicate) {
// Short-circuit this logic if the icon exists somewhere on the workspace
if (shortcutExists(context, item.title.toString(),
item.getIntent(), item.user)) {
continue;
}
}
// Find the coordinate again
coords = LauncherModel.findNextAvailableIconSpace(context,
name, launchIntent, startSearchPageIndex, workspaceScreens);
}
if (coords == null) {
throw new RuntimeException("Coordinates should not be null");
}
// Find appropriate space for the item.
Pair<Long, int[]> coords = findSpaceForItem(context, preferredScreen,
fallbackStartScreen, workspaceScreens, addedWorkspaceScreensFinal,
1, 1);
long screenId = coords.first;
int[] cordinates = coords.second;
ShortcutInfo shortcutInfo;
if (a instanceof ShortcutInfo) {
shortcutInfo = (ShortcutInfo) a;
} else if (a instanceof AppInfo) {
shortcutInfo = ((AppInfo) a).makeShortcut();
if (item instanceof ShortcutInfo) {
shortcutInfo = (ShortcutInfo) item;
} else if (item instanceof AppInfo) {
shortcutInfo = ((AppInfo) item).makeShortcut();
} else {
throw new RuntimeException("Unexpected info type");
}
@@ -481,7 +585,7 @@ public class LauncherModel extends BroadcastReceiver
// Add the shortcut to the db
addItemToDatabase(context, shortcutInfo,
LauncherSettings.Favorites.CONTAINER_DESKTOP,
coords.first, coords.second[0], coords.second[1], false);
screenId, cordinates[0], cordinates[1], false);
// Save the ShortcutInfo for binding in the workspace
addedShortcutsFinal.add(shortcutInfo);
}
@@ -717,35 +821,6 @@ public class LauncherModel extends BroadcastReceiver
}
}
public void flushWorkerThread() {
mFlushingWorkerThread = true;
Runnable waiter = new Runnable() {
public void run() {
synchronized (this) {
notifyAll();
mFlushingWorkerThread = false;
}
}
};
synchronized(waiter) {
runOnWorkerThread(waiter);
if (mLoaderTask != null) {
synchronized(mLoaderTask) {
mLoaderTask.notify();
}
}
boolean success = false;
while (!success) {
try {
waiter.wait();
success = true;
} catch (InterruptedException e) {
}
}
}
}
/**
* Move an item in the DB to a new <container, screen, cellX, cellY>
*/
@@ -889,57 +964,6 @@ public class LauncherModel extends BroadcastReceiver
}
}
/**
* Returns an ItemInfo array containing all the items in the LauncherModel.
* The ItemInfo.id is not set through this function.
*/
static ArrayList<ItemInfo> getItemsInLocalCoordinates(Context context) {
ArrayList<ItemInfo> items = new ArrayList<ItemInfo>();
final ContentResolver cr = context.getContentResolver();
Cursor c = cr.query(LauncherSettings.Favorites.CONTENT_URI, new String[] {
LauncherSettings.Favorites.ITEM_TYPE, LauncherSettings.Favorites.CONTAINER,
LauncherSettings.Favorites.SCREEN,
LauncherSettings.Favorites.CELLX, LauncherSettings.Favorites.CELLY,
LauncherSettings.Favorites.SPANX, LauncherSettings.Favorites.SPANY,
LauncherSettings.Favorites.PROFILE_ID }, null, null, null);
final int itemTypeIndex = c.getColumnIndexOrThrow(LauncherSettings.Favorites.ITEM_TYPE);
final int containerIndex = c.getColumnIndexOrThrow(LauncherSettings.Favorites.CONTAINER);
final int screenIndex = c.getColumnIndexOrThrow(LauncherSettings.Favorites.SCREEN);
final int cellXIndex = c.getColumnIndexOrThrow(LauncherSettings.Favorites.CELLX);
final int cellYIndex = c.getColumnIndexOrThrow(LauncherSettings.Favorites.CELLY);
final int rankIndex = c.getColumnIndexOrThrow(LauncherSettings.Favorites.RANK);
final int spanXIndex = c.getColumnIndexOrThrow(LauncherSettings.Favorites.SPANX);
final int spanYIndex = c.getColumnIndexOrThrow(LauncherSettings.Favorites.SPANY);
final int profileIdIndex = c.getColumnIndexOrThrow(LauncherSettings.Favorites.PROFILE_ID);
UserManagerCompat userManager = UserManagerCompat.getInstance(context);
try {
while (c.moveToNext()) {
ItemInfo item = new ItemInfo();
item.cellX = c.getInt(cellXIndex);
item.cellY = c.getInt(cellYIndex);
item.rank = c.getInt(rankIndex);
item.spanX = Math.max(1, c.getInt(spanXIndex));
item.spanY = Math.max(1, c.getInt(spanYIndex));
item.container = c.getInt(containerIndex);
item.itemType = c.getInt(itemTypeIndex);
item.screenId = c.getInt(screenIndex);
long serialNumber = c.getInt(profileIdIndex);
item.user = userManager.getUserForSerialNumber(serialNumber);
// Skip if user has been deleted.
if (item.user != null) {
items.add(item);
}
}
} catch (Exception e) {
items.clear();
} finally {
c.close();
}
return items;
}
/**
* Find a folder in the db, creating the FolderInfo if necessary, and adding it to folderList.
*/
@@ -1543,7 +1567,7 @@ public class LauncherModel extends BroadcastReceiver
}
});
while (!mStopped && !mLoadAndBindStepFinished && !mFlushingWorkerThread) {
while (!mStopped && !mLoadAndBindStepFinished) {
try {
// Just in case mFlushingWorkerThread changes but we aren't woken up,
// wait no longer than 1sec at a time
@@ -16,7 +16,6 @@
package com.android.launcher3;
import android.appwidget.AppWidgetProviderInfo;
import android.content.Context;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
@@ -67,6 +66,7 @@ public class PagedViewWidget extends LinearLayout {
setWillNotDraw(false);
setClipToPadding(false);
setAccessibilityDelegate(LauncherAppState.getInstance().getAccessibilityDelegate());
}
@Override
@@ -54,12 +54,11 @@ class PreloadIconDrawable extends Drawable {
mPaint.setStrokeCap(Paint.Cap.ROUND);
setBounds(icon.getBounds());
applyTheme(theme);
applyPreloaderTheme(theme);
onLevelChange(0);
}
@Override
public void applyTheme(Theme t) {
public void applyPreloaderTheme(Theme t) {
TypedArray ta = t.obtainStyledAttributes(R.styleable.PreloadIconDrawable);
mBgDrawable = ta.getDrawable(R.styleable.PreloadIconDrawable_background);
mBgDrawable.setFilterBitmap(true);
+16 -45
View File
@@ -31,10 +31,7 @@ import android.appwidget.AppWidgetHostView;
import android.appwidget.AppWidgetProviderInfo;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.content.res.Resources;
import android.content.res.TypedArray;
import android.graphics.Bitmap;
@@ -77,8 +74,6 @@ import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.atomic.AtomicInteger;
/**
@@ -92,9 +87,6 @@ public class Workspace extends SmoothPagedView
Insettable {
private static final String TAG = "Launcher.Workspace";
// Y rotation to apply to the workspace screens
private static final float WORKSPACE_OVERSCROLL_ROTATION = 24f;
private static final int CHILDREN_OUTLINE_FADE_OUT_DELAY = 0;
private static final int CHILDREN_OUTLINE_FADE_OUT_DURATION = 375;
private static final int CHILDREN_OUTLINE_FADE_IN_DURATION = 100;
@@ -228,7 +220,6 @@ public class Workspace extends SmoothPagedView
private Runnable mDelayedResizeRunnable;
private Runnable mDelayedSnapToPageRunnable;
private Point mDisplaySize = new Point();
private int mCameraDistance;
// Variables relating to the creation of user folders by hovering shortcuts over shortcuts
private static final int FOLDER_CREATION_TIMEOUT = 0;
@@ -346,7 +337,6 @@ public class Workspace extends SmoothPagedView
mSpringLoadedShrinkFactor =
res.getInteger(R.integer.config_workspaceSpringLoadShrinkPercentage) / 100.0f;
mOverviewModeShrinkFactor = grid.getOverviewModeScale();
mCameraDistance = res.getInteger(R.integer.config_cameraDistance);
mOriginalDefaultPage = mDefaultPage = a.getInt(R.styleable.Workspace_defaultScreen, 1);
a.recycle();
@@ -450,7 +440,6 @@ public class Workspace extends SmoothPagedView
*/
protected void initWorkspace() {
mCurrentPage = mDefaultPage;
Launcher.setScreen(mCurrentPage);
LauncherAppState app = LauncherAppState.getInstance();
DeviceProfile grid = app.getDynamicGrid().getDeviceProfile();
mIconCache = app.getIconCache();
@@ -1323,7 +1312,6 @@ public class Workspace extends SmoothPagedView
@Override
protected void notifyPageSwitchListener() {
super.notifyPageSwitchListener();
Launcher.setScreen(getNextPage());
if (hasCustomContent() && getNextPage() == 0 && !mCustomContentShowing) {
mCustomContentShowing = true;
@@ -3952,23 +3940,8 @@ public class Workspace extends SmoothPagedView
// When dragging and dropping from customization tray, we deal with creating
// widgets/shortcuts/folders in a slightly different way
switch (pendingInfo.itemType) {
case LauncherSettings.Favorites.ITEM_TYPE_CUSTOM_APPWIDGET:
case LauncherSettings.Favorites.ITEM_TYPE_APPWIDGET:
int span[] = new int[2];
span[0] = item.spanX;
span[1] = item.spanY;
mLauncher.addAppWidgetFromDrop((PendingAddWidgetInfo) pendingInfo,
container, screenId, mTargetCell, span, null);
break;
case LauncherSettings.Favorites.ITEM_TYPE_SHORTCUT:
mLauncher.processShortcutFromDrop(pendingInfo.componentName,
container, screenId, mTargetCell, null);
break;
default:
throw new IllegalStateException("Unknown item type: " +
pendingInfo.itemType);
}
mLauncher.addPendingItem(pendingInfo, container, screenId, mTargetCell,
item.spanX, item.spanY);
}
};
boolean isWidget = pendingInfo.itemType == LauncherSettings.Favorites.ITEM_TYPE_APPWIDGET
@@ -3998,7 +3971,7 @@ public class Workspace extends SmoothPagedView
case LauncherSettings.Favorites.ITEM_TYPE_SHORTCUT:
if (info.container == NO_ID && info instanceof AppInfo) {
// Came from all apps -- make a copy
info = new ShortcutInfo((AppInfo) info);
info = ((AppInfo) info).makeShortcut();
}
view = mLauncher.createShortcut(R.layout.application, cellLayout,
(ShortcutInfo) info);
@@ -4250,15 +4223,7 @@ public class Workspace extends SmoothPagedView
if (success && !(beingCalledAfterUninstall && !mUninstallSuccessful)) {
if (target != this && mDragInfo != null) {
CellLayout parentCell = getParentCellLayoutForView(mDragInfo.cell);
if (parentCell != null) {
parentCell.removeView(mDragInfo.cell);
} else if (LauncherAppState.isDogfoodBuild()) {
throw new NullPointerException("mDragInfo.cell has null parent");
}
if (mDragInfo.cell instanceof DropTarget) {
mDragController.removeDropTarget((DropTarget) mDragInfo.cell);
}
removeWorkspaceItem(mDragInfo.cell);
}
} else if (mDragInfo != null) {
CellLayout cellLayout;
@@ -4283,6 +4248,18 @@ public class Workspace extends SmoothPagedView
mDragInfo = null;
}
public void removeWorkspaceItem(View v) {
CellLayout parentCell = getParentCellLayoutForView(v);
if (parentCell != null) {
parentCell.removeView(v);
} else if (LauncherAppState.isDogfoodBuild()) {
throw new NullPointerException("mDragInfo.cell has null parent");
}
if (v instanceof DropTarget) {
mDragController.removeDropTarget((DropTarget) v);
}
}
public void deferCompleteDropAfterUninstallActivity() {
mDeferDropAfterUninstall = true;
}
@@ -4477,12 +4454,6 @@ public class Workspace extends SmoothPagedView
return true;
}
@Override
protected void onRestoreInstanceState(Parcelable state) {
super.onRestoreInstanceState(state);
Launcher.setScreen(mCurrentPage);
}
@Override
protected void dispatchRestoreInstanceState(SparseArray<Parcelable> container) {
// We don't dispatch restoreInstanceState to our children using this code path.