summaryrefslogtreecommitdiffstats
path: root/src/com/android/launcher3/compat
diff options
context:
space:
mode:
Diffstat (limited to 'src/com/android/launcher3/compat')
-rw-r--r--src/com/android/launcher3/compat/AlphabeticIndexCompat.java170
-rw-r--r--src/com/android/launcher3/compat/AppWidgetManagerCompat.java10
-rw-r--r--src/com/android/launcher3/compat/AppWidgetManagerCompatV16.java14
-rw-r--r--src/com/android/launcher3/compat/AppWidgetManagerCompatVL.java27
-rw-r--r--src/com/android/launcher3/compat/LauncherActivityInfoCompat.java9
-rw-r--r--src/com/android/launcher3/compat/LauncherActivityInfoCompatV16.java45
-rw-r--r--src/com/android/launcher3/compat/LauncherActivityInfoCompatVL.java4
-rw-r--r--src/com/android/launcher3/compat/LauncherAppsCompatV16.java6
-rw-r--r--src/com/android/launcher3/compat/LauncherAppsCompatVL.java4
-rw-r--r--src/com/android/launcher3/compat/PackageInstallerCompat.java17
-rw-r--r--src/com/android/launcher3/compat/PackageInstallerCompatV16.java151
-rw-r--r--src/com/android/launcher3/compat/PackageInstallerCompatVL.java152
-rw-r--r--src/com/android/launcher3/compat/UserHandleCompat.java5
-rw-r--r--src/com/android/launcher3/compat/UserManagerCompat.java1
-rw-r--r--src/com/android/launcher3/compat/UserManagerCompatV16.java5
-rw-r--r--src/com/android/launcher3/compat/UserManagerCompatV17.java8
-rw-r--r--src/com/android/launcher3/compat/UserManagerCompatVL.java25
17 files changed, 322 insertions, 331 deletions
diff --git a/src/com/android/launcher3/compat/AlphabeticIndexCompat.java b/src/com/android/launcher3/compat/AlphabeticIndexCompat.java
new file mode 100644
index 000000000..ec1fb669f
--- /dev/null
+++ b/src/com/android/launcher3/compat/AlphabeticIndexCompat.java
@@ -0,0 +1,170 @@
+package com.android.launcher3.compat;
+
+import android.content.Context;
+import com.android.launcher3.Utilities;
+
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Method;
+import java.util.Locale;
+
+/**
+ * Fallback class to support Alphabetic indexing if not supported by the framework.
+ * TODO(winsonc): disable for non-english locales
+ */
+class BaseAlphabeticIndex {
+
+ private static final String BUCKETS = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ-";
+ private static final int UNKNOWN_BUCKET_INDEX = BUCKETS.length() - 1;
+
+ public BaseAlphabeticIndex() {}
+
+ /**
+ * Sets the max number of the label buckets in this index.
+ */
+ public void setMaxLabelCount(int count) {
+ // Not currently supported
+ }
+
+ /**
+ * Returns the index of the bucket in which the given string should appear.
+ */
+ protected int getBucketIndex(String s) {
+ if (s.isEmpty()) {
+ return UNKNOWN_BUCKET_INDEX;
+ }
+ int index = BUCKETS.indexOf(s.substring(0, 1).toUpperCase());
+ if (index != -1) {
+ return index;
+ }
+ return UNKNOWN_BUCKET_INDEX;
+ }
+
+ /**
+ * Returns the label for the bucket at the given index (as returned by getBucketIndex).
+ */
+ protected String getBucketLabel(int index) {
+ return BUCKETS.substring(index, index + 1);
+ }
+}
+
+/**
+ * Reflected libcore.icu.AlphabeticIndex implementation, falls back to the base alphabetic index.
+ */
+public class AlphabeticIndexCompat extends BaseAlphabeticIndex {
+
+ private static final String MID_DOT = "\u2219";
+
+ private Object mAlphabeticIndex;
+ private Method mAddLabelsMethod;
+ private Method mSetMaxLabelCountMethod;
+ private Method mGetBucketIndexMethod;
+ private Method mGetBucketLabelMethod;
+ private boolean mHasValidAlphabeticIndex;
+ private String mDefaultMiscLabel;
+
+ public AlphabeticIndexCompat(Context context) {
+ super();
+ try {
+ Locale curLocale = context.getResources().getConfiguration().locale;
+ Class clazz = Class.forName("libcore.icu.AlphabeticIndex");
+ Constructor ctor = clazz.getConstructor(Locale.class);
+ mAddLabelsMethod = clazz.getDeclaredMethod("addLabels", Locale.class);
+ mSetMaxLabelCountMethod = clazz.getDeclaredMethod("setMaxLabelCount", int.class);
+ mGetBucketIndexMethod = clazz.getDeclaredMethod("getBucketIndex", String.class);
+ mGetBucketLabelMethod = clazz.getDeclaredMethod("getBucketLabel", int.class);
+ mAlphabeticIndex = ctor.newInstance(curLocale);
+ try {
+ // Ensure we always have some base English locale buckets
+ if (!curLocale.getLanguage().equals(Locale.ENGLISH.getLanguage())) {
+ mAddLabelsMethod.invoke(mAlphabeticIndex, Locale.ENGLISH);
+ }
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ if (curLocale.getLanguage().equals(Locale.JAPANESE.getLanguage())) {
+ // Japanese character 他 ("misc")
+ mDefaultMiscLabel = "\u4ed6";
+ // TODO(winsonc, omakoto): We need to handle Japanese sections better, especially the kanji
+ } else {
+ // Dot
+ mDefaultMiscLabel = MID_DOT;
+ }
+ mHasValidAlphabeticIndex = true;
+ } catch (Exception e) {
+ mHasValidAlphabeticIndex = false;
+ }
+ }
+
+ /**
+ * Sets the max number of the label buckets in this index.
+ * (ICU 51 default is 99)
+ */
+ public void setMaxLabelCount(int count) {
+ if (mHasValidAlphabeticIndex) {
+ try {
+ mSetMaxLabelCountMethod.invoke(mAlphabeticIndex, count);
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ } else {
+ super.setMaxLabelCount(count);
+ }
+ }
+
+ /**
+ * Computes the section name for an given string {@param s}.
+ */
+ public String computeSectionName(CharSequence cs) {
+ String s = Utilities.trim(cs);
+ String sectionName = getBucketLabel(getBucketIndex(s));
+ if (Utilities.trim(sectionName).isEmpty() && s.length() > 0) {
+ int c = s.codePointAt(0);
+ boolean startsWithDigit = Character.isDigit(c);
+ if (startsWithDigit) {
+ // Digit section
+ return "#";
+ } else {
+ boolean startsWithLetter = Character.isLetter(c);
+ if (startsWithLetter) {
+ return mDefaultMiscLabel;
+ } else {
+ // In languages where these differ, this ensures that we differentiate
+ // between the misc section in the native language and a misc section
+ // for everything else.
+ return MID_DOT;
+ }
+ }
+ }
+ return sectionName;
+ }
+
+ /**
+ * Returns the index of the bucket in which {@param s} should appear.
+ * Function is synchronized because underlying routine walks an iterator
+ * whose state is maintained inside the index object.
+ */
+ protected int getBucketIndex(String s) {
+ if (mHasValidAlphabeticIndex) {
+ try {
+ return (Integer) mGetBucketIndexMethod.invoke(mAlphabeticIndex, s);
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+ return super.getBucketIndex(s);
+ }
+
+ /**
+ * Returns the label for the bucket at the given index (as returned by getBucketIndex).
+ */
+ protected String getBucketLabel(int index) {
+ if (mHasValidAlphabeticIndex) {
+ try {
+ return (String) mGetBucketLabelMethod.invoke(mAlphabeticIndex, index);
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+ return super.getBucketLabel(index);
+ }
+}
diff --git a/src/com/android/launcher3/compat/AppWidgetManagerCompat.java b/src/com/android/launcher3/compat/AppWidgetManagerCompat.java
index 6512d427e..7aa36d447 100644
--- a/src/com/android/launcher3/compat/AppWidgetManagerCompat.java
+++ b/src/com/android/launcher3/compat/AppWidgetManagerCompat.java
@@ -26,6 +26,7 @@ import android.graphics.drawable.Drawable;
import android.os.Bundle;
import com.android.launcher3.IconCache;
+import com.android.launcher3.LauncherAppWidgetProviderInfo;
import com.android.launcher3.Utilities;
import java.util.List;
@@ -63,20 +64,21 @@ public abstract class AppWidgetManagerCompat {
public abstract List<AppWidgetProviderInfo> getAllProviders();
- public abstract String loadLabel(AppWidgetProviderInfo info);
+ public abstract String loadLabel(LauncherAppWidgetProviderInfo info);
public abstract boolean bindAppWidgetIdIfAllowed(
int appWidgetId, AppWidgetProviderInfo info, Bundle options);
- public abstract UserHandleCompat getUser(AppWidgetProviderInfo info);
+ public abstract UserHandleCompat getUser(LauncherAppWidgetProviderInfo info);
public abstract void startConfigActivity(AppWidgetProviderInfo info, int widgetId,
Activity activity, AppWidgetHost host, int requestCode);
public abstract Drawable loadPreview(AppWidgetProviderInfo info);
- public abstract Drawable loadIcon(AppWidgetProviderInfo info, IconCache cache);
+ public abstract Drawable loadIcon(LauncherAppWidgetProviderInfo info, IconCache cache);
- public abstract Bitmap getBadgeBitmap(AppWidgetProviderInfo info, Bitmap bitmap);
+ public abstract Bitmap getBadgeBitmap(LauncherAppWidgetProviderInfo info, Bitmap bitmap,
+ int imageHeight);
}
diff --git a/src/com/android/launcher3/compat/AppWidgetManagerCompatV16.java b/src/com/android/launcher3/compat/AppWidgetManagerCompatV16.java
index f599f4303..f7f4b7e4f 100644
--- a/src/com/android/launcher3/compat/AppWidgetManagerCompatV16.java
+++ b/src/com/android/launcher3/compat/AppWidgetManagerCompatV16.java
@@ -16,6 +16,7 @@
package com.android.launcher3.compat;
+import android.annotation.TargetApi;
import android.app.Activity;
import android.appwidget.AppWidgetHost;
import android.appwidget.AppWidgetManager;
@@ -28,6 +29,7 @@ import android.os.Build;
import android.os.Bundle;
import com.android.launcher3.IconCache;
+import com.android.launcher3.LauncherAppWidgetProviderInfo;
import com.android.launcher3.Utilities;
import java.util.List;
@@ -44,10 +46,11 @@ class AppWidgetManagerCompatV16 extends AppWidgetManagerCompat {
}
@Override
- public String loadLabel(AppWidgetProviderInfo info) {
- return info.label.trim();
+ public String loadLabel(LauncherAppWidgetProviderInfo info) {
+ return Utilities.trim(info.label);
}
+ @TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR1)
@Override
public boolean bindAppWidgetIdIfAllowed(int appWidgetId, AppWidgetProviderInfo info,
Bundle options) {
@@ -59,7 +62,7 @@ class AppWidgetManagerCompatV16 extends AppWidgetManagerCompat {
}
@Override
- public UserHandleCompat getUser(AppWidgetProviderInfo info) {
+ public UserHandleCompat getUser(LauncherAppWidgetProviderInfo info) {
return UserHandleCompat.myUserHandle();
}
@@ -79,12 +82,13 @@ class AppWidgetManagerCompatV16 extends AppWidgetManagerCompat {
}
@Override
- public Drawable loadIcon(AppWidgetProviderInfo info, IconCache cache) {
+ public Drawable loadIcon(LauncherAppWidgetProviderInfo info, IconCache cache) {
return cache.getFullResIcon(info.provider.getPackageName(), info.icon);
}
@Override
- public Bitmap getBadgeBitmap(AppWidgetProviderInfo info, Bitmap bitmap) {
+ public Bitmap getBadgeBitmap(LauncherAppWidgetProviderInfo info, Bitmap bitmap,
+ int imageHeight) {
return bitmap;
}
}
diff --git a/src/com/android/launcher3/compat/AppWidgetManagerCompatVL.java b/src/com/android/launcher3/compat/AppWidgetManagerCompatVL.java
index 03d43a6f2..13712d8c7 100644
--- a/src/com/android/launcher3/compat/AppWidgetManagerCompatVL.java
+++ b/src/com/android/launcher3/compat/AppWidgetManagerCompatVL.java
@@ -38,6 +38,7 @@ import android.view.View;
import android.widget.Toast;
import com.android.launcher3.IconCache;
+import com.android.launcher3.LauncherAppWidgetProviderInfo;
import com.android.launcher3.R;
import java.util.ArrayList;
@@ -65,8 +66,8 @@ class AppWidgetManagerCompatVL extends AppWidgetManagerCompat {
}
@Override
- public String loadLabel(AppWidgetProviderInfo info) {
- return info.loadLabel(mPm);
+ public String loadLabel(LauncherAppWidgetProviderInfo info) {
+ return info.getLabel(mPm);
}
@Override
@@ -77,7 +78,10 @@ class AppWidgetManagerCompatVL extends AppWidgetManagerCompat {
}
@Override
- public UserHandleCompat getUser(AppWidgetProviderInfo info) {
+ public UserHandleCompat getUser(LauncherAppWidgetProviderInfo info) {
+ if (info.isCustomWidget) {
+ return UserHandleCompat.myUserHandle();
+ }
return UserHandleCompat.fromUser(info.getProfile());
}
@@ -99,27 +103,28 @@ class AppWidgetManagerCompatVL extends AppWidgetManagerCompat {
}
@Override
- public Drawable loadIcon(AppWidgetProviderInfo info, IconCache cache) {
- return info.loadIcon(mContext, cache.getFullResIconDpi());
+ public Drawable loadIcon(LauncherAppWidgetProviderInfo info, IconCache cache) {
+ return info.getIcon(mContext, cache);
}
@Override
- public Bitmap getBadgeBitmap(AppWidgetProviderInfo info, Bitmap bitmap) {
- if (info.getProfile().equals(android.os.Process.myUserHandle())) {
+ public Bitmap getBadgeBitmap(LauncherAppWidgetProviderInfo info, Bitmap bitmap,
+ int imageHeight) {
+ if (info.isCustomWidget || info.getProfile().equals(android.os.Process.myUserHandle())) {
return bitmap;
}
// Add a user badge in the bottom right of the image.
final Resources res = mContext.getResources();
final int badgeSize = res.getDimensionPixelSize(R.dimen.profile_badge_size);
- final int badgeMargin = res.getDimensionPixelSize(R.dimen.profile_badge_margin);
+ final int badgeMinTop = res.getDimensionPixelSize(R.dimen.profile_badge_minimum_top);
final Rect badgeLocation = new Rect(0, 0, badgeSize, badgeSize);
- final int top = bitmap.getHeight() - badgeSize - badgeMargin;
+ final int top = Math.max(imageHeight - badgeSize, badgeMinTop);
if (res.getConfiguration().getLayoutDirection() == View.LAYOUT_DIRECTION_RTL) {
- badgeLocation.offset(badgeMargin, top);
+ badgeLocation.offset(0, top);
} else {
- badgeLocation.offset(bitmap.getWidth() - badgeSize - badgeMargin, top);
+ badgeLocation.offset(bitmap.getWidth() - badgeSize, top);
}
Drawable drawable = mPm.getUserBadgedDrawableForDensity(
diff --git a/src/com/android/launcher3/compat/LauncherActivityInfoCompat.java b/src/com/android/launcher3/compat/LauncherActivityInfoCompat.java
index 90a4d1a1f..07ef0efb7 100644
--- a/src/com/android/launcher3/compat/LauncherActivityInfoCompat.java
+++ b/src/com/android/launcher3/compat/LauncherActivityInfoCompat.java
@@ -17,7 +17,9 @@
package com.android.launcher3.compat;
import android.content.ComponentName;
+import android.content.Context;
import android.content.pm.ApplicationInfo;
+import android.content.pm.ResolveInfo;
import android.graphics.drawable.Drawable;
public abstract class LauncherActivityInfoCompat {
@@ -32,4 +34,11 @@ public abstract class LauncherActivityInfoCompat {
public abstract ApplicationInfo getApplicationInfo();
public abstract long getFirstInstallTime();
public abstract Drawable getBadgedIcon(int density);
+
+ /**
+ * Creates a LauncherActivityInfoCompat for the primary user.
+ */
+ public static LauncherActivityInfoCompat fromResolveInfo(ResolveInfo info, Context context) {
+ return new LauncherActivityInfoCompatV16(context, info);
+ }
}
diff --git a/src/com/android/launcher3/compat/LauncherActivityInfoCompatV16.java b/src/com/android/launcher3/compat/LauncherActivityInfoCompatV16.java
index 1d41a6ff6..ea51aace8 100644
--- a/src/com/android/launcher3/compat/LauncherActivityInfoCompatV16.java
+++ b/src/com/android/launcher3/compat/LauncherActivityInfoCompatV16.java
@@ -29,13 +29,15 @@ import android.graphics.drawable.Drawable;
public class LauncherActivityInfoCompatV16 extends LauncherActivityInfoCompat {
- private ActivityInfo mActivityInfo;
- private ComponentName mComponentName;
- private PackageManager mPm;
+ private final ResolveInfo mResolveInfo;
+ private final ActivityInfo mActivityInfo;
+ private final ComponentName mComponentName;
+ private final PackageManager mPm;
LauncherActivityInfoCompatV16(Context context, ResolveInfo info) {
super();
- this.mActivityInfo = info.activityInfo;
+ mResolveInfo = info;
+ mActivityInfo = info.activityInfo;
mComponentName = new ComponentName(mActivityInfo.packageName, mActivityInfo.name);
mPm = context.getPackageManager();
}
@@ -49,31 +51,30 @@ public class LauncherActivityInfoCompatV16 extends LauncherActivityInfoCompat {
}
public CharSequence getLabel() {
- return mActivityInfo.loadLabel(mPm);
+ return mResolveInfo.loadLabel(mPm);
}
public Drawable getIcon(int density) {
- Drawable d = null;
- if (mActivityInfo.getIconResource() != 0) {
- Resources resources;
+ int iconRes = mResolveInfo.getIconResource();
+ Resources resources = null;
+ Drawable icon = null;
+ // Get the preferred density icon from the app's resources
+ if (density != 0 && iconRes != 0) {
try {
- resources = mPm.getResourcesForApplication(mActivityInfo.packageName);
- } catch (PackageManager.NameNotFoundException e) {
- resources = null;
- }
- if (resources != null) {
- try {
- d = resources.getDrawableForDensity(mActivityInfo.getIconResource(), density);
- } catch (Resources.NotFoundException e) {
- // Return default icon below.
- }
+ resources = mPm.getResourcesForApplication(mActivityInfo.applicationInfo);
+ icon = resources.getDrawableForDensity(iconRes, density);
+ } catch (NameNotFoundException | Resources.NotFoundException exc) {
}
}
- if (d == null) {
- Resources resources = Resources.getSystem();
- d = resources.getDrawableForDensity(android.R.mipmap.sym_def_app_icon, density);
+ // Get the default density icon
+ if (icon == null) {
+ icon = mResolveInfo.loadIcon(mPm);
+ }
+ if (icon == null) {
+ resources = Resources.getSystem();
+ icon = resources.getDrawableForDensity(android.R.mipmap.sym_def_app_icon, density);
}
- return d;
+ return icon;
}
public ApplicationInfo getApplicationInfo() {
diff --git a/src/com/android/launcher3/compat/LauncherActivityInfoCompatVL.java b/src/com/android/launcher3/compat/LauncherActivityInfoCompatVL.java
index b52cf1de2..4448758e7 100644
--- a/src/com/android/launcher3/compat/LauncherActivityInfoCompatVL.java
+++ b/src/com/android/launcher3/compat/LauncherActivityInfoCompatVL.java
@@ -16,12 +16,14 @@
package com.android.launcher3.compat;
+import android.annotation.TargetApi;
import android.content.ComponentName;
import android.content.pm.ApplicationInfo;
import android.content.pm.LauncherActivityInfo;
import android.graphics.drawable.Drawable;
-import android.os.UserHandle;
+import android.os.Build;
+@TargetApi(Build.VERSION_CODES.LOLLIPOP)
public class LauncherActivityInfoCompatVL extends LauncherActivityInfoCompat {
private LauncherActivityInfo mLauncherActivityInfo;
diff --git a/src/com/android/launcher3/compat/LauncherAppsCompatV16.java b/src/com/android/launcher3/compat/LauncherAppsCompatV16.java
index e47b9a58d..ac3d252f5 100644
--- a/src/com/android/launcher3/compat/LauncherAppsCompatV16.java
+++ b/src/com/android/launcher3/compat/LauncherAppsCompatV16.java
@@ -31,6 +31,8 @@ import android.os.Build;
import android.os.Bundle;
import android.provider.Settings;
+import com.android.launcher3.util.Thunk;
+
import java.util.ArrayList;
import java.util.List;
@@ -139,11 +141,11 @@ public class LauncherAppsCompatV16 extends LauncherAppsCompat {
mContext.registerReceiver(mPackageMonitor, filter);
}
- private synchronized List<OnAppsChangedCallbackCompat> getCallbacks() {
+ @Thunk synchronized List<OnAppsChangedCallbackCompat> getCallbacks() {
return new ArrayList<OnAppsChangedCallbackCompat>(mCallbacks);
}
- private class PackageMonitor extends BroadcastReceiver {
+ @Thunk class PackageMonitor extends BroadcastReceiver {
public void onReceive(Context context, Intent intent) {
final String action = intent.getAction();
final UserHandleCompat user = UserHandleCompat.myUserHandle();
diff --git a/src/com/android/launcher3/compat/LauncherAppsCompatVL.java b/src/com/android/launcher3/compat/LauncherAppsCompatVL.java
index e0d28b566..fbf91b548 100644
--- a/src/com/android/launcher3/compat/LauncherAppsCompatVL.java
+++ b/src/com/android/launcher3/compat/LauncherAppsCompatVL.java
@@ -16,6 +16,7 @@
package com.android.launcher3.compat;
+import android.annotation.TargetApi;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
@@ -32,6 +33,7 @@ import java.util.HashMap;
import java.util.List;
import java.util.Map;
+@TargetApi(Build.VERSION_CODES.LOLLIPOP)
public class LauncherAppsCompatVL extends LauncherAppsCompat {
private LauncherApps mLauncherApps;
@@ -49,7 +51,7 @@ public class LauncherAppsCompatVL extends LauncherAppsCompat {
List<LauncherActivityInfo> list = mLauncherApps.getActivityList(packageName,
user.getUser());
if (list.size() == 0) {
- return Collections.EMPTY_LIST;
+ return Collections.emptyList();
}
ArrayList<LauncherActivityInfoCompat> compatList =
new ArrayList<LauncherActivityInfoCompat>(list.size());
diff --git a/src/com/android/launcher3/compat/PackageInstallerCompat.java b/src/com/android/launcher3/compat/PackageInstallerCompat.java
index 0eb8754e8..c49908328 100644
--- a/src/com/android/launcher3/compat/PackageInstallerCompat.java
+++ b/src/com/android/launcher3/compat/PackageInstallerCompat.java
@@ -20,7 +20,7 @@ import android.content.Context;
import com.android.launcher3.Utilities;
-import java.util.HashSet;
+import java.util.HashMap;
public abstract class PackageInstallerCompat {
@@ -37,25 +37,20 @@ public abstract class PackageInstallerCompat {
if (Utilities.isLmpOrAbove()) {
sInstance = new PackageInstallerCompatVL(context);
} else {
- sInstance = new PackageInstallerCompatV16(context) { };
+ sInstance = new PackageInstallerCompatV16();
}
}
return sInstance;
}
}
- public abstract HashSet<String> updateAndGetActiveSessionCache();
-
- public abstract void onPause();
-
- public abstract void onResume();
-
- public abstract void onFinishBind();
+ /**
+ * @return a map of active installs to their progress
+ */
+ public abstract HashMap<String, Integer> updateAndGetActiveSessionCache();
public abstract void onStop();
- public abstract void recordPackageUpdate(String packageName, int state, int progress);
-
public static final class PackageInstallInfo {
public final String packageName;
diff --git a/src/com/android/launcher3/compat/PackageInstallerCompatV16.java b/src/com/android/launcher3/compat/PackageInstallerCompatV16.java
index 1910d22ae..654e34968 100644
--- a/src/com/android/launcher3/compat/PackageInstallerCompatV16.java
+++ b/src/com/android/launcher3/compat/PackageInstallerCompatV16.java
@@ -16,160 +16,17 @@
package com.android.launcher3.compat;
-import android.content.Context;
-import android.content.SharedPreferences;
-import android.text.TextUtils;
-import android.util.Log;
-
-import com.android.launcher3.LauncherAppState;
-
-import org.json.JSONException;
-import org.json.JSONObject;
-import org.json.JSONStringer;
-import org.json.JSONTokener;
-
-import java.util.ArrayList;
-import java.util.HashSet;
+import java.util.HashMap;
public class PackageInstallerCompatV16 extends PackageInstallerCompat {
- private static final String TAG = "PackageInstallerCompatV16";
- private static final boolean DEBUG = false;
-
- private static final String KEY_PROGRESS = "progress";
- private static final String KEY_STATE = "state";
-
- private static final String PREFS =
- "com.android.launcher3.compat.PackageInstallerCompatV16.queue";
-
- protected final SharedPreferences mPrefs;
-
- boolean mUseQueue;
- boolean mFinishedBind;
- boolean mReplayPending;
-
- PackageInstallerCompatV16(Context context) {
- mPrefs = context.getSharedPreferences(PREFS, Context.MODE_PRIVATE);
- }
-
- @Override
- public void onPause() {
- mUseQueue = true;
- if (DEBUG) Log.d(TAG, "updates paused");
- }
-
- @Override
- public void onResume() {
- mUseQueue = false;
- if (mFinishedBind) {
- replayUpdates();
- }
- }
-
- @Override
- public void onFinishBind() {
- mFinishedBind = true;
- if (!mUseQueue) {
- replayUpdates();
- }
- }
+ PackageInstallerCompatV16() { }
@Override
public void onStop() { }
- private void replayUpdates() {
- if (DEBUG) Log.d(TAG, "updates resumed");
- LauncherAppState app = LauncherAppState.getInstanceNoCreate();
- if (app == null) {
- mReplayPending = true; // try again later
- if (DEBUG) Log.d(TAG, "app is null, delaying send");
- return;
- }
- mReplayPending = false;
- ArrayList<PackageInstallInfo> updates = new ArrayList<PackageInstallInfo>();
- for (String packageName: mPrefs.getAll().keySet()) {
- final String json = mPrefs.getString(packageName, null);
- if (!TextUtils.isEmpty(json)) {
- updates.add(infoFromJson(packageName, json));
- }
- }
- if (!updates.isEmpty()) {
- sendUpdate(app, updates);
- }
- }
-
- /**
- * This should be called by the implementations to register a package update.
- */
- @Override
- public synchronized void recordPackageUpdate(String packageName, int state, int progress) {
- SharedPreferences.Editor editor = mPrefs.edit();
- PackageInstallInfo installInfo = new PackageInstallInfo(packageName);
- installInfo.progress = progress;
- installInfo.state = state;
- if (state == STATUS_INSTALLED) {
- // no longer necessary to track this package
- editor.remove(packageName);
- if (DEBUG) Log.d(TAG, "no longer tracking " + packageName);
- } else {
- editor.putString(packageName, infoToJson(installInfo));
- if (DEBUG)
- Log.d(TAG, "saved state: " + infoToJson(installInfo)
- + " for package: " + packageName);
-
- }
- editor.commit();
-
- if (!mUseQueue) {
- if (mReplayPending) {
- replayUpdates();
- } else if (state != STATUS_INSTALLED) {
- LauncherAppState app = LauncherAppState.getInstanceNoCreate();
- ArrayList<PackageInstallInfo> update = new ArrayList<PackageInstallInfo>();
- update.add(installInfo);
- sendUpdate(app, update);
- }
- }
- }
-
- private void sendUpdate(LauncherAppState app, ArrayList<PackageInstallInfo> updates) {
- if (app == null) {
- mReplayPending = true; // try again later
- if (DEBUG) Log.d(TAG, "app is null, delaying send");
- } else {
- app.setPackageState(updates);
- }
- }
-
- private static PackageInstallInfo infoFromJson(String packageName, String json) {
- PackageInstallInfo info = new PackageInstallInfo(packageName);
- try {
- JSONObject object = (JSONObject) new JSONTokener(json).nextValue();
- info.state = object.getInt(KEY_STATE);
- info.progress = object.getInt(KEY_PROGRESS);
- } catch (JSONException e) {
- Log.e(TAG, "failed to deserialize app state update", e);
- }
- return info;
- }
-
- private static String infoToJson(PackageInstallInfo info) {
- String value = null;
- try {
- JSONStringer json = new JSONStringer()
- .object()
- .key(KEY_STATE).value(info.state)
- .key(KEY_PROGRESS).value(info.progress)
- .endObject();
- value = json.toString();
- } catch (JSONException e) {
- Log.e(TAG, "failed to serialize app state update", e);
- }
- return value;
- }
-
@Override
- public HashSet<String> updateAndGetActiveSessionCache() {
- return new HashSet<String>();
+ public HashMap<String, Integer> updateAndGetActiveSessionCache() {
+ return new HashMap<>();
}
}
diff --git a/src/com/android/launcher3/compat/PackageInstallerCompatVL.java b/src/com/android/launcher3/compat/PackageInstallerCompatVL.java
index 601f04cea..3ad51017d 100644
--- a/src/com/android/launcher3/compat/PackageInstallerCompatVL.java
+++ b/src/com/android/launcher3/compat/PackageInstallerCompatVL.java
@@ -16,73 +16,55 @@
package com.android.launcher3.compat;
+import android.annotation.TargetApi;
import android.content.Context;
import android.content.pm.PackageInstaller;
import android.content.pm.PackageInstaller.SessionCallback;
import android.content.pm.PackageInstaller.SessionInfo;
+import android.os.Build;
import android.os.Handler;
-import android.util.Log;
import android.util.SparseArray;
import com.android.launcher3.IconCache;
import com.android.launcher3.LauncherAppState;
+import com.android.launcher3.LauncherModel;
+import com.android.launcher3.util.Thunk;
-import java.util.ArrayList;
-import java.util.HashSet;
+import java.util.HashMap;
-public class PackageInstallerCompatVL extends PackageInstallerCompat implements Runnable {
+@TargetApi(Build.VERSION_CODES.LOLLIPOP)
+public class PackageInstallerCompatVL extends PackageInstallerCompat {
- private static final String TAG = "PackageInstallerCompatVL";
- private static final boolean DEBUG = false;
+ @Thunk final SparseArray<String> mActiveSessions = new SparseArray<>();
- // All updates to these sets must happen on the {@link #mWorker} thread.
- private final SparseArray<SessionInfo> mPendingReplays = new SparseArray<SessionInfo>();
- private final HashSet<String> mPendingBadgeUpdates = new HashSet<String>();
-
- private final PackageInstaller mInstaller;
+ @Thunk final PackageInstaller mInstaller;
private final IconCache mCache;
private final Handler mWorker;
- private boolean mResumed;
- private boolean mBound;
-
PackageInstallerCompatVL(Context context) {
mInstaller = context.getPackageManager().getPackageInstaller();
LauncherAppState.setApplicationContext(context.getApplicationContext());
mCache = LauncherAppState.getInstance().getIconCache();
- mWorker = new Handler();
-
- mResumed = false;
- mBound = false;
+ mWorker = new Handler(LauncherModel.getWorkerLooper());
mInstaller.registerSessionCallback(mCallback, mWorker);
-
- // On start, send updates for all active sessions
- mWorker.post(new Runnable() {
-
- @Override
- public void run() {
- for (SessionInfo info : mInstaller.getAllSessions()) {
- mPendingReplays.append(info.getSessionId(), info);
- }
- }
- });
}
@Override
- public HashSet<String> updateAndGetActiveSessionCache() {
- HashSet<String> activePackages = new HashSet<String>();
+ public HashMap<String, Integer> updateAndGetActiveSessionCache() {
+ HashMap<String, Integer> activePackages = new HashMap<>();
UserHandleCompat user = UserHandleCompat.myUserHandle();
for (SessionInfo info : mInstaller.getAllSessions()) {
addSessionInfoToCahce(info, user);
if (info.getAppPackageName() != null) {
- activePackages.add(info.getAppPackageName());
+ activePackages.put(info.getAppPackageName(), (int) (info.getProgress() * 100));
+ mActiveSessions.put(info.getSessionId(), info.getAppPackageName());
}
}
return activePackages;
}
- private void addSessionInfoToCahce(SessionInfo info, UserHandleCompat user) {
+ @Thunk void addSessionInfoToCahce(SessionInfo info, UserHandleCompat user) {
String packageName = info.getAppPackageName();
if (packageName != null) {
mCache.cachePackageInstallInfo(packageName, user, info.getAppIcon(),
@@ -95,74 +77,10 @@ public class PackageInstallerCompatVL extends PackageInstallerCompat implements
mInstaller.unregisterSessionCallback(mCallback);
}
- @Override
- public void onFinishBind() {
- mBound = true;
- mWorker.post(this);
- }
-
- @Override
- public void onPause() {
- mResumed = false;
- }
-
- @Override
- public void onResume() {
- mResumed = true;
- mWorker.post(this);
- }
-
- @Override
- public void recordPackageUpdate(String packageName, int state, int progress) {
- // No op
- }
-
- @Override
- public void run() {
- // Called on mWorker thread.
- replayUpdates(null);
- }
-
- private void replayUpdates(PackageInstallInfo newInfo) {
- if (DEBUG) Log.d(TAG, "updates resumed");
- if (!mResumed || !mBound) {
- // Not yet ready
- return;
- }
- if ((mPendingReplays.size() == 0) && (newInfo == null)) {
- // Nothing to update
- return;
- }
-
+ @Thunk void sendUpdate(PackageInstallInfo info) {
LauncherAppState app = LauncherAppState.getInstanceNoCreate();
- if (app == null) {
- // Try again later
- if (DEBUG) Log.d(TAG, "app is null, delaying send");
- return;
- }
-
- ArrayList<PackageInstallInfo> updates = new ArrayList<PackageInstallInfo>();
- if ((newInfo != null) && (newInfo.state != STATUS_INSTALLED)) {
- updates.add(newInfo);
- }
- for (int i = mPendingReplays.size() - 1; i >= 0; i--) {
- SessionInfo session = mPendingReplays.valueAt(i);
- if (session.getAppPackageName() != null) {
- updates.add(new PackageInstallInfo(session.getAppPackageName(),
- STATUS_INSTALLING,
- (int) (session.getProgress() * 100)));
- }
- }
- mPendingReplays.clear();
- if (!updates.isEmpty()) {
- app.setPackageState(updates);
- }
-
- if (!mPendingBadgeUpdates.isEmpty()) {
- for (String pkg : mPendingBadgeUpdates) {
- app.updatePackageBadge(pkg);
- }
- mPendingBadgeUpdates.clear();
+ if (app != null) {
+ app.getModel().setPackageState(info);
}
}
@@ -170,19 +88,18 @@ public class PackageInstallerCompatVL extends PackageInstallerCompat implements
@Override
public void onCreated(int sessionId) {
- pushSessionBadgeToLauncher(sessionId);
+ pushSessionDisplayToLauncher(sessionId);
}
@Override
public void onFinished(int sessionId, boolean success) {
- mPendingReplays.remove(sessionId);
- SessionInfo session = mInstaller.getSessionInfo(sessionId);
- if ((session != null) && (session.getAppPackageName() != null)) {
- mPendingBadgeUpdates.remove(session.getAppPackageName());
- // Replay all updates with a one time update for this installed package. No
- // need to store this record for future updates, as the app list will get
- // refreshed on resume.
- replayUpdates(new PackageInstallInfo(session.getAppPackageName(),
+ // For a finished session, we can't get the session info. So use the
+ // packageName from our local cache.
+ String packageName = mActiveSessions.get(sessionId);
+ mActiveSessions.remove(sessionId);
+
+ if (packageName != null) {
+ sendUpdate(new PackageInstallInfo(packageName,
success ? STATUS_INSTALLED : STATUS_FAILED, 0));
}
}
@@ -191,8 +108,9 @@ public class PackageInstallerCompatVL extends PackageInstallerCompat implements
public void onProgressChanged(int sessionId, float progress) {
SessionInfo session = mInstaller.getSessionInfo(sessionId);
if (session != null) {
- mPendingReplays.put(sessionId, session);
- replayUpdates(null);
+ sendUpdate(new PackageInstallInfo(session.getAppPackageName(),
+ STATUS_INSTALLING,
+ (int) (session.getProgress() * 100)));
}
}
@@ -201,18 +119,18 @@ public class PackageInstallerCompatVL extends PackageInstallerCompat implements
@Override
public void onBadgingChanged(int sessionId) {
- pushSessionBadgeToLauncher(sessionId);
+ pushSessionDisplayToLauncher(sessionId);
}
- private void pushSessionBadgeToLauncher(int sessionId) {
+ private void pushSessionDisplayToLauncher(int sessionId) {
SessionInfo session = mInstaller.getSessionInfo(sessionId);
if (session != null) {
addSessionInfoToCahce(session, UserHandleCompat.myUserHandle());
- if (session.getAppPackageName() != null) {
- mPendingBadgeUpdates.add(session.getAppPackageName());
+ LauncherAppState app = LauncherAppState.getInstanceNoCreate();
+
+ if (app != null) {
+ app.getModel().updateSessionDisplayInfo(session.getAppPackageName());
}
- mPendingReplays.put(sessionId, session);
- replayUpdates(null);
}
}
};
diff --git a/src/com/android/launcher3/compat/UserHandleCompat.java b/src/com/android/launcher3/compat/UserHandleCompat.java
index 2ae673171..ab4b7216b 100644
--- a/src/com/android/launcher3/compat/UserHandleCompat.java
+++ b/src/com/android/launcher3/compat/UserHandleCompat.java
@@ -16,10 +16,10 @@
package com.android.launcher3.compat;
+import android.annotation.TargetApi;
import android.content.Intent;
import android.os.Build;
import android.os.UserHandle;
-
import com.android.launcher3.Utilities;
public class UserHandleCompat {
@@ -32,6 +32,7 @@ public class UserHandleCompat {
private UserHandleCompat() {
}
+ @TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR1)
public static UserHandleCompat myUserHandle() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
return new UserHandleCompat(android.os.Process.myUserHandle());
@@ -40,7 +41,7 @@ public class UserHandleCompat {
}
}
- static UserHandleCompat fromUser(UserHandle user) {
+ public static UserHandleCompat fromUser(UserHandle user) {
if (user == null) {
return null;
} else {
diff --git a/src/com/android/launcher3/compat/UserManagerCompat.java b/src/com/android/launcher3/compat/UserManagerCompat.java
index 1374b4e49..a79d94646 100644
--- a/src/com/android/launcher3/compat/UserManagerCompat.java
+++ b/src/com/android/launcher3/compat/UserManagerCompat.java
@@ -43,4 +43,5 @@ public abstract class UserManagerCompat {
public abstract UserHandleCompat getUserForSerialNumber(long serialNumber);
public abstract Drawable getBadgedDrawableForUser(Drawable unbadged, UserHandleCompat user);
public abstract CharSequence getBadgedLabelForUser(CharSequence label, UserHandleCompat user);
+ public abstract long getUserCreationTime(UserHandleCompat user);
}
diff --git a/src/com/android/launcher3/compat/UserManagerCompatV16.java b/src/com/android/launcher3/compat/UserManagerCompatV16.java
index 32f972e85..ffe698c8b 100644
--- a/src/com/android/launcher3/compat/UserManagerCompatV16.java
+++ b/src/com/android/launcher3/compat/UserManagerCompatV16.java
@@ -48,4 +48,9 @@ public class UserManagerCompatV16 extends UserManagerCompat {
public CharSequence getBadgedLabelForUser(CharSequence label, UserHandleCompat user) {
return label;
}
+
+ @Override
+ public long getUserCreationTime(UserHandleCompat user) {
+ return 0;
+ }
}
diff --git a/src/com/android/launcher3/compat/UserManagerCompatV17.java b/src/com/android/launcher3/compat/UserManagerCompatV17.java
index 055359afe..c42c00c7d 100644
--- a/src/com/android/launcher3/compat/UserManagerCompatV17.java
+++ b/src/com/android/launcher3/compat/UserManagerCompatV17.java
@@ -16,14 +16,12 @@
package com.android.launcher3.compat;
+import android.annotation.TargetApi;
import android.content.Context;
-import android.graphics.drawable.Drawable;
-import android.os.UserHandle;
+import android.os.Build;
import android.os.UserManager;
-import java.util.ArrayList;
-import java.util.List;
-
+@TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR1)
public class UserManagerCompatV17 extends UserManagerCompatV16 {
protected UserManager mUserManager;
diff --git a/src/com/android/launcher3/compat/UserManagerCompatVL.java b/src/com/android/launcher3/compat/UserManagerCompatVL.java
index 19eeabdcf..dd7a72617 100644
--- a/src/com/android/launcher3/compat/UserManagerCompatVL.java
+++ b/src/com/android/launcher3/compat/UserManagerCompatVL.java
@@ -17,29 +17,36 @@
package com.android.launcher3.compat;
+import android.annotation.TargetApi;
import android.content.Context;
+import android.content.SharedPreferences;
import android.content.pm.PackageManager;
import android.graphics.drawable.Drawable;
+import android.os.Build;
import android.os.UserHandle;
-import android.os.UserManager;
-
+import com.android.launcher3.LauncherAppState;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
+@TargetApi(Build.VERSION_CODES.LOLLIPOP)
public class UserManagerCompatVL extends UserManagerCompatV17 {
+ private static final String USER_CREATION_TIME_KEY = "user_creation_time_";
+
private final PackageManager mPm;
+ private final Context mContext;
UserManagerCompatVL(Context context) {
super(context);
mPm = context.getPackageManager();
+ mContext = context;
}
@Override
public List<UserHandleCompat> getUserProfiles() {
List<UserHandle> users = mUserManager.getUserProfiles();
if (users == null) {
- return Collections.EMPTY_LIST;
+ return Collections.emptyList();
}
ArrayList<UserHandleCompat> compatUsers = new ArrayList<UserHandleCompat>(
users.size());
@@ -61,5 +68,17 @@ public class UserManagerCompatVL extends UserManagerCompatV17 {
}
return mPm.getUserBadgedLabel(label, user.getUser());
}
+
+ @Override
+ public long getUserCreationTime(UserHandleCompat user) {
+ // TODO: Use system API once available.
+ SharedPreferences prefs = mContext.getSharedPreferences(
+ LauncherAppState.getSharedPreferencesKey(), Context.MODE_PRIVATE);
+ String key = USER_CREATION_TIME_KEY + getSerialNumberForUser(user);
+ if (!prefs.contains(key)) {
+ prefs.edit().putLong(key, System.currentTimeMillis()).apply();
+ }
+ return prefs.getLong(key, 0);
+ }
}