Merge "ComponentName null check MUST proceed before creating ComponentKey." into ub-launcher3-calgary-polish
diff --git a/src/com/android/launcher3/Alarm.java b/src/com/android/launcher3/Alarm.java
index e9f1fd9..d5b434c 100644
--- a/src/com/android/launcher3/Alarm.java
+++ b/src/com/android/launcher3/Alarm.java
@@ -17,6 +17,7 @@
package com.android.launcher3;
import android.os.Handler;
+import android.os.SystemClock;
public class Alarm implements Runnable{
// if we reach this time and the alarm hasn't been cancelled, call the listener
@@ -41,9 +42,16 @@
// Sets the alarm to go off in a certain number of milliseconds. If the alarm is already set,
// it's overwritten and only the new alarm setting is used
public void setAlarm(long millisecondsInFuture) {
- long currentTime = System.currentTimeMillis();
+ long currentTime = SystemClock.uptimeMillis();
mAlarmPending = true;
+ long oldTriggerTime = mAlarmTriggerTime;
mAlarmTriggerTime = currentTime + millisecondsInFuture;
+
+ // If the previous alarm was set for a longer duration, cancel it.
+ if (mWaitingForCallback && oldTriggerTime > mAlarmTriggerTime) {
+ mHandler.removeCallbacks(this);
+ mWaitingForCallback = false;
+ }
if (!mWaitingForCallback) {
mHandler.postDelayed(this, mAlarmTriggerTime - currentTime);
mWaitingForCallback = true;
@@ -51,15 +59,14 @@
}
public void cancelAlarm() {
- mAlarmTriggerTime = 0;
mAlarmPending = false;
}
// this is called when our timer runs out
public void run() {
mWaitingForCallback = false;
- if (mAlarmTriggerTime != 0) {
- long currentTime = System.currentTimeMillis();
+ if (mAlarmPending) {
+ long currentTime = SystemClock.uptimeMillis();
if (mAlarmTriggerTime > currentTime) {
// We still need to wait some time to trigger spring loaded mode--
// post a new callback
diff --git a/src/com/android/launcher3/Launcher.java b/src/com/android/launcher3/Launcher.java
index 340c670..c919db8 100644
--- a/src/com/android/launcher3/Launcher.java
+++ b/src/com/android/launcher3/Launcher.java
@@ -2932,7 +2932,8 @@
try {
if (Utilities.ATLEAST_MARSHMALLOW && item != null
&& (item.itemType == Favorites.ITEM_TYPE_SHORTCUT
- || item.itemType == Favorites.ITEM_TYPE_DEEP_SHORTCUT)) {
+ || item.itemType == Favorites.ITEM_TYPE_DEEP_SHORTCUT)
+ && ((ShortcutInfo) item).promisedIntent == null) {
// Shortcuts need some special checks due to legacy reasons.
startShortcutIntentSafely(intent, optsBundle, item);
} else if (user == null || user.equals(UserHandleCompat.myUserHandle())) {
@@ -4242,7 +4243,7 @@
for (ShortcutInfo si : removed) {
if (si.itemType == Favorites.ITEM_TYPE_DEEP_SHORTCUT) {
- removedDeepShortcuts.add(ShortcutKey.fromItemInfo(si));
+ removedDeepShortcuts.add(ShortcutKey.fromShortcutInfo(si));
} else {
removedComponents.add(si.getTargetComponent());
}
diff --git a/src/com/android/launcher3/LauncherModel.java b/src/com/android/launcher3/LauncherModel.java
index 1607a4a..68450e7 100644
--- a/src/com/android/launcher3/LauncherModel.java
+++ b/src/com/android/launcher3/LauncherModel.java
@@ -103,7 +103,6 @@
implements LauncherAppsCompat.OnAppsChangedCallbackCompat {
static final boolean DEBUG_LOADERS = false;
private static final boolean DEBUG_RECEIVER = false;
- private static final boolean REMOVE_UNRESTORED_ICONS = true;
static final String TAG = "Launcher.Model";
@@ -931,7 +930,8 @@
}
if (item.itemType == LauncherSettings.Favorites.ITEM_TYPE_DEEP_SHORTCUT) {
incrementPinnedShortcutCount(
- ShortcutKey.fromItemInfo(item), true /* shouldPin */);
+ ShortcutKey.fromShortcutInfo((ShortcutInfo) item),
+ true /* shouldPin */);
}
break;
case LauncherSettings.Favorites.ITEM_TYPE_APPWIDGET:
@@ -1000,7 +1000,8 @@
sBgWorkspaceItems.remove(item);
break;
case LauncherSettings.Favorites.ITEM_TYPE_DEEP_SHORTCUT:
- decrementPinnedShortcutCount(ShortcutKey.fromItemInfo(item));
+ decrementPinnedShortcutCount(ShortcutKey.fromShortcutInfo(
+ (ShortcutInfo) item));
// Fall through.
case LauncherSettings.Favorites.ITEM_TYPE_APPLICATION:
case LauncherSettings.Favorites.ITEM_TYPE_SHORTCUT:
@@ -1881,12 +1882,12 @@
restored = false;
itemReplaced = true;
- } else if (REMOVE_UNRESTORED_ICONS) {
+ } else {
FileLog.d(TAG, "Unrestored package removed: " + cn);
itemsToRemove.add(id);
continue;
}
- } else if (REMOVE_UNRESTORED_ICONS) {
+ } else {
FileLog.d(TAG, "Unrestored package removed: " + cn);
itemsToRemove.add(id);
continue;
@@ -2168,7 +2169,7 @@
// App restore has started. Update the flag
appWidgetInfo.restoreStatus |=
LauncherAppWidgetInfo.FLAG_RESTORE_STARTED;
- } else if (REMOVE_UNRESTORED_ICONS && !isSafeMode) {
+ } else if (!isSafeMode) {
FileLog.d(TAG, "Unrestored widget removed: " + component);
itemsToRemove.add(id);
continue;
@@ -3389,7 +3390,8 @@
for (ItemInfo itemInfo : sBgItemsIdMap) {
if (itemInfo.itemType == LauncherSettings.Favorites.ITEM_TYPE_DEEP_SHORTCUT) {
ShortcutInfo si = (ShortcutInfo) itemInfo;
- if (si.getIntent().getPackage().equals(mPackageName) && si.user.equals(mUser)) {
+ if (si.getPromisedIntent().getPackage().equals(mPackageName)
+ && si.user.equals(mUser)) {
String shortcutId = si.getDeepShortcutId();
if (idsToShortcuts.containsKey(shortcutId)) {
idsToWorkspaceShortcutInfos.addToList(shortcutId, si);
@@ -3462,7 +3464,7 @@
ShortcutInfo si = (ShortcutInfo) itemInfo;
if (isUserUnlocked) {
ShortcutInfoCompat shortcut =
- pinnedShortcuts.get(ShortcutKey.fromItemInfo(si));
+ pinnedShortcuts.get(ShortcutKey.fromShortcutInfo(si));
// We couldn't verify the shortcut during loader. If its no longer available
// (probably due to clear data), delete the workspace item as well
if (shortcut == null) {
diff --git a/src/com/android/launcher3/ShortcutInfo.java b/src/com/android/launcher3/ShortcutInfo.java
index 8c466b2..21fa8a0 100644
--- a/src/com/android/launcher3/ShortcutInfo.java
+++ b/src/com/android/launcher3/ShortcutInfo.java
@@ -167,6 +167,11 @@
return intent;
}
+ /** Returns {@link #promisedIntent}, or {@link #intent} if promisedIntent is null. */
+ public Intent getPromisedIntent() {
+ return promisedIntent != null ? promisedIntent : intent;
+ }
+
ShortcutInfo(Intent intent, CharSequence title, CharSequence contentDescription,
Bitmap icon, UserHandleCompat user) {
this();
@@ -349,7 +354,7 @@
/** Returns the ShortcutInfo id associated with the deep shortcut. */
public String getDeepShortcutId() {
return itemType == Favorites.ITEM_TYPE_DEEP_SHORTCUT ?
- intent.getStringExtra(ShortcutInfoCompat.EXTRA_SHORTCUT_ID) : null;
+ getPromisedIntent().getStringExtra(ShortcutInfoCompat.EXTRA_SHORTCUT_ID) : null;
}
@Override
diff --git a/src/com/android/launcher3/Utilities.java b/src/com/android/launcher3/Utilities.java
index 2988fb9..9079837 100644
--- a/src/com/android/launcher3/Utilities.java
+++ b/src/com/android/launcher3/Utilities.java
@@ -776,16 +776,21 @@
}
public static boolean isBootCompleted() {
+ return "1".equals(getSystemProperty("sys.boot_completed", "1"));
+ }
+
+ public static String getSystemProperty(String property, String defaultValue) {
try {
Class clazz = Class.forName("android.os.SystemProperties");
Method getter = clazz.getDeclaredMethod("get", String.class);
- String value = (String) getter.invoke(null, "sys.boot_completed");
- return "1".equals(value);
+ String value = (String) getter.invoke(null, property);
+ if (!TextUtils.isEmpty(value)) {
+ return value;
+ }
} catch (Exception e) {
Log.d(TAG, "Unable to read system properties");
- // Assume that boot has completed
- return true;
}
+ return defaultValue;
}
/**
diff --git a/src/com/android/launcher3/Workspace.java b/src/com/android/launcher3/Workspace.java
index 4c2d4bb..88eeac6 100644
--- a/src/com/android/launcher3/Workspace.java
+++ b/src/com/android/launcher3/Workspace.java
@@ -624,8 +624,8 @@
ViewGroup.LayoutParams lp = qsbContainer.getLayoutParams();
if (cellHeight > 0 && lp.height != cellHeight) {
lp.height = cellHeight;
+ qsbContainer.setLayoutParams(lp);
}
- qsbContainer.setLayoutParams(lp);
}
}
diff --git a/src/com/android/launcher3/provider/RestoreDbTask.java b/src/com/android/launcher3/provider/RestoreDbTask.java
index 9d8b6b3..47bee06 100644
--- a/src/com/android/launcher3/provider/RestoreDbTask.java
+++ b/src/com/android/launcher3/provider/RestoreDbTask.java
@@ -24,6 +24,7 @@
import com.android.launcher3.LauncherAppWidgetInfo;
import com.android.launcher3.LauncherProvider.DatabaseHelper;
import com.android.launcher3.LauncherSettings.Favorites;
+import com.android.launcher3.ShortcutInfo;
import com.android.launcher3.Utilities;
import com.android.launcher3.logging.FileLog;
@@ -43,6 +44,13 @@
private static final String INFO_COLUMN_NAME = "name";
private static final String INFO_COLUMN_DEFAULT_VALUE = "dflt_value";
+ /**
+ * When enabled all icons are kept on the home screen, even if they don't have an active
+ * session. To enable use:
+ * adb shell setprop log.tag.launcher_keep_all_icons VERBOSE
+ */
+ private static final String KEEP_ALL_ICONS = "launcher_keep_all_icons";
+
public static boolean performRestore(DatabaseHelper helper) {
SQLiteDatabase db = helper.getWritableDatabase();
db.beginTransaction();
@@ -77,15 +85,17 @@
}
// Mark all items as restored.
+ boolean keepAllIcons = Utilities.isPropertyEnabled(KEEP_ALL_ICONS);
ContentValues values = new ContentValues();
- values.put(Favorites.RESTORED, 1);
+ values.put(Favorites.RESTORED, ShortcutInfo.FLAG_RESTORED_ICON
+ | (keepAllIcons ? ShortcutInfo.FLAG_RESTORE_STARTED : 0));
db.update(Favorites.TABLE_NAME, values, null, null);
// Mark widgets with appropriate restore flag
- values.put(Favorites.RESTORED,
- LauncherAppWidgetInfo.FLAG_ID_NOT_VALID |
- LauncherAppWidgetInfo.FLAG_PROVIDER_NOT_READY |
- LauncherAppWidgetInfo.FLAG_UI_NOT_READY);
+ values.put(Favorites.RESTORED, LauncherAppWidgetInfo.FLAG_ID_NOT_VALID |
+ LauncherAppWidgetInfo.FLAG_PROVIDER_NOT_READY |
+ LauncherAppWidgetInfo.FLAG_UI_NOT_READY |
+ (keepAllIcons ? LauncherAppWidgetInfo.FLAG_RESTORE_STARTED : 0));
db.update(Favorites.TABLE_NAME, values, "itemType = ?",
new String[]{Integer.toString(Favorites.ITEM_TYPE_APPWIDGET)});
diff --git a/src/com/android/launcher3/shortcuts/ShortcutKey.java b/src/com/android/launcher3/shortcuts/ShortcutKey.java
index 4053030..a219c54 100644
--- a/src/com/android/launcher3/shortcuts/ShortcutKey.java
+++ b/src/com/android/launcher3/shortcuts/ShortcutKey.java
@@ -3,7 +3,7 @@
import android.content.ComponentName;
import android.content.Intent;
-import com.android.launcher3.ItemInfo;
+import com.android.launcher3.ShortcutInfo;
import com.android.launcher3.compat.UserHandleCompat;
import com.android.launcher3.util.ComponentKey;
@@ -32,7 +32,7 @@
return new ShortcutKey(intent.getPackage(), user, shortcutId);
}
- public static ShortcutKey fromItemInfo(ItemInfo info) {
- return fromIntent(info.getIntent(), info.user);
+ public static ShortcutKey fromShortcutInfo(ShortcutInfo info) {
+ return fromIntent(info.getPromisedIntent(), info.user);
}
}
diff --git a/src/com/android/launcher3/util/ItemInfoMatcher.java b/src/com/android/launcher3/util/ItemInfoMatcher.java
index 6189bf2..46e9184 100644
--- a/src/com/android/launcher3/util/ItemInfoMatcher.java
+++ b/src/com/android/launcher3/util/ItemInfoMatcher.java
@@ -20,6 +20,7 @@
import com.android.launcher3.ItemInfo;
import com.android.launcher3.LauncherSettings.Favorites;
+import com.android.launcher3.ShortcutInfo;
import com.android.launcher3.compat.UserHandleCompat;
import com.android.launcher3.shortcuts.ShortcutKey;
@@ -57,7 +58,7 @@
@Override
public boolean matches(ItemInfo info, ComponentName cn) {
return info.itemType == Favorites.ITEM_TYPE_DEEP_SHORTCUT &&
- keys.contains(ShortcutKey.fromItemInfo(info));
+ keys.contains(ShortcutKey.fromShortcutInfo((ShortcutInfo) info));
}
};
}
diff --git a/tests/src/com/android/launcher3/util/Wait.java b/tests/src/com/android/launcher3/util/Wait.java
index 02a1913..f9e53ba 100644
--- a/tests/src/com/android/launcher3/util/Wait.java
+++ b/tests/src/com/android/launcher3/util/Wait.java
@@ -25,6 +25,15 @@
}
SystemClock.sleep(sleepMillis);
}
+
+ // Check once more before returning false.
+ try {
+ if (condition.isTrue()) {
+ return true;
+ }
+ } catch (Throwable t) {
+ // Ignore
+ }
return false;
}
}