Merge "Moving the scrim to draglayer" into ub-launcher3-calgary-polish
diff --git a/AndroidManifest-common.xml b/AndroidManifest-common.xml
index 3da3535..bbe1f4a 100644
--- a/AndroidManifest-common.xml
+++ b/AndroidManifest-common.xml
@@ -50,7 +50,7 @@
android:fullBackupContent="@xml/backupscheme"
android:hardwareAccelerated="true"
android:icon="@mipmap/ic_launcher_home"
- android:label="@string/app_name"
+ android:label="@string/derived_app_name"
android:largeHeap="@bool/config_largeHeap"
android:restoreAnyVersion="true"
android:supportsRtl="true" >
diff --git a/res/values/config.xml b/res/values/config.xml
index 94f02f9..2347f66 100644
--- a/res/values/config.xml
+++ b/res/values/config.xml
@@ -9,6 +9,10 @@
<bool name="is_large_tablet">false</bool>
<bool name="allow_rotation">false</bool>
+ <!-- A string pointer to the original app name string. This allows derived projects to
+ easily override the app name without providing all translations -->
+ <string name="derived_app_name" translatable="false">@string/app_name</string>
+
<!-- DragController -->
<item type="id" name="drag_event_parity" />
diff --git a/src/com/android/launcher3/DeviceProfile.java b/src/com/android/launcher3/DeviceProfile.java
index 15f47b4..e6802bd 100644
--- a/src/com/android/launcher3/DeviceProfile.java
+++ b/src/com/android/launcher3/DeviceProfile.java
@@ -589,9 +589,9 @@
return new int[] {0, 0};
}
- // In landscape, we just match the vertical display width
- int containerWidth = heightPx;
- int padding = (availableWidthPx - containerWidth) / 2;
+ // In landscape, we match the width of the workspace
+ int padding = (pageIndicatorLandGutterRightNavBarPx +
+ hotseatBarHeightPx + hotseatLandGutterPx + mInsets.left) / 2;
return new int[]{ padding, padding };
}
}
diff --git a/src/com/android/launcher3/Hotseat.java b/src/com/android/launcher3/Hotseat.java
index ceaedef..c738480 100644
--- a/src/com/android/launcher3/Hotseat.java
+++ b/src/com/android/launcher3/Hotseat.java
@@ -16,6 +16,8 @@
package com.android.launcher3;
+import android.animation.Animator;
+import android.animation.AnimatorListenerAdapter;
import android.animation.ArgbEvaluator;
import android.animation.ValueAnimator;
import android.content.Context;
@@ -52,6 +54,7 @@
private int mBackgroundColor;
@ViewDebug.ExportedProperty(category = "launcher")
private ColorDrawable mBackground;
+ private ValueAnimator mBackgroundColorAnimator;
public Hotseat(Context context) {
this(context, null);
@@ -177,18 +180,27 @@
public void updateColor(ExtractedColors extractedColors, boolean animate) {
if (!mHasVerticalHotseat) {
int color = extractedColors.getColor(ExtractedColors.HOTSEAT_INDEX, Color.TRANSPARENT);
+ if (mBackgroundColorAnimator != null) {
+ mBackgroundColorAnimator.cancel();
+ }
if (!animate) {
setBackgroundColor(color);
} else {
- ValueAnimator animator = ValueAnimator.ofInt(mBackgroundColor, color);
- animator.setEvaluator(new ArgbEvaluator());
- animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
+ mBackgroundColorAnimator = ValueAnimator.ofInt(mBackgroundColor, color);
+ mBackgroundColorAnimator.setEvaluator(new ArgbEvaluator());
+ mBackgroundColorAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
mBackground.setColor((Integer) animation.getAnimatedValue());
}
});
- animator.start();
+ mBackgroundColorAnimator.addListener(new AnimatorListenerAdapter() {
+ @Override
+ public void onAnimationEnd(Animator animation) {
+ mBackgroundColorAnimator = null;
+ }
+ });
+ mBackgroundColorAnimator.start();
}
mBackgroundColor = color;
}
diff --git a/src/com/android/launcher3/Launcher.java b/src/com/android/launcher3/Launcher.java
index 3d35b1b..f125287 100644
--- a/src/com/android/launcher3/Launcher.java
+++ b/src/com/android/launcher3/Launcher.java
@@ -865,7 +865,7 @@
} else {
// TODO: Show a snack bar with link to settings
Toast.makeText(this, getString(R.string.msg_no_phone_permission,
- getString(R.string.app_name)), Toast.LENGTH_SHORT).show();
+ getString(R.string.derived_app_name)), Toast.LENGTH_SHORT).show();
}
}
if (mLauncherCallbacks != null) {
@@ -2760,8 +2760,10 @@
*/
public void onClickSettingsButton(View v) {
if (LOGD) Log.d(TAG, "onClickSettingsButton");
- startActivity(new Intent(Utilities.ACTION_APPLICATION_PREFERENCES)
- .setPackage(getPackageName()));
+ Intent intent = new Intent(Intent.ACTION_APPLICATION_PREFERENCES)
+ .setPackage(getPackageName());
+ intent.setSourceBounds(getViewBounds(v));
+ startActivity(intent, getActivityLaunchOptions(v));
}
public View.OnTouchListener getHapticFeedbackTouchListener() {
diff --git a/src/com/android/launcher3/LauncherModel.java b/src/com/android/launcher3/LauncherModel.java
index d4223e1..1607a4a 100644
--- a/src/com/android/launcher3/LauncherModel.java
+++ b/src/com/android/launcher3/LauncherModel.java
@@ -862,7 +862,9 @@
Intent targetIntent = info.promisedIntent == null
? info.intent : info.promisedIntent;
if (targetIntent != null && info.user.equals(user)) {
- String s = targetIntent.toUri(0);
+ Intent copyIntent = new Intent(targetIntent);
+ copyIntent.setSourceBounds(intent.getSourceBounds());
+ String s = copyIntent.toUri(0);
if (intentWithPkg.equals(s) || intentWithoutPkg.equals(s)) {
return true;
}
diff --git a/src/com/android/launcher3/Utilities.java b/src/com/android/launcher3/Utilities.java
index 50f7156..2988fb9 100644
--- a/src/com/android/launcher3/Utilities.java
+++ b/src/com/android/launcher3/Utilities.java
@@ -183,10 +183,6 @@
}
}
- // TODO: Use Intent.ACTION_APPLICATION_PREFERENCES when N SDK is available.
- public static final String ACTION_APPLICATION_PREFERENCES
- = "android.intent.action.APPLICATION_PREFERENCES";
-
public static Bitmap createIconBitmap(Cursor c, int iconIndex, Context context) {
byte[] data = c.getBlob(iconIndex);
try {
diff --git a/src/com/android/launcher3/model/GridSizeMigrationTask.java b/src/com/android/launcher3/model/GridSizeMigrationTask.java
index 600768e..fd647c7 100644
--- a/src/com/android/launcher3/model/GridSizeMigrationTask.java
+++ b/src/com/android/launcher3/model/GridSizeMigrationTask.java
@@ -974,6 +974,26 @@
}
/**
+ * Removes any broken item from the hotseat.
+ * @return a map with occupied hotseat position set to non-null value.
+ */
+ public static LongArrayMap<Object> removeBrokenHotseatItems(Context context) throws Exception {
+ GridSizeMigrationTask task = new GridSizeMigrationTask(context,
+ LauncherAppState.getInstance().getInvariantDeviceProfile(),
+ getValidPackages(context), Integer.MAX_VALUE, Integer.MAX_VALUE);
+
+ // Load all the valid entries
+ ArrayList<DbEntry> items = task.loadHotseatEntries();
+ // Delete any entry marked for deletion by above load.
+ task.applyOperations();
+ LongArrayMap<Object> positions = new LongArrayMap<>();
+ for (DbEntry item : items) {
+ positions.put(item.screenId, item);
+ }
+ return positions;
+ }
+
+ /**
* Task to run grid migration in multiple steps when the size difference is more than 1.
*/
protected static class MultiStepMigrationTask {
diff --git a/src/com/android/launcher3/model/WidgetItem.java b/src/com/android/launcher3/model/WidgetItem.java
index b3f0c82..0d7ba1e 100644
--- a/src/com/android/launcher3/model/WidgetItem.java
+++ b/src/com/android/launcher3/model/WidgetItem.java
@@ -68,6 +68,17 @@
return thisWorkProfile ? 1 : -1;
}
- return sCollator.compare(label, another.label);
+ int labelCompare = sCollator.compare(label, another.label);
+ if (labelCompare != 0) {
+ return labelCompare;
+ }
+
+ // If the label is same, put the smaller widget before the larger widget. If the area is
+ // also same, put the widget with smaller height before.
+ int thisArea = spanX * spanY;
+ int otherArea = another.spanX * another.spanY;
+ return thisArea == otherArea
+ ? Integer.compare(spanY, another.spanY)
+ : Integer.compare(thisArea, otherArea);
}
}
diff --git a/src/com/android/launcher3/provider/ImportDataTask.java b/src/com/android/launcher3/provider/ImportDataTask.java
index 233c3ed..5cb34e8 100644
--- a/src/com/android/launcher3/provider/ImportDataTask.java
+++ b/src/com/android/launcher3/provider/ImportDataTask.java
@@ -148,7 +148,6 @@
// Set of package names present in hotseat
final HashSet<String> hotseatTargetApps = new HashSet<>();
- final LongArrayMap<Intent> hotseatItems = new LongArrayMap<>();
int maxId = 0;
// Number of imported items on workspace and hotseat
@@ -270,7 +269,6 @@
if (intent.getComponent() != null) {
intent.setPackage(intent.getComponent().getPackageName());
}
- hotseatItems.put(screen, intent);
hotseatTargetApps.add(getPackage(intent));
}
@@ -299,7 +297,13 @@
if (totalItemsOnWorkspace < MIN_ITEM_COUNT_FOR_SUCCESSFUL_MIGRATION) {
throw new Exception("Insufficient data");
}
+ if (!insertOperations.isEmpty()) {
+ mContext.getContentResolver().applyBatch(ProviderConfig.AUTHORITY,
+ insertOperations);
+ insertOperations.clear();
+ }
+ LongArrayMap<Object> hotseatItems = GridSizeMigrationTask.removeBrokenHotseatItems(mContext);
int myHotseatCount = LauncherAppState.getInstance().getInvariantDeviceProfile().numHotseatIcons;
if (!FeatureFlags.NO_ALL_APPS_ICON) {
myHotseatCount--;
@@ -307,14 +311,15 @@
if (hotseatItems.size() < myHotseatCount) {
// Insufficient hotseat items. Add a few more.
HotseatParserCallback parserCallback = new HotseatParserCallback(
- hotseatTargetApps, hotseatItems, insertOperations, maxId + 1);
+ hotseatTargetApps, hotseatItems, insertOperations, maxId + 1, myHotseatCount);
new HotseatLayoutParser(mContext,
parserCallback).loadLayout(null, new ArrayList<Long>());
mHotseatSize = (int) hotseatItems.keyAt(hotseatItems.size() - 1) + 1;
- }
- if (!insertOperations.isEmpty()) {
- mContext.getContentResolver().applyBatch(ProviderConfig.AUTHORITY,
- insertOperations);
+
+ if (!insertOperations.isEmpty()) {
+ mContext.getContentResolver().applyBatch(ProviderConfig.AUTHORITY,
+ insertOperations);
+ }
}
}
@@ -404,16 +409,18 @@
*/
private static class HotseatParserCallback implements LayoutParserCallback {
private final HashSet<String> mExisitingApps;
- private final LongArrayMap<Intent> mExistingItems;
+ private final LongArrayMap<Object> mExistingItems;
private final ArrayList<ContentProviderOperation> mOutOps;
+ private final int mRequiredSize;
private int mStartItemId;
HotseatParserCallback(
- HashSet<String> existingApps, LongArrayMap<Intent> existingItems,
- ArrayList<ContentProviderOperation> outOps, int startItemId) {
+ HashSet<String> existingApps, LongArrayMap<Object> existingItems,
+ ArrayList<ContentProviderOperation> outOps, int startItemId, int requiredSize) {
mExisitingApps = existingApps;
mExistingItems = existingItems;
mOutOps = outOps;
+ mRequiredSize = requiredSize;
mStartItemId = startItemId;
}
@@ -424,6 +431,10 @@
@Override
public long insertAndCheck(SQLiteDatabase db, ContentValues values) {
+ if (mExistingItems.size() >= mRequiredSize) {
+ // No need to add more items.
+ return 0;
+ }
Intent intent;
try {
intent = Intent.parseUri(values.getAsString(Favorites.INTENT), 0);
diff --git a/src/com/android/launcher3/util/ComponentKey.java b/src/com/android/launcher3/util/ComponentKey.java
index 144b411..5882f21 100644
--- a/src/com/android/launcher3/util/ComponentKey.java
+++ b/src/com/android/launcher3/util/ComponentKey.java
@@ -32,8 +32,8 @@
private final int mHashCode;
public ComponentKey(ComponentName componentName, UserHandleCompat user) {
- assert (componentName != null);
- assert (user != null);
+ Preconditions.assertNotNull(componentName);
+ Preconditions.assertNotNull(user);
this.componentName = componentName;
this.user = user;
mHashCode = Arrays.hashCode(new Object[] {componentName, user});
@@ -58,6 +58,8 @@
componentName = ComponentName.unflattenFromString(componentKeyStr);
user = UserHandleCompat.myUserHandle();
}
+ Preconditions.assertNotNull(componentName);
+ Preconditions.assertNotNull(user);
mHashCode = Arrays.hashCode(new Object[] {componentName, user});
}
diff --git a/src/com/android/launcher3/util/Preconditions.java b/src/com/android/launcher3/util/Preconditions.java
index 3760c63..89353e1 100644
--- a/src/com/android/launcher3/util/Preconditions.java
+++ b/src/com/android/launcher3/util/Preconditions.java
@@ -26,6 +26,12 @@
*/
public class Preconditions {
+ public static void assertNotNull(Object o) {
+ if (ProviderConfig.IS_DOGFOOD_BUILD && o == null) {
+ throw new IllegalStateException();
+ }
+ }
+
public static void assertWorkerThread() {
if (ProviderConfig.IS_DOGFOOD_BUILD && !isSameLooper(LauncherModel.getWorkerLooper())) {
throw new IllegalStateException();