Merge "Import translations. DO NOT MERGE" into ub-launcher3-calgary
diff --git a/res/layout-port/launcher.xml b/res/layout-port/launcher.xml
index f711274..4576e4d 100644
--- a/res/layout-port/launcher.xml
+++ b/res/layout-port/launcher.xml
@@ -57,12 +57,10 @@
<!-- Keep these behind the workspace so that they are not visible when
we go into AllApps -->
- <include
+ <com.android.launcher3.pageindicators.PageIndicatorLine
android:id="@+id/page_indicator"
- layout="@layout/page_indicator"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_gravity="center_horizontal" />
+ android:layout_width="match_parent"
+ android:layout_height="1dp" />
<include
android:id="@+id/app_info_drop_target_bar"
diff --git a/res/layout-sw720dp/launcher.xml b/res/layout-sw720dp/launcher.xml
index 780d645..0f755d8 100644
--- a/res/layout-sw720dp/launcher.xml
+++ b/res/layout-sw720dp/launcher.xml
@@ -64,11 +64,10 @@
<!-- Keep these behind the workspace so that they are not visible when
we go into AllApps -->
- <include android:id="@+id/page_indicator"
- layout="@layout/page_indicator"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_gravity="center_horizontal" />
+ <com.android.launcher3.pageindicators.PageIndicatorLine
+ android:id="@+id/page_indicator"
+ android:layout_width="match_parent"
+ android:layout_height="1dp" />
<include layout="@layout/widgets_view"
android:id="@+id/widgets_view"
diff --git a/res/layout/page_indicator.xml b/res/layout/page_indicator.xml
index 68fe3dd..5655159 100644
--- a/res/layout/page_indicator.xml
+++ b/res/layout/page_indicator.xml
@@ -13,9 +13,9 @@
See the License for the specific language governing permissions and
limitations under the License.
-->
-<com.android.launcher3.PageIndicator
+<com.android.launcher3.pageindicators.PageIndicatorDots
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:launcher="http://schemas.android.com/apk/res-auto"
android:animateLayoutChanges="true"
launcher:windowSize="@integer/config_maxNumberOfPageIndicatorsToShow">
-</com.android.launcher3.PageIndicator>
+</com.android.launcher3.pageindicators.PageIndicatorDots>
diff --git a/res/layout/page_indicator_marker.xml b/res/layout/page_indicator_marker.xml
index 564a958..357a761 100644
--- a/res/layout/page_indicator_marker.xml
+++ b/res/layout/page_indicator_marker.xml
@@ -13,7 +13,7 @@
See the License for the specific language governing permissions and
limitations under the License.
-->
-<com.android.launcher3.PageIndicatorMarker
+<com.android.launcher3.pageindicators.PageIndicatorDot
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:launcher="http://schemas.android.com/apk/res-auto"
android:layout_width="12dp"
@@ -36,4 +36,4 @@
android:scaleX="0.5"
android:scaleY="0.5"
/>
-</com.android.launcher3.PageIndicatorMarker>
+</com.android.launcher3.pageindicators.PageIndicatorDot>
diff --git a/res/values/attrs.xml b/res/values/attrs.xml
index 6d8efaa..2eb9b91 100644
--- a/res/values/attrs.xml
+++ b/res/values/attrs.xml
@@ -32,7 +32,7 @@
</declare-styleable>
<!-- Page Indicator specific attributes. -->
- <declare-styleable name="PageIndicator">
+ <declare-styleable name="PageIndicatorDots">
<attr name="windowSize" format="integer" />
</declare-styleable>
diff --git a/res/values/config.xml b/res/values/config.xml
index d689f1b..88aa7fd 100644
--- a/res/values/config.xml
+++ b/res/values/config.xml
@@ -75,6 +75,9 @@
<!-- Name of an icon provider class. -->
<string name="icon_provider_class" translatable="false"></string>
+ <!-- Package name of the default wallpaper picker. -->
+ <string name="wallpaper_picker_package" translatable="false"></string>
+
<!-- View ID to use for QSB widget -->
<item type="id" name="qsb_widget" />
diff --git a/res/values/strings.xml b/res/values/strings.xml
index 813953e..4c9d0b5 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -169,7 +169,11 @@
<!-- Strings for settings -->
<!-- Title for Allow Rotation setting. [CHAR LIMIT=50] -->
- <string name="allow_rotation_title">Allow rotation</string>
+ <string name="allow_rotation_title">Allow homescreen rotation</string>
+ <!-- Text explaining when the home screen will get rotated. [CHAR LIMIT=100] -->
+ <string name="allow_rotation_desc">When device is rotated</string>
+ <!-- Text explaining that rotation is disabled in Display settings. 'Display' refers to the Display section in system settings [CHAR LIMIT=100] -->
+ <string name="allow_rotation_blocked_desc">Current Display setting doesn\'t permit rotation</string>
<!-- Label on an icon that references an uninstalled package, for which we have no information about when it might be installed. [CHAR_LIMIT=15] -->
<string name="package_state_unknown">Unknown</string>
diff --git a/src/com/android/launcher3/DeviceProfile.java b/src/com/android/launcher3/DeviceProfile.java
index 9ab5611..8d11aaa 100644
--- a/src/com/android/launcher3/DeviceProfile.java
+++ b/src/com/android/launcher3/DeviceProfile.java
@@ -537,7 +537,6 @@
lp = (FrameLayout.LayoutParams) pageIndicator.getLayoutParams();
lp.gravity = Gravity.CENTER_HORIZONTAL | Gravity.BOTTOM;
lp.width = LayoutParams.WRAP_CONTENT;
- lp.height = LayoutParams.WRAP_CONTENT;
lp.bottomMargin = hotseatBarHeightPx;
pageIndicator.setLayoutParams(lp);
}
diff --git a/src/com/android/launcher3/FolderInfo.java b/src/com/android/launcher3/FolderInfo.java
index 6c9d969..9a99852 100644
--- a/src/com/android/launcher3/FolderInfo.java
+++ b/src/com/android/launcher3/FolderInfo.java
@@ -109,10 +109,8 @@
listeners.add(listener);
}
- void removeListener(FolderListener listener) {
- if (listeners.contains(listener)) {
- listeners.remove(listener);
- }
+ public void removeListener(FolderListener listener) {
+ listeners.remove(listener);
}
public void itemsChanged(boolean animate) {
@@ -121,12 +119,6 @@
}
}
- @Override
- void unbind() {
- super.unbind();
- listeners.clear();
- }
-
public interface FolderListener {
public void onAdd(ShortcutInfo item);
public void onRemove(ShortcutInfo item);
diff --git a/src/com/android/launcher3/InfoDropTarget.java b/src/com/android/launcher3/InfoDropTarget.java
index 191becf..259370c 100644
--- a/src/com/android/launcher3/InfoDropTarget.java
+++ b/src/com/android/launcher3/InfoDropTarget.java
@@ -18,7 +18,9 @@
import android.content.ActivityNotFoundException;
import android.content.ComponentName;
+import android.content.ContentResolver;
import android.content.Context;
+import android.provider.Settings;
import android.util.AttributeSet;
import android.util.Log;
import android.widget.Toast;
@@ -92,7 +94,12 @@
}
public static boolean supportsDrop(ItemInfo info) {
- return info instanceof AppInfo || info instanceof ShortcutInfo
- || info instanceof PendingAddItemInfo || info instanceof LauncherAppWidgetInfo;
+ // Only show the App Info drop target if developer settings are enabled.
+ ContentResolver resolver = LauncherAppState.getInstance().getContext().getContentResolver();
+ boolean developmentSettingsEnabled = Settings.Global.getInt(resolver,
+ Settings.Global.DEVELOPMENT_SETTINGS_ENABLED, 0) == 1;
+ return developmentSettingsEnabled
+ && (info instanceof AppInfo || info instanceof ShortcutInfo
+ || info instanceof PendingAddItemInfo || info instanceof LauncherAppWidgetInfo);
}
}
diff --git a/src/com/android/launcher3/ItemInfo.java b/src/com/android/launcher3/ItemInfo.java
index 1ba09e1..286a7f1 100644
--- a/src/com/android/launcher3/ItemInfo.java
+++ b/src/com/android/launcher3/ItemInfo.java
@@ -183,15 +183,6 @@
}
}
- /**
- * It is very important that sub-classes implement this if they contain any references
- * to the activity (anything in the view hierarchy etc.). If not, leaks can result since
- * ItemInfo objects persist across rotation and can hence leak by holding stale references
- * to the old view hierarchy / activity.
- */
- void unbind() {
- }
-
@Override
public String toString() {
return "Item(id=" + this.id + " type=" + this.itemType + " container=" + this.container
diff --git a/src/com/android/launcher3/Launcher.java b/src/com/android/launcher3/Launcher.java
index eacf72a..a5ebb52 100644
--- a/src/com/android/launcher3/Launcher.java
+++ b/src/com/android/launcher3/Launcher.java
@@ -58,6 +58,7 @@
import android.graphics.Rect;
import android.graphics.drawable.ColorDrawable;
import android.graphics.drawable.Drawable;
+import android.net.Uri;
import android.os.AsyncTask;
import android.os.Build;
import android.os.Bundle;
@@ -112,9 +113,12 @@
import com.android.launcher3.logging.LoggerUtils;
import com.android.launcher3.logging.UserEventDispatcher;
import com.android.launcher3.model.WidgetsModel;
+import com.android.launcher3.pageindicators.PageIndicator;
+import com.android.launcher3.pageindicators.PageIndicatorLine;
import com.android.launcher3.userevent.nano.LauncherLogProto;
import com.android.launcher3.util.ComponentKey;
import com.android.launcher3.logging.FileLog;
+import com.android.launcher3.util.PackageManagerHelper;
import com.android.launcher3.util.TestingUtils;
import com.android.launcher3.util.Thunk;
import com.android.launcher3.util.ViewOnDrawExecutor;
@@ -198,6 +202,7 @@
private static final String QSB_WIDGET_PROVIDER = "qsb_widget_provider";
public static final String USER_HAS_MIGRATED = "launcher.user_migrated_from_old_data";
+ private static final String MIGRATE_AUTHORITY = "com.android.launcher2.settings";
/** The different states that Launcher can be in. */
enum State { NONE, WORKSPACE, WORKSPACE_SPRING_LOADED, APPS, APPS_SPRING_LOADED,
@@ -223,7 +228,7 @@
@Thunk Workspace mWorkspace;
private View mLauncherView;
- private View mPageIndicators;
+ private PageIndicatorLine mPageIndicator;
@Thunk DragLayer mDragLayer;
private DragController mDragController;
@@ -500,6 +505,7 @@
if (mExtractedColors != null && Utilities.isNycOrAbove()) {
mExtractedColors.load(this);
mHotseat.updateColor(mExtractedColors, !mPaused);
+ mPageIndicator.updateColor(mExtractedColors);
}
}
@@ -1326,7 +1332,7 @@
mFocusHandler = (FocusIndicatorView) findViewById(R.id.focus_indicator);
mDragLayer = (DragLayer) findViewById(R.id.drag_layer);
mWorkspace = (Workspace) mDragLayer.findViewById(R.id.workspace);
- mPageIndicators = mDragLayer.findViewById(R.id.page_indicator);
+ mPageIndicator = (PageIndicatorLine) mDragLayer.findViewById(R.id.page_indicator);
mLauncherView.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
| View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
@@ -1567,31 +1573,28 @@
if (!mRestoring) {
if (hostView == null) {
// Perform actual inflation because we're live
- launcherInfo.hostView = mAppWidgetHost.createView(this, appWidgetId,
- appWidgetInfo);
- } else {
- // The AppWidgetHostView has already been inflated and instantiated
- launcherInfo.hostView = hostView;
+ hostView = mAppWidgetHost.createView(this, appWidgetId, appWidgetInfo);
}
- launcherInfo.hostView.setVisibility(View.VISIBLE);
- addAppWidgetToWorkspace(launcherInfo, appWidgetInfo, isWorkspaceLocked());
+ hostView.setVisibility(View.VISIBLE);
+ addAppWidgetToWorkspace(hostView, launcherInfo, appWidgetInfo, isWorkspaceLocked());
}
resetAddInfo();
}
- private void addAppWidgetToWorkspace(LauncherAppWidgetInfo item,
+ private void addAppWidgetToWorkspace(
+ AppWidgetHostView hostView, LauncherAppWidgetInfo item,
LauncherAppWidgetProviderInfo appWidgetInfo, boolean insert) {
- item.hostView.setTag(item);
- item.onBindAppWidget(this);
+ hostView.setTag(item);
+ item.onBindAppWidget(this, hostView);
- item.hostView.setFocusable(true);
- item.hostView.setOnFocusChangeListener(mFocusHandler);
+ hostView.setFocusable(true);
+ hostView.setOnFocusChangeListener(mFocusHandler);
- mWorkspace.addInScreen(item.hostView, item.container, item.screenId,
+ mWorkspace.addInScreen(hostView, item.container, item.screenId,
item.cellX, item.cellY, item.spanX, item.spanY, insert);
if (!item.isCustomWidget()) {
- addWidgetToAutoAdvanceIfNeeded(item.hostView, appWidgetInfo);
+ addWidgetToAutoAdvanceIfNeeded(hostView, appWidgetInfo);
}
}
@@ -1969,6 +1972,7 @@
mHandler.removeMessages(ADVANCE_MSG);
mHandler.removeMessages(0);
mWorkspace.removeCallbacks(mBuildLayersRunnable);
+ mWorkspace.removeFolderListeners();
// Stop callbacks from LauncherModel
// It's possible to receive onDestroy after a new Launcher activity has
@@ -2367,6 +2371,9 @@
}
} else if (itemInfo instanceof FolderInfo) {
final FolderInfo folderInfo = (FolderInfo) itemInfo;
+ if (v instanceof FolderIcon) {
+ ((FolderIcon) v).removeListeners();
+ }
mWorkspace.removeWorkspaceItem(v);
if (deleteFromDb) {
LauncherModel.deleteFolderAndContentsFromDatabase(this, folderInfo);
@@ -2374,8 +2381,7 @@
} else if (itemInfo instanceof LauncherAppWidgetInfo) {
final LauncherAppWidgetInfo widgetInfo = (LauncherAppWidgetInfo) itemInfo;
mWorkspace.removeWorkspaceItem(v);
- removeWidgetToAutoAdvance(widgetInfo.hostView);
- widgetInfo.hostView = null;
+ removeWidgetToAutoAdvance(v);
if (deleteFromDb) {
deleteWidgetInfo(widgetInfo);
}
@@ -2719,10 +2725,17 @@
return;
}
- if (LOGD) Log.d(TAG, "onClickWallpaperPicker");
+ String pickerPackage = getString(R.string.wallpaper_picker_package);
+ if (TextUtils.isEmpty(pickerPackage)) {
+ pickerPackage = PackageManagerHelper.getWallpaperPickerPackage(getPackageManager());
+ }
+
int pageScroll = mWorkspace.getScrollForPage(mWorkspace.getPageNearestToCenterOfScreen());
float offset = mWorkspace.mWallpaperOffset.wallpaperOffsetForScroll(pageScroll);
- // TODO: Start the system wallpaper picker
+ startActivityForResult(new Intent(Intent.ACTION_SET_WALLPAPER)
+ .setPackage(pickerPackage)
+ .putExtra(Utilities.EXTRA_WALLPAPER_OFFSET, offset),
+ REQUEST_PICK_WALLPAPER);
}
/**
@@ -3860,10 +3873,9 @@
private void bindSafeModeWidget(LauncherAppWidgetInfo item) {
PendingAppWidgetHostView view = new PendingAppWidgetHostView(this, item, true);
view.updateIcon(mIconCache);
- item.hostView = view;
- item.hostView.updateAppWidget(null);
- item.hostView.setOnClickListener(this);
- addAppWidgetToWorkspace(item, null, false);
+ view.updateAppWidget(null);
+ view.setOnClickListener(this);
+ addAppWidgetToWorkspace(view, item, null, false);
mWorkspace.requestLayout();
}
@@ -3976,18 +3988,17 @@
return;
}
- item.hostView = mAppWidgetHost.createView(this, item.appWidgetId, appWidgetInfo);
item.minSpanX = appWidgetInfo.minSpanX;
item.minSpanY = appWidgetInfo.minSpanY;
- addAppWidgetToWorkspace(item, appWidgetInfo, false);
+ addAppWidgetToWorkspace(
+ mAppWidgetHost.createView(this, item.appWidgetId, appWidgetInfo),
+ item, appWidgetInfo, false);
} else {
- PendingAppWidgetHostView view = new PendingAppWidgetHostView(this, item,
- mIsSafeModeEnabled);
+ PendingAppWidgetHostView view = new PendingAppWidgetHostView(this, item, false);
view.updateIcon(mIconCache);
- item.hostView = view;
- item.hostView.updateAppWidget(null);
- item.hostView.setOnClickListener(this);
- addAppWidgetToWorkspace(item, null, false);
+ view.updateAppWidget(null);
+ view.setOnClickListener(this);
+ addAppWidgetToWorkspace(view, item, null, false);
}
mWorkspace.requestLayout();
@@ -4379,21 +4390,6 @@
}
}
- protected boolean isLauncherPreinstalled() {
- PackageManager pm = getPackageManager();
- try {
- ApplicationInfo ai = pm.getApplicationInfo(getComponentName().getPackageName(), 0);
- if ((ai.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
- return true;
- } else {
- return false;
- }
- } catch (NameNotFoundException e) {
- e.printStackTrace();
- return false;
- }
- }
-
/**
* To be overridden by subclasses to indicate that there is an activity to launch
* before showing the standard launcher experience.
@@ -4513,7 +4509,7 @@
LauncherClings launcherClings = new LauncherClings(this);
if (launcherClings.shouldShowFirstRunOrMigrationClings()) {
mClings = launcherClings;
- if (mModel.canMigrateFromOldLauncherDb(this)) {
+ if (canMigrateFromOldLauncherDb()) {
launcherClings.showMigrationCling();
} else {
launcherClings.showLongPressCling(true);
@@ -4521,10 +4517,23 @@
}
}
+ private boolean canMigrateFromOldLauncherDb() {
+ // Return true if launcher was not preinstalled and and old content provider exists.
+ return ((getApplicationInfo().flags & ApplicationInfo.FLAG_SYSTEM) == 0) &&
+ providerExists(MIGRATE_AUTHORITY) &&
+ providerExists(Uri.parse(getString(R.string.old_launcher_provider_uri)).getAuthority());
+
+ }
+
+ private boolean providerExists(String authority) {
+ return getPackageManager().resolveContentProvider(authority, 0) != null;
+ }
+
+
void showWorkspaceSearchAndHotseat() {
if (mWorkspace != null) mWorkspace.setAlpha(1f);
if (mHotseat != null) mHotseat.setAlpha(1f);
- if (mPageIndicators != null) mPageIndicators.setAlpha(1f);
+ if (mPageIndicator != null) mPageIndicator.setAlpha(1f);
if (mSearchDropTargetBar != null) mSearchDropTargetBar.animateToState(
SearchDropTargetBar.State.SEARCH_BAR, 0);
}
@@ -4532,7 +4541,7 @@
void hideWorkspaceSearchAndHotseat() {
if (mWorkspace != null) mWorkspace.setAlpha(0f);
if (mHotseat != null) mHotseat.setAlpha(0f);
- if (mPageIndicators != null) mPageIndicators.setAlpha(0f);
+ if (mPageIndicator != null) mPageIndicator.setAlpha(0f);
if (mSearchDropTargetBar != null) mSearchDropTargetBar.animateToState(
SearchDropTargetBar.State.INVISIBLE, 0);
}
diff --git a/src/com/android/launcher3/LauncherAppWidgetInfo.java b/src/com/android/launcher3/LauncherAppWidgetInfo.java
index 55edf45..42d6468 100644
--- a/src/com/android/launcher3/LauncherAppWidgetInfo.java
+++ b/src/com/android/launcher3/LauncherAppWidgetInfo.java
@@ -80,12 +80,6 @@
private boolean mHasNotifiedInitialWidgetSizeChanged;
- /**
- * View that holds this widget after it's been created. This view isn't created
- * until Launcher knows it's needed.
- */
- AppWidgetHostView hostView = null;
-
LauncherAppWidgetInfo(int appWidgetId, ComponentName providerName) {
if (appWidgetId == CUSTOM_WIDGET_ID) {
itemType = LauncherSettings.Favorites.ITEM_TYPE_CUSTOM_APPWIDGET;
@@ -121,25 +115,18 @@
* When we bind the widget, we should notify the widget that the size has changed if we have not
* done so already (only really for default workspace widgets).
*/
- void onBindAppWidget(Launcher launcher) {
+ void onBindAppWidget(Launcher launcher, AppWidgetHostView hostView) {
if (!mHasNotifiedInitialWidgetSizeChanged) {
AppWidgetResizeFrame.updateWidgetSizeRanges(hostView, launcher, spanX, spanY);
mHasNotifiedInitialWidgetSizeChanged = true;
}
}
-
@Override
public String toString() {
return "AppWidget(id=" + Integer.toString(appWidgetId) + ")";
}
- @Override
- void unbind() {
- super.unbind();
- hostView = null;
- }
-
public final boolean isWidgetIdValid() {
return (restoreStatus & FLAG_ID_NOT_VALID) == 0;
}
diff --git a/src/com/android/launcher3/LauncherClings.java b/src/com/android/launcher3/LauncherClings.java
index 9b8e894..1cfa3f7 100644
--- a/src/com/android/launcher3/LauncherClings.java
+++ b/src/com/android/launcher3/LauncherClings.java
@@ -22,7 +22,9 @@
import android.app.ActivityManager;
import android.content.Context;
import android.content.SharedPreferences;
+import android.content.pm.ApplicationInfo;
import android.graphics.drawable.Drawable;
+import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.os.UserManager;
@@ -48,9 +50,6 @@
private static final int SHOW_CLING_DURATION = 250;
private static final int DISMISS_CLING_DURATION = 200;
- // New Secure Setting in L
- private static final String SKIP_FIRST_USE_HINTS = "skip_first_use_hints";
-
@Thunk Launcher mLauncher;
private LayoutInflater mInflater;
@Thunk boolean mIsVisible;
@@ -262,8 +261,8 @@
return false;
}
}
- if (Settings.Secure.getInt(mLauncher.getContentResolver(), SKIP_FIRST_USE_HINTS, 0)
- == 1) {
+ if (Settings.Secure.getInt(mLauncher.getContentResolver(),
+ Settings.Secure.SKIP_FIRST_USE_HINTS, 0) == 1) {
return false;
}
return true;
diff --git a/src/com/android/launcher3/LauncherModel.java b/src/com/android/launcher3/LauncherModel.java
index eaeb1ac..fec96ca 100644
--- a/src/com/android/launcher3/LauncherModel.java
+++ b/src/com/android/launcher3/LauncherModel.java
@@ -28,7 +28,6 @@
import android.content.Intent.ShortcutIconResource;
import android.content.IntentFilter;
import android.content.pm.PackageManager;
-import android.content.pm.ProviderInfo;
import android.content.pm.ResolveInfo;
import android.database.Cursor;
import android.graphics.Bitmap;
@@ -56,15 +55,16 @@
import com.android.launcher3.dynamicui.ExtractionUtils;
import com.android.launcher3.folder.Folder;
import com.android.launcher3.folder.FolderIcon;
+import com.android.launcher3.logging.FileLog;
import com.android.launcher3.model.GridSizeMigrationTask;
import com.android.launcher3.model.WidgetsModel;
import com.android.launcher3.util.ComponentKey;
import com.android.launcher3.util.CursorIconInfo;
-import com.android.launcher3.logging.FileLog;
import com.android.launcher3.util.FlagOp;
import com.android.launcher3.util.LongArrayMap;
import com.android.launcher3.util.ManagedProfileHeuristic;
import com.android.launcher3.util.PackageManagerHelper;
+import com.android.launcher3.util.Preconditions;
import com.android.launcher3.util.StringFilter;
import com.android.launcher3.util.Thunk;
import com.android.launcher3.util.ViewOnDrawExecutor;
@@ -104,8 +104,6 @@
private static final int ITEMS_CHUNK = 6; // batch size for the workspace icons
private static final long INVALID_SCREEN_ID = -1L;
- private final boolean mOldContentProviderExists;
-
@Thunk final LauncherAppState mApp;
@Thunk final Object mLock = new Object();
@Thunk DeferredHandler mHandler = new DeferredHandler();
@@ -113,8 +111,6 @@
@Thunk boolean mIsLoaderTaskRunning;
@Thunk boolean mHasLoaderCompletedOnce;
- private static final String MIGRATE_AUTHORITY = "com.android.launcher2.settings";
-
@Thunk static final HandlerThread sWorkerThread = new HandlerThread("launcher-loader");
static {
sWorkerThread.start();
@@ -215,25 +211,6 @@
LauncherModel(LauncherAppState app, IconCache iconCache, AppFilter appFilter) {
Context context = app.getContext();
-
- String oldProvider = context.getString(R.string.old_launcher_provider_uri);
- // This may be the same as MIGRATE_AUTHORITY, or it may be replaced by a different
- // resource string.
- String redirectAuthority = Uri.parse(oldProvider).getAuthority();
- ProviderInfo providerInfo =
- context.getPackageManager().resolveContentProvider(MIGRATE_AUTHORITY, 0);
- ProviderInfo redirectProvider =
- context.getPackageManager().resolveContentProvider(redirectAuthority, 0);
-
- Log.d(TAG, "Old launcher provider: " + oldProvider);
- mOldContentProviderExists = (providerInfo != null) && (redirectProvider != null);
-
- if (mOldContentProviderExists) {
- Log.d(TAG, "Old launcher provider exists.");
- } else {
- Log.d(TAG, "Old launcher provider does not exist.");
- }
-
mApp = app;
mBgAllAppsList = new AllAppsList(iconCache, appFilter);
mBgWidgetsModel = new WidgetsModel(context, iconCache, appFilter);
@@ -265,10 +242,6 @@
}
}
- boolean canMigrateFromOldLauncherDb(Launcher launcher) {
- return mOldContentProviderExists && !launcher.isLauncherPreinstalled() ;
- }
-
public void setPackageState(final PackageInstallInfo installInfo) {
Runnable updateRunnable = new Runnable() {
@@ -578,38 +551,6 @@
runOnWorkerThread(r);
}
- private void unbindItemInfosAndClearQueuedBindRunnables() {
- if (sWorkerThread.getThreadId() == Process.myTid()) {
- throw new RuntimeException("Expected unbindLauncherItemInfos() to be called from the " +
- "main thread");
- }
-
- // Remove any queued UI runnables
- mHandler.cancelAll();
- // Unbind all the workspace items
- unbindWorkspaceItemsOnMainThread();
- }
-
- /** Unbinds all the sBgWorkspaceItems and sBgAppWidgets on the main thread */
- void unbindWorkspaceItemsOnMainThread() {
- // Ensure that we don't use the same workspace items data structure on the main thread
- // by making a copy of workspace items first.
- final ArrayList<ItemInfo> tmpItems = new ArrayList<ItemInfo>();
- synchronized (sBgLock) {
- tmpItems.addAll(sBgWorkspaceItems);
- tmpItems.addAll(sBgAppWidgets);
- }
- Runnable r = new Runnable() {
- @Override
- public void run() {
- for (ItemInfo item : tmpItems) {
- item.unbind();
- }
- }
- };
- runOnMainThread(r);
- }
-
/**
* Adds an item to the DB if it was not created previously, or move it to a new
* <container, screen, cellX, cellY>
@@ -1137,10 +1078,10 @@
*/
public void initialize(Callbacks callbacks) {
synchronized (mLock) {
- // Disconnect any of the callbacks and drawables associated with ItemInfos on the
- // workspace to prevent leaking Launcher activities on orientation change.
- unbindItemInfosAndClearQueuedBindRunnables();
- mCallbacks = new WeakReference<Callbacks>(callbacks);
+ Preconditions.assertUIThread();
+ // Remove any queued UI runnables
+ mHandler.cancelAll();
+ mCallbacks = new WeakReference<>(callbacks);
}
}
@@ -2482,10 +2423,6 @@
final long currentScreenId = currentScreen < 0
? INVALID_SCREEN_ID : orderedScreenIds.get(currentScreen);
- // Load all the items that are on the current page first (and in the process, unbind
- // all the existing workspace items before we call startBinding() below.
- unbindWorkspaceItemsOnMainThread();
-
// Separate the items that are on the current screen, and all the other remaining items
ArrayList<ItemInfo> currentWorkspaceItems = new ArrayList<>();
ArrayList<ItemInfo> otherWorkspaceItems = new ArrayList<>();
diff --git a/src/com/android/launcher3/LauncherProvider.java b/src/com/android/launcher3/LauncherProvider.java
index 5cc5aa6..7ebee31 100644
--- a/src/com/android/launcher3/LauncherProvider.java
+++ b/src/com/android/launcher3/LauncherProvider.java
@@ -323,28 +323,6 @@
createDbIfNotExists();
switch (method) {
- case LauncherSettings.Settings.METHOD_GET_BOOLEAN: {
- Bundle result = new Bundle();
- if (Utilities.ALLOW_ROTATION_PREFERENCE_KEY.equals(arg)) {
- result.putBoolean(LauncherSettings.Settings.EXTRA_VALUE,
- Utilities.isAllowRotationPrefEnabled(getContext()));
- } else {
- result.putBoolean(LauncherSettings.Settings.EXTRA_VALUE,
- Utilities.getPrefs(getContext()).getBoolean(arg, extras.getBoolean(
- LauncherSettings.Settings.EXTRA_DEFAULT_VALUE)));
- }
- return result;
- }
- case LauncherSettings.Settings.METHOD_SET_BOOLEAN: {
- final boolean value = extras.getBoolean(LauncherSettings.Settings.EXTRA_VALUE);
- Utilities.getPrefs(getContext()).edit().putBoolean(arg, value).apply();
- if (extras.getBoolean(LauncherSettings.Settings.NOTIFY_BACKUP)) {
- LauncherBackupAgentHelper.dataChanged(getContext());
- }
- Bundle result = new Bundle();
- result.putBoolean(LauncherSettings.Settings.EXTRA_VALUE, value);
- return result;
- }
case LauncherSettings.Settings.METHOD_SET_EXTRACTED_COLORS_AND_WALLPAPER_ID: {
String extractedColors = extras.getString(
LauncherSettings.Settings.EXTRA_EXTRACTED_COLORS);
diff --git a/src/com/android/launcher3/LauncherSettings.java b/src/com/android/launcher3/LauncherSettings.java
index 095670d..45a87cc 100644
--- a/src/com/android/launcher3/LauncherSettings.java
+++ b/src/com/android/launcher3/LauncherSettings.java
@@ -277,8 +277,6 @@
public static final Uri CONTENT_URI = Uri.parse("content://" +
ProviderConfig.AUTHORITY + "/settings");
- public static final String METHOD_GET_BOOLEAN = "get_boolean_setting";
- public static final String METHOD_SET_BOOLEAN = "set_boolean_setting";
public static final String METHOD_CLEAR_EMPTY_DB_FLAG = "clear_empty_db_flag";
public static final String METHOD_DELETE_EMPTY_FOLDERS = "delete_empty_folders";
@@ -301,9 +299,6 @@
public static final String EXTRA_WALLPAPER_ID = "extra_wallpaperId";
public static final String EXTRA_VALUE = "value";
- public static final String EXTRA_DEFAULT_VALUE = "default_value";
- // Extra for set_boolean method to also notify the backup manager of the change.
- public static final String NOTIFY_BACKUP = "notify_backup";
public static Bundle call(ContentResolver cr, String method) {
return cr.call(CONTENT_URI, method, null, null);
diff --git a/src/com/android/launcher3/PagedView.java b/src/com/android/launcher3/PagedView.java
index e1cb082..02e894b 100644
--- a/src/com/android/launcher3/PagedView.java
+++ b/src/com/android/launcher3/PagedView.java
@@ -49,8 +49,11 @@
import android.view.accessibility.AccessibilityManager;
import android.view.accessibility.AccessibilityNodeInfo;
import android.view.animation.Interpolator;
+
+import com.android.launcher3.pageindicators.PageIndicator;
import com.android.launcher3.util.LauncherEdgeEffect;
import com.android.launcher3.util.Thunk;
+
import java.util.ArrayList;
/**
@@ -254,8 +257,7 @@
mPageIndicator = (PageIndicator) grandParent.findViewById(mPageIndicatorViewId);
mPageIndicator.removeAllMarkers(true);
- ArrayList<PageIndicator.PageMarkerResources> markers =
- new ArrayList<PageIndicator.PageMarkerResources>();
+ ArrayList<PageIndicator.PageMarkerResources> markers = new ArrayList<>();
for (int i = 0; i < getChildCount(); ++i) {
markers.add(getPageIndicatorMarker(i));
}
@@ -264,9 +266,9 @@
OnClickListener listener = getPageIndicatorClickListener();
if (listener != null) {
- mPageIndicator.setOnClickListener(listener);
+ mPageIndicator.getView().setOnClickListener(listener);
}
- mPageIndicator.setContentDescription(getPageIndicatorDescription());
+ mPageIndicator.getView().setContentDescription(getPageIndicatorDescription());
}
}
@@ -355,7 +357,8 @@
return mPageIndicator;
}
protected PageIndicator.PageMarkerResources getPageIndicatorMarker(int pageIndex) {
- return new PageIndicator.PageMarkerResources();
+ return new PageIndicator.PageMarkerResources(R.drawable.ic_pageindicator_current,
+ R.drawable.ic_pageindicator_default);
}
/**
@@ -430,7 +433,7 @@
Math.min(newPage, mTempVisiblePagesRange[1]));
}
// Ensure that it is clamped by the actual set of children in all cases
- validatedPage = Utilities.boundInRange(validatedPage, 0, getPageCount() - 1);
+ validatedPage = Utilities.boundToRange(validatedPage, 0, getPageCount() - 1);
return validatedPage;
}
@@ -475,7 +478,7 @@
private void updatePageIndicator() {
// Update the page indicator (when we aren't reordering)
if (mPageIndicator != null) {
- mPageIndicator.setContentDescription(getPageIndicatorDescription());
+ mPageIndicator.getView().setContentDescription(getPageIndicatorDescription());
if (!isReordering(false)) {
mPageIndicator.setActiveMarker(getNextPage());
}
@@ -931,12 +934,16 @@
}
@Thunk void updateMaxScrollX() {
+ mMaxScrollX = computeMaxScrollX();
+ }
+
+ protected int computeMaxScrollX() {
int childCount = getChildCount();
if (childCount > 0) {
final int index = mIsRtl ? 0 : childCount - 1;
- mMaxScrollX = getScrollForPage(index);
+ return getScrollForPage(index);
} else {
- mMaxScrollX = 0;
+ return 0;
}
}
diff --git a/src/com/android/launcher3/PinchAnimationManager.java b/src/com/android/launcher3/PinchAnimationManager.java
index c8c8fa4..477b92c 100644
--- a/src/com/android/launcher3/PinchAnimationManager.java
+++ b/src/com/android/launcher3/PinchAnimationManager.java
@@ -194,7 +194,7 @@
animateShowHideView(INDEX_HOTSEAT, mLauncher.getHotseat(), show);
if (mWorkspace.getPageIndicator() != null) {
// There aren't page indicators in landscape mode on phones, hence the null check.
- animateShowHideView(INDEX_PAGE_INDICATOR, mWorkspace.getPageIndicator(), show);
+ animateShowHideView(INDEX_PAGE_INDICATOR, mWorkspace.getPageIndicator().getView(), show);
}
}
diff --git a/src/com/android/launcher3/SettingsActivity.java b/src/com/android/launcher3/SettingsActivity.java
index 4135d5b..5ef6dd5 100644
--- a/src/com/android/launcher3/SettingsActivity.java
+++ b/src/com/android/launcher3/SettingsActivity.java
@@ -17,13 +17,14 @@
package com.android.launcher3;
import android.app.Activity;
-import android.os.AsyncTask;
+import android.content.ContentResolver;
+import android.database.ContentObserver;
import android.os.Bundle;
+import android.os.Handler;
import android.preference.Preference;
-import android.preference.Preference.OnPreferenceChangeListener;
import android.preference.PreferenceFragment;
-import android.preference.PreferenceScreen;
-import android.preference.TwoStatePreference;
+import android.provider.Settings;
+import android.provider.Settings.System;
/**
* Settings activity for Launcher. Currently implements the following setting: Allow rotation
@@ -42,56 +43,70 @@
/**
* This fragment shows the launcher preferences.
*/
- public static class LauncherSettingsFragment extends PreferenceFragment
- implements OnPreferenceChangeListener {
+ public static class LauncherSettingsFragment extends PreferenceFragment {
+
+ private SystemDisplayRotationLockObserver mRotationLockObserver;
+
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
+ getPreferenceManager().setSharedPreferencesName(LauncherFiles.SHARED_PREFERENCES_KEY);
addPreferencesFromResource(R.xml.launcher_preferences);
- PreferenceScreen screen = getPreferenceScreen();
- for (int i = screen.getPreferenceCount() - 1; i >= 0; i--) {
- Preference pref = screen.getPreference(i);
- if (pref instanceof TwoStatePreference) {
- setBooleanPrefUsingContentProvider((TwoStatePreference) pref);
- }
+ // Setup allow rotation preference
+ Preference rotationPref = findPreference(Utilities.ALLOW_ROTATION_PREFERENCE_KEY);
+ if (getResources().getBoolean(R.bool.allow_rotation)) {
+ // Launcher supports rotation by default. No need to show this setting.
+ getPreferenceScreen().removePreference(rotationPref);
+ } else {
+ ContentResolver resolver = getContext().getContentResolver();
+ mRotationLockObserver = new SystemDisplayRotationLockObserver(rotationPref, resolver);
+
+ // Register a content observer to listen for system setting changes while
+ // this UI is active.
+ resolver.registerContentObserver(
+ Settings.System.getUriFor(System.ACCELEROMETER_ROTATION),
+ false, mRotationLockObserver);
+
+ // Initialize the UI once
+ mRotationLockObserver.onChange(true);
+ rotationPref.setDefaultValue(Utilities.getAllowRotationDefaultValue(getContext()));
}
}
@Override
- public boolean onPreferenceChange(Preference preference, Object newValue) {
- Bundle extras = new Bundle();
- extras.putBoolean(LauncherSettings.Settings.EXTRA_VALUE, (Boolean) newValue);
- getActivity().getContentResolver().call(
- LauncherSettings.Settings.CONTENT_URI,
- LauncherSettings.Settings.METHOD_SET_BOOLEAN,
- preference.getKey(), extras);
- return true;
+ public void onDestroy() {
+ if (mRotationLockObserver != null) {
+ getContext().getContentResolver().unregisterContentObserver(mRotationLockObserver);
+ mRotationLockObserver = null;
+ }
+ super.onDestroy();
+ }
+ }
+
+ /**
+ * Content observer which listens for system auto-rotate setting changes, and enables/disables
+ * the launcher rotation setting accordingly.
+ */
+ private static class SystemDisplayRotationLockObserver extends ContentObserver {
+
+ private final Preference mRotationPref;
+ private final ContentResolver mResolver;
+
+ public SystemDisplayRotationLockObserver(
+ Preference rotationPref, ContentResolver resolver) {
+ super(new Handler());
+ mRotationPref = rotationPref;
+ mResolver = resolver;
}
- private void setBooleanPrefUsingContentProvider(final TwoStatePreference pref) {
- pref.setPersistent(false);
- pref.setEnabled(false);
-
- new AsyncTask<Void, Void, Boolean>() {
- @Override
- protected Boolean doInBackground(Void... params) {
- Bundle extras = new Bundle();
- extras.putBoolean(LauncherSettings.Settings.EXTRA_DEFAULT_VALUE, true);
- Bundle value = pref.getContext().getContentResolver().call(
- LauncherSettings.Settings.CONTENT_URI,
- LauncherSettings.Settings.METHOD_GET_BOOLEAN,
- pref.getKey(), extras);
- return value.getBoolean(LauncherSettings.Settings.EXTRA_VALUE);
- }
-
- @Override
- protected void onPostExecute(Boolean aBoolean) {
- pref.setChecked(aBoolean);
- pref.setEnabled(true);
- pref.setOnPreferenceChangeListener(LauncherSettingsFragment.this);
- }
- }.execute();
+ @Override
+ public void onChange(boolean selfChange) {
+ boolean enabled = Settings.System.getInt(mResolver,
+ Settings.System.ACCELEROMETER_ROTATION, 1) == 1;
+ mRotationPref.setEnabled(enabled);
+ mRotationPref.setSummary(enabled
+ ? R.string.allow_rotation_desc : R.string.allow_rotation_blocked_desc);
}
}
}
diff --git a/src/com/android/launcher3/Utilities.java b/src/com/android/launcher3/Utilities.java
index c5f601d..e3b959b 100644
--- a/src/com/android/launcher3/Utilities.java
+++ b/src/com/android/launcher3/Utilities.java
@@ -142,7 +142,11 @@
}
public static boolean isAllowRotationPrefEnabled(Context context) {
- boolean allowRotationPref = false;
+ return getPrefs(context).getBoolean(ALLOW_ROTATION_PREFERENCE_KEY,
+ getAllowRotationDefaultValue(context));
+ }
+
+ public static boolean getAllowRotationDefaultValue(Context context) {
if (isNycOrAbove()) {
// If the device was scaled, used the original dimensions to determine if rotation
// is allowed of not.
@@ -153,13 +157,12 @@
Resources res = context.getResources();
int originalSmallestWidth = res.getConfiguration().smallestScreenWidthDp
* res.getDisplayMetrics().densityDpi / originalDensity;
- allowRotationPref = originalSmallestWidth >= 600;
+ return originalSmallestWidth >= 600;
} catch (Exception e) {
// Ignore
}
}
-
- return getPrefs(context).getBoolean(ALLOW_ROTATION_PREFERENCE_KEY, allowRotationPref);
+ return false;
}
public static boolean isNycOrAbove() {
@@ -795,7 +798,14 @@
* If value is less than lowerBound, return lowerBound; else if value is greater than upperBound,
* return upperBound; else return value unchanged.
*/
- public static int boundInRange(int value, int lowerBound, int upperBound) {
+ public static int boundToRange(int value, int lowerBound, int upperBound) {
+ return Math.max(lowerBound, Math.min(value, upperBound));
+ }
+
+ /**
+ * @see #boundToRange(int, int, int).
+ */
+ public static float boundToRange(float value, float lowerBound, float upperBound) {
return Math.max(lowerBound, Math.min(value, upperBound));
}
diff --git a/src/com/android/launcher3/Workspace.java b/src/com/android/launcher3/Workspace.java
index 88e5251..386e016 100644
--- a/src/com/android/launcher3/Workspace.java
+++ b/src/com/android/launcher3/Workspace.java
@@ -73,6 +73,7 @@
import com.android.launcher3.folder.Folder;
import com.android.launcher3.folder.FolderIcon;
import com.android.launcher3.logging.UserEventDispatcher;
+import com.android.launcher3.pageindicators.PageIndicator;
import com.android.launcher3.userevent.nano.LauncherLogProto;
import com.android.launcher3.userevent.nano.LauncherLogProto.Target;
import com.android.launcher3.util.LongArrayMap;
@@ -1096,10 +1097,11 @@
for (int j = 0; j < itemCount; j++) {
View v = swc.getChildAt(j);
- if (v != null && v.getTag() instanceof LauncherAppWidgetInfo) {
+ if (v instanceof LauncherAppWidgetHostView
+ && v.getTag() instanceof LauncherAppWidgetInfo) {
LauncherAppWidgetInfo info = (LauncherAppWidgetInfo) v.getTag();
- LauncherAppWidgetHostView lahv = (LauncherAppWidgetHostView) info.hostView;
- if (lahv != null && lahv.isReinflateRequired()) {
+ LauncherAppWidgetHostView lahv = (LauncherAppWidgetHostView) v;
+ if (lahv.isReinflateRequired()) {
// Remove and rebind the current widget (which was inflated in the wrong
// orientation), but don't delete it from the database
mLauncher.removeItem(lahv, info, false /* deleteFromDb */);
@@ -1272,6 +1274,22 @@
}
@Override
+ protected void onScrollChanged(int l, int t, int oldl, int oldt) {
+ super.onScrollChanged(l, t, oldl, oldt);
+
+ // Update the page indicator progress.
+ boolean isTransitioning = mIsSwitchingState
+ || (getLayoutTransition() != null && getLayoutTransition().isRunning());
+ if (mPageIndicator != null && !isTransitioning) {
+ showPageIndicatorAtCurrentScroll();
+ }
+ }
+
+ private void showPageIndicatorAtCurrentScroll() {
+ mPageIndicator.setProgress((float) getScrollX() / computeMaxScrollX());
+ }
+
+ @Override
protected void overScroll(float amount) {
boolean shouldOverScroll = (amount <= 0 && (!hasCustomContent() || mIsRtl)) ||
(amount >= 0 && (!hasCustomContent() || !mIsRtl));
@@ -1324,7 +1342,7 @@
// different effects based on device performance. On at least one relatively high-end
// device I've tried, translating the launcher causes things to get quite laggy.
setTranslationAndAlpha(mLauncher.getSearchDropTargetBar(), transX, alpha);
- setTranslationAndAlpha(getPageIndicator(), transX, alpha);
+ setTranslationAndAlpha(getPageIndicator().getView(), transX, alpha);
setTranslationAndAlpha(getChildAt(getCurrentPage()), transX, alpha);
setTranslationAndAlpha(mLauncher.getHotseat(), transX, alpha);
@@ -1537,7 +1555,7 @@
}
if (getPageIndicator() != null) {
- getPageIndicator().setTranslationX(translationX);
+ getPageIndicator().getView().setTranslationX(translationX);
}
if (mCustomContentCallbacks != null) {
@@ -1586,8 +1604,10 @@
// attach to window
OnClickListener listener = getPageIndicatorClickListener();
if (listener != null) {
- getPageIndicator().setOnClickListener(listener);
+ getPageIndicator().getView().setOnClickListener(listener);
}
+
+ showPageIndicatorAtCurrentScroll();
}
// Update wallpaper dimensions if they were changed since last onResume
@@ -1738,8 +1758,8 @@
super.getVisiblePages(range);
if (mForceDrawAdjacentPages) {
// In overview mode, make sure that the two side pages are visible.
- range[0] = Utilities.boundInRange(getCurrentPage() - 1, numCustomPages(), range[1]);
- range[1] = Utilities.boundInRange(getCurrentPage() + 1, range[0], getPageCount() - 1);
+ range[0] = Utilities.boundToRange(getCurrentPage() - 1, numCustomPages(), range[1]);
+ range[1] = Utilities.boundToRange(getCurrentPage() + 1, range[0], getPageCount() - 1);
}
}
@@ -2005,6 +2025,9 @@
updateChildrenLayersEnabled(false);
showCustomContentIfNecessary();
mForceDrawAdjacentPages = false;
+ if (mState == State.NORMAL || mState == State.SPRING_LOADED) {
+ showPageIndicatorAtCurrentScroll();
+ }
}
void updateCustomContentVisibility() {
@@ -3668,6 +3691,21 @@
}
}
+ /**
+ * Removes all folder listeners
+ */
+ public void removeFolderListeners() {
+ mapOverItems(false, new ItemOperator() {
+ @Override
+ public boolean evaluate(ItemInfo info, View view) {
+ if (view instanceof FolderIcon) {
+ ((FolderIcon) view).removeListeners();
+ }
+ return false;
+ }
+ });
+ }
+
@Override
public void deferCompleteDropAfterUninstallActivity() {
mDeferDropAfterUninstall = true;
@@ -4156,7 +4194,7 @@
});
}
- public void widgetsRestored(ArrayList<LauncherAppWidgetInfo> changedInfo) {
+ public void widgetsRestored(final ArrayList<LauncherAppWidgetInfo> changedInfo) {
if (!changedInfo.isEmpty()) {
DeferredWidgetRefresh widgetRefresh = new DeferredWidgetRefresh(changedInfo,
mLauncher.getAppWidgetHost());
@@ -4177,12 +4215,18 @@
} else {
// widgetRefresh will automatically run when the packages are updated.
// For now just update the progress bars
- for (LauncherAppWidgetInfo info : changedInfo) {
- if (info.hostView instanceof PendingAppWidgetHostView) {
- info.installProgress = 100;
- ((PendingAppWidgetHostView) info.hostView).applyState();
+ mapOverItems(MAP_NO_RECURSE, new ItemOperator() {
+ @Override
+ public boolean evaluate(ItemInfo info, View view) {
+ if (view instanceof PendingAppWidgetHostView
+ && changedInfo.contains(info)) {
+ ((LauncherAppWidgetInfo) info).installProgress = 100;
+ ((PendingAppWidgetHostView) view).applyState();
+ }
+ // process all the shortcuts
+ return false;
}
- }
+ });
}
}
}
@@ -4310,14 +4354,18 @@
mRefreshPending = false;
- for (LauncherAppWidgetInfo info : mInfos) {
- if (info.hostView instanceof PendingAppWidgetHostView) {
- // Remove and rebind the current widget, but don't delete it from the database
- PendingAppWidgetHostView view = (PendingAppWidgetHostView) info.hostView;
- mLauncher.removeItem(view, info, false /* deleteFromDb */);
- mLauncher.bindAppWidget(info);
+ mapOverItems(MAP_NO_RECURSE, new ItemOperator() {
+ @Override
+ public boolean evaluate(ItemInfo info, View view) {
+ if (view instanceof PendingAppWidgetHostView && mInfos.contains(info)) {
+ PendingAppWidgetHostView hostView = (PendingAppWidgetHostView) view;
+ mLauncher.removeItem(view, info, false /* deleteFromDb */);
+ mLauncher.bindAppWidget((LauncherAppWidgetInfo) info);
+ }
+ // process all the shortcuts
+ return false;
}
- }
+ });
}
}
}
diff --git a/src/com/android/launcher3/WorkspaceStateTransitionAnimation.java b/src/com/android/launcher3/WorkspaceStateTransitionAnimation.java
index c0eb7ed..60070a8 100644
--- a/src/com/android/launcher3/WorkspaceStateTransitionAnimation.java
+++ b/src/com/android/launcher3/WorkspaceStateTransitionAnimation.java
@@ -288,7 +288,7 @@
float finalBackgroundAlpha = (states.stateIsSpringLoaded || states.stateIsOverview) ?
1.0f : 0f;
float finalHotseatAlpha = (states.stateIsNormal || states.stateIsSpringLoaded) ? 1f : 0f;
- float finalPageIndicatorAlpha = states.stateIsNormal ? 1f : 0f;
+ float finalPageIndicatorAlpha = finalHotseatAlpha;
float finalOverviewPanelAlpha = states.stateIsOverview ? 1f : 0f;
float finalWorkspaceTranslationY = 0;
@@ -357,7 +357,7 @@
final ViewGroup overviewPanel = mLauncher.getOverviewPanel();
final View hotseat = mLauncher.getHotseat();
- final View pageIndicator = mWorkspace.getPageIndicator();
+ final View pageIndicator = mWorkspace.getPageIndicator().getView();
if (animated) {
LauncherViewPropertyAnimator scale = new LauncherViewPropertyAnimator(mWorkspace);
scale.scaleX(mNewScale)
diff --git a/src/com/android/launcher3/folder/FolderIcon.java b/src/com/android/launcher3/folder/FolderIcon.java
index 1e4eb7f..157a970 100644
--- a/src/com/android/launcher3/folder/FolderIcon.java
+++ b/src/com/android/launcher3/folder/FolderIcon.java
@@ -1000,6 +1000,11 @@
mLongPressHelper.cancelLongPress();
}
+ public void removeListeners() {
+ mInfo.removeListener(this);
+ mInfo.removeListener(mFolder);
+ }
+
public interface PreviewLayoutRule {
public PreviewItemDrawingParams computePreviewItemDrawingParams(int index, int curNumItems,
PreviewItemDrawingParams params);
diff --git a/src/com/android/launcher3/folder/FolderPagedView.java b/src/com/android/launcher3/folder/FolderPagedView.java
index 1af1485..e1a1431 100644
--- a/src/com/android/launcher3/folder/FolderPagedView.java
+++ b/src/com/android/launcher3/folder/FolderPagedView.java
@@ -39,8 +39,8 @@
import com.android.launcher3.Launcher;
import com.android.launcher3.LauncherAppState;
import com.android.launcher3.LauncherModel;
-import com.android.launcher3.PageIndicator;
-import com.android.launcher3.PageIndicator.PageMarkerResources;
+import com.android.launcher3.pageindicators.PageIndicatorDots;
+import com.android.launcher3.pageindicators.PageIndicator.PageMarkerResources;
import com.android.launcher3.PagedView;
import com.android.launcher3.R;
import com.android.launcher3.ShortcutAndWidgetContainer;
@@ -103,7 +103,7 @@
private FocusIndicatorView mFocusIndicatorView;
private PagedFolderKeyEventListener mKeyListener;
- private PageIndicator mPageIndicator;
+ private PageIndicatorDots mPageIndicator;
public FolderPagedView(Context context, AttributeSet attrs) {
super(context, attrs);
@@ -128,7 +128,7 @@
mFolder = folder;
mFocusIndicatorView = (FocusIndicatorView) folder.findViewById(R.id.focus_indicator);
mKeyListener = new PagedFolderKeyEventListener(folder);
- mPageIndicator = (PageIndicator) folder.findViewById(R.id.folder_page_indicator);
+ mPageIndicator = (PageIndicatorDots) folder.findViewById(R.id.folder_page_indicator);
}
/**
diff --git a/src/com/android/launcher3/pageindicators/PageIndicator.java b/src/com/android/launcher3/pageindicators/PageIndicator.java
new file mode 100644
index 0000000..6348b12
--- /dev/null
+++ b/src/com/android/launcher3/pageindicators/PageIndicator.java
@@ -0,0 +1,31 @@
+package com.android.launcher3.pageindicators;
+
+import android.view.View;
+
+import java.util.ArrayList;
+
+public interface PageIndicator {
+ View getView();
+ void setProgress(float progress);
+
+ void removeAllMarkers(boolean allowAnimations);
+ void addMarkers(ArrayList<PageMarkerResources> markers, boolean allowAnimations);
+ void setActiveMarker(int activePage);
+ void addMarker(int pageIndex, PageMarkerResources pageIndicatorMarker, boolean allowAnimations);
+ void removeMarker(int pageIndex, boolean allowAnimations);
+ void updateMarker(int pageIndex, PageMarkerResources pageIndicatorMarker);
+
+ /**
+ * Contains two resource ids for each page indicator marker (e.g. dots):
+ * one for when the page is active and one for when the page is inactive.
+ */
+ class PageMarkerResources {
+ int activeId;
+ int inactiveId;
+
+ public PageMarkerResources(int aId, int iaId) {
+ activeId = aId;
+ inactiveId = iaId;
+ }
+ }
+}
diff --git a/src/com/android/launcher3/PageIndicatorMarker.java b/src/com/android/launcher3/pageindicators/PageIndicatorDot.java
similarity index 89%
rename from src/com/android/launcher3/PageIndicatorMarker.java
rename to src/com/android/launcher3/pageindicators/PageIndicatorDot.java
index 7bf21dd..5ed3426 100644
--- a/src/com/android/launcher3/PageIndicatorMarker.java
+++ b/src/com/android/launcher3/pageindicators/PageIndicatorDot.java
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package com.android.launcher3;
+package com.android.launcher3.pageindicators;
import android.content.Context;
import android.content.res.Resources;
@@ -22,7 +22,9 @@
import android.widget.FrameLayout;
import android.widget.ImageView;
-public class PageIndicatorMarker extends FrameLayout {
+import com.android.launcher3.R;
+
+public class PageIndicatorDot extends FrameLayout {
@SuppressWarnings("unused")
private static final String TAG = "PageIndicator";
@@ -32,15 +34,15 @@
private ImageView mInactiveMarker;
private boolean mIsActive = false;
- public PageIndicatorMarker(Context context) {
+ public PageIndicatorDot(Context context) {
this(context, null);
}
- public PageIndicatorMarker(Context context, AttributeSet attrs) {
+ public PageIndicatorDot(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
- public PageIndicatorMarker(Context context, AttributeSet attrs, int defStyle) {
+ public PageIndicatorDot(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
diff --git a/src/com/android/launcher3/PageIndicator.java b/src/com/android/launcher3/pageindicators/PageIndicatorDots.java
similarity index 77%
rename from src/com/android/launcher3/PageIndicator.java
rename to src/com/android/launcher3/pageindicators/PageIndicatorDots.java
index 8adbf8d..a488f02 100644
--- a/src/com/android/launcher3/PageIndicator.java
+++ b/src/com/android/launcher3/pageindicators/PageIndicatorDots.java
@@ -14,19 +14,22 @@
* limitations under the License.
*/
-package com.android.launcher3;
+package com.android.launcher3.pageindicators;
import android.animation.LayoutTransition;
import android.content.Context;
import android.content.res.TypedArray;
import android.util.AttributeSet;
import android.view.LayoutInflater;
+import android.view.View;
import android.view.ViewDebug;
import android.widget.LinearLayout;
+import com.android.launcher3.R;
+
import java.util.ArrayList;
-public class PageIndicator extends LinearLayout {
+public class PageIndicatorDots extends LinearLayout implements PageIndicator {
@SuppressWarnings("unused")
private static final String TAG = "PageIndicator";
// Want this to look good? Keep it odd
@@ -36,38 +39,23 @@
private int[] mWindowRange = new int[2];
private int mMaxWindowSize;
- private ArrayList<PageIndicatorMarker> mMarkers =
- new ArrayList<PageIndicatorMarker>();
+ private ArrayList<PageIndicatorDot> mMarkers = new ArrayList<>();
@ViewDebug.ExportedProperty(category = "launcher")
private int mActiveMarkerIndex;
- public static class PageMarkerResources {
- int activeId;
- int inactiveId;
-
- public PageMarkerResources() {
- activeId = R.drawable.ic_pageindicator_current;
- inactiveId = R.drawable.ic_pageindicator_default;
- }
- public PageMarkerResources(int aId, int iaId) {
- activeId = aId;
- inactiveId = iaId;
- }
- }
-
- public PageIndicator(Context context) {
+ public PageIndicatorDots(Context context) {
this(context, null);
}
- public PageIndicator(Context context, AttributeSet attrs) {
+ public PageIndicatorDots(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
- public PageIndicator(Context context, AttributeSet attrs, int defStyle) {
+ public PageIndicatorDots(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
TypedArray a = context.obtainStyledAttributes(attrs,
- R.styleable.PageIndicator, defStyle, 0);
- mMaxWindowSize = a.getInteger(R.styleable.PageIndicator_windowSize, 15);
+ R.styleable.PageIndicatorDots, defStyle, 0);
+ mMaxWindowSize = a.getInteger(R.styleable.PageIndicatorDots_windowSize, 15);
mWindowRange[0] = 0;
mWindowRange[1] = 0;
mLayoutInflater = LayoutInflater.from(context);
@@ -94,7 +82,7 @@
transition.disableTransitionType(LayoutTransition.CHANGE_DISAPPEARING);
}
- void offsetWindowCenterTo(int activeIndex, boolean allowAnimations) {
+ public void offsetWindowCenterTo(int activeIndex, boolean allowAnimations) {
if (activeIndex < 0) {
new Throwable().printStackTrace();
}
@@ -116,7 +104,7 @@
// Remove all the previous children that are no longer in the window
for (int i = getChildCount() - 1; i >= 0; --i) {
- PageIndicatorMarker marker = (PageIndicatorMarker) getChildAt(i);
+ PageIndicatorDot marker = (PageIndicatorDot) getChildAt(i);
int markerIndex = mMarkers.indexOf(marker);
if (markerIndex < windowStart || markerIndex >= windowEnd) {
removeView(marker);
@@ -125,7 +113,7 @@
// Add all the new children that belong in the window
for (int i = 0; i < mMarkers.size(); ++i) {
- PageIndicatorMarker marker = (PageIndicatorMarker) mMarkers.get(i);
+ PageIndicatorDot marker = (PageIndicatorDot) mMarkers.get(i);
if (windowStart <= i && i < windowEnd) {
if (indexOfChild(marker) < 0) {
addView(marker, i - windowStart);
@@ -161,58 +149,75 @@
mWindowRange[1] = windowEnd;
}
- void addMarker(int index, PageMarkerResources marker, boolean allowAnimations) {
+ @Override
+ public void addMarker(int index, PageMarkerResources marker, boolean allowAnimations) {
index = Math.max(0, Math.min(index, mMarkers.size()));
- PageIndicatorMarker m =
- (PageIndicatorMarker) mLayoutInflater.inflate(R.layout.page_indicator_marker,
+ PageIndicatorDot m =
+ (PageIndicatorDot) mLayoutInflater.inflate(R.layout.page_indicator_marker,
this, false);
m.setMarkerDrawables(marker.activeId, marker.inactiveId);
mMarkers.add(index, m);
offsetWindowCenterTo(mActiveMarkerIndex, allowAnimations);
}
- void addMarkers(ArrayList<PageMarkerResources> markers, boolean allowAnimations) {
+
+ @Override
+ public void addMarkers(ArrayList<PageMarkerResources> markers, boolean allowAnimations) {
for (int i = 0; i < markers.size(); ++i) {
addMarker(Integer.MAX_VALUE, markers.get(i), allowAnimations);
}
}
- void updateMarker(int index, PageMarkerResources marker) {
- PageIndicatorMarker m = mMarkers.get(index);
+ @Override
+ public void updateMarker(int index, PageMarkerResources marker) {
+ PageIndicatorDot m = mMarkers.get(index);
m.setMarkerDrawables(marker.activeId, marker.inactiveId);
}
- void removeMarker(int index, boolean allowAnimations) {
+ @Override
+ public void removeMarker(int index, boolean allowAnimations) {
if (mMarkers.size() > 0) {
index = Math.max(0, Math.min(mMarkers.size() - 1, index));
mMarkers.remove(index);
offsetWindowCenterTo(mActiveMarkerIndex, allowAnimations);
}
}
- void removeAllMarkers(boolean allowAnimations) {
+
+ @Override
+ public View getView() {
+ return this;
+ }
+
+ @Override
+ public void setProgress(float progress) {
+ }
+
+ @Override
+ public void removeAllMarkers(boolean allowAnimations) {
while (mMarkers.size() > 0) {
removeMarker(Integer.MAX_VALUE, allowAnimations);
}
}
- void setActiveMarker(int index) {
+ @Override
+ public void setActiveMarker(int index) {
// Center the active marker
mActiveMarkerIndex = index;
offsetWindowCenterTo(index, false);
}
- void dumpState(String txt) {
+ private void dumpState(String txt) {
System.out.println(txt);
System.out.println("\tmMarkers: " + mMarkers.size());
for (int i = 0; i < mMarkers.size(); ++i) {
- PageIndicatorMarker m = mMarkers.get(i);
+ PageIndicatorDot m = mMarkers.get(i);
System.out.println("\t\t(" + i + ") " + m);
}
System.out.println("\twindow: [" + mWindowRange[0] + ", " + mWindowRange[1] + "]");
System.out.println("\tchildren: " + getChildCount());
for (int i = 0; i < getChildCount(); ++i) {
- PageIndicatorMarker m = (PageIndicatorMarker) getChildAt(i);
+ PageIndicatorDot m = (PageIndicatorDot) getChildAt(i);
System.out.println("\t\t(" + i + ") " + m);
}
System.out.println("\tactive: " + mActiveMarkerIndex);
diff --git a/src/com/android/launcher3/pageindicators/PageIndicatorLine.java b/src/com/android/launcher3/pageindicators/PageIndicatorLine.java
new file mode 100644
index 0000000..449bf06
--- /dev/null
+++ b/src/com/android/launcher3/pageindicators/PageIndicatorLine.java
@@ -0,0 +1,187 @@
+package com.android.launcher3.pageindicators;
+
+import android.animation.Animator;
+import android.animation.AnimatorListenerAdapter;
+import android.animation.ObjectAnimator;
+import android.animation.ValueAnimator;
+import android.content.Context;
+import android.graphics.Canvas;
+import android.graphics.Color;
+import android.graphics.Paint;
+import android.os.Handler;
+import android.os.Looper;
+import android.support.v4.graphics.ColorUtils;
+import android.util.AttributeSet;
+import android.util.Log;
+import android.util.Property;
+import android.view.View;
+import android.view.ViewConfiguration;
+
+import com.android.launcher3.Utilities;
+import com.android.launcher3.dynamicui.ExtractedColors;
+
+import java.util.ArrayList;
+
+/**
+ * A PageIndicator that briefly shows a fraction of a line when moving between pages.
+ *
+ * The fraction is 1 / number of pages and the position is based on the progress of the page scroll.
+ */
+public class PageIndicatorLine extends View implements PageIndicator {
+ private static final String TAG = "PageIndicatorLine";
+
+ private static final int LINE_FADE_DURATION = ViewConfiguration.getScrollBarFadeDuration();
+ private static final int LINE_FADE_DELAY = ViewConfiguration.getScrollDefaultDelay();
+ public static final int WHITE_ALPHA = (int) (0.70f * 255);
+ public static final int BLACK_ALPHA = (int) (0.65f * 255);
+
+ private final Handler mHandler = new Handler(Looper.getMainLooper());
+
+ private ValueAnimator mLineAlphaAnimator;
+ private int mAlpha = 0;
+ private float mProgress = 0f;
+ private int mNumPages = 1;
+ private Paint mLinePaint;
+
+ private Property<Paint, Integer> mPaintAlphaProperty
+ = new Property<Paint, Integer>(Integer.class, "paint_alpha") {
+ @Override
+ public Integer get(Paint paint) {
+ return paint.getAlpha();
+ }
+
+ @Override
+ public void set(Paint paint, Integer alpha) {
+ paint.setAlpha(alpha);
+ invalidate();
+ }
+ };
+
+ private Runnable mHideLineRunnable = new Runnable() {
+ @Override
+ public void run() {
+ animateLineToAlpha(0);
+ }
+ };
+
+ public PageIndicatorLine(Context context) {
+ this(context, null);
+ }
+
+ public PageIndicatorLine(Context context, AttributeSet attrs) {
+ this(context, attrs, 0);
+ }
+
+ public PageIndicatorLine(Context context, AttributeSet attrs, int defStyle) {
+ super(context, attrs, defStyle);
+ mLinePaint = new Paint();
+ mLinePaint.setAlpha(0);
+ }
+
+ @Override
+ protected void onDraw(Canvas canvas) {
+ super.onDraw(canvas);
+
+ if (mNumPages == 0) {
+ return;
+ }
+
+ int availableWidth = canvas.getWidth();
+ int lineWidth = availableWidth / mNumPages;
+ int lineLeft = (int) (mProgress * (availableWidth - lineWidth));
+ int lineRight = lineLeft + lineWidth;
+ canvas.drawRect(lineLeft, 0, lineRight, canvas.getHeight(), mLinePaint);
+ }
+
+ @Override
+ public View getView() {
+ return this;
+ }
+
+ @Override
+ public void setProgress(float progress) {
+ if (getAlpha() == 0) {
+ return;
+ }
+ progress = Utilities.boundToRange(progress, 0f, 1f);
+ animateLineToAlpha(mAlpha);
+ mProgress = progress;
+ invalidate();
+
+ // Hide after a brief period.
+ mHandler.removeCallbacksAndMessages(null);
+ mHandler.postDelayed(mHideLineRunnable, LINE_FADE_DELAY);
+ }
+
+ @Override
+ public void removeAllMarkers(boolean allowAnimations) {
+ mNumPages = 0;
+ }
+
+ @Override
+ public void addMarkers(ArrayList<PageMarkerResources> markers, boolean allowAnimations) {
+ mNumPages += markers.size();
+ }
+
+ @Override
+ public void setActiveMarker(int activePage) {
+ }
+
+ @Override
+ public void addMarker(int pageIndex, PageMarkerResources pageIndicatorMarker,
+ boolean allowAnimations) {
+ mNumPages++;
+ }
+
+ @Override
+ public void removeMarker(int pageIndex, boolean allowAnimations) {
+ mNumPages--;
+ }
+
+ @Override
+ public void updateMarker(int pageIndex, PageMarkerResources pageIndicatorMarker) {
+ }
+
+ /**
+ * The line's color will be:
+ * - mostly opaque white if the hotseat is white (ignoring alpha)
+ * - mostly opaque black if the hotseat is black (ignoring alpha)
+ */
+ public void updateColor(ExtractedColors extractedColors) {
+ int originalLineAlpha = mLinePaint.getAlpha();
+ int color = extractedColors.getColor(ExtractedColors.HOTSEAT_INDEX, Color.TRANSPARENT);
+ if (color != Color.TRANSPARENT) {
+ color = ColorUtils.setAlphaComponent(color, 255);
+ if (color == Color.BLACK) {
+ mAlpha = BLACK_ALPHA;
+ } else if (color == Color.WHITE) {
+ mAlpha = WHITE_ALPHA;
+ } else {
+ Log.e(TAG, "Setting workspace page indicators to an unsupported color: #"
+ + Integer.toHexString(color));
+ }
+ mLinePaint.setColor(color);
+ mLinePaint.setAlpha(originalLineAlpha);
+ }
+ }
+
+ private void animateLineToAlpha(int alpha) {
+ if (mLineAlphaAnimator != null) {
+ // An animation is already running, so ignore the new animation request unless we are
+ // trying to hide the line, in which case we always allow the animation.
+ if (alpha != 0) {
+ return;
+ }
+ mLineAlphaAnimator.cancel();
+ }
+ mLineAlphaAnimator = ObjectAnimator.ofInt(mLinePaint, mPaintAlphaProperty, alpha);
+ mLineAlphaAnimator.addListener(new AnimatorListenerAdapter() {
+ @Override
+ public void onAnimationEnd(Animator animation) {
+ mLineAlphaAnimator = null;
+ }
+ });
+ mLineAlphaAnimator.setDuration(LINE_FADE_DURATION);
+ mLineAlphaAnimator.start();
+ }
+}
diff --git a/src/com/android/launcher3/util/PackageManagerHelper.java b/src/com/android/launcher3/util/PackageManagerHelper.java
index 08e8e86..3c4c79a 100644
--- a/src/com/android/launcher3/util/PackageManagerHelper.java
+++ b/src/com/android/launcher3/util/PackageManagerHelper.java
@@ -16,17 +16,22 @@
package com.android.launcher3.util;
+import android.content.Intent;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
+import android.content.pm.ResolveInfo;
import com.android.launcher3.Utilities;
+import java.util.ArrayList;
+
/**
* Utility methods using package manager
*/
public class PackageManagerHelper {
private static final int FLAG_SUSPENDED = 1<<30;
+ private static final String LIVE_WALLPAPER_PICKER_PKG = "com.android.wallpaper.livepicker";
/**
* Returns true if the app can possibly be on the SDCard. This is just a workaround and doesn't
@@ -68,4 +73,27 @@
return false;
}
}
+
+ /**
+ * Returns the package for a wallpaper picker system app giving preference to a app which
+ * is not as image picker.
+ */
+ public static String getWallpaperPickerPackage(PackageManager pm) {
+ ArrayList<String> excludePackages = new ArrayList<>();
+ // Exclude packages which contain an image picker
+ for (ResolveInfo info : pm.queryIntentActivities(
+ new Intent(Intent.ACTION_GET_CONTENT).setType("image/*"), 0)) {
+ excludePackages.add(info.activityInfo.packageName);
+ }
+ excludePackages.add(LIVE_WALLPAPER_PICKER_PKG);
+
+ for (ResolveInfo info : pm.queryIntentActivities(
+ new Intent(Intent.ACTION_SET_WALLPAPER), 0)) {
+ if (!excludePackages.contains(info.activityInfo.packageName) &&
+ (info.activityInfo.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
+ return info.activityInfo.packageName;
+ }
+ }
+ return excludePackages.get(0);
+ }
}