diff options
author | Sunny Goyal <sunnygoyal@google.com> | 2015-04-16 15:20:51 -0700 |
---|---|---|
committer | Sunny Goyal <sunnygoyal@google.com> | 2015-04-22 10:08:14 -0700 |
commit | 756adbc3e41ee1edb53c580b8c679f343924fab5 (patch) | |
tree | ab8f8180f393dad6586e31c14aac4905ad3eb44d /src/com/android/launcher3/compat | |
parent | 7372fc659ed16c2e14a64a3d78a2c63554005844 (diff) | |
download | android_packages_apps_Trebuchet-756adbc3e41ee1edb53c580b8c679f343924fab5.tar.gz android_packages_apps_Trebuchet-756adbc3e41ee1edb53c580b8c679f343924fab5.tar.bz2 android_packages_apps_Trebuchet-756adbc3e41ee1edb53c580b8c679f343924fab5.zip |
Fixing missing updates in package install sessions
> Ensure icon cache never returns null icon
> Enabling install shortuct receiver only after workspace has finished binding
> Making all the model changes for package installs on worker thread and only
posting the updaes on the UI
> Making shortcut exists check on the loaded items and not on the DB
> Explicitely using worker thread for PckageInstallListener
> Removing backward compatibility support from PackageInstallerCompat
Change-Id: I9592771b9670c1c1c84c8208cae8dafa7b393e65
Diffstat (limited to 'src/com/android/launcher3/compat')
3 files changed, 39 insertions, 273 deletions
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 d6d4b8287..395d5f9e2 100644 --- a/src/com/android/launcher3/compat/PackageInstallerCompatVL.java +++ b/src/com/android/launcher3/compat/PackageInstallerCompatVL.java @@ -21,63 +21,41 @@ import android.content.pm.PackageInstaller; import android.content.pm.PackageInstaller.SessionCallback; import android.content.pm.PackageInstaller.SessionInfo; 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 { +public class PackageInstallerCompatVL extends PackageInstallerCompat { - private static final String TAG = "PackageInstallerCompatVL"; - private static final boolean DEBUG = false; - - // All updates to these sets must happen on the {@link #mWorker} thread. - @Thunk final SparseArray<SessionInfo> mPendingReplays = new SparseArray<SessionInfo>(); - @Thunk final HashSet<String> mPendingBadgeUpdates = new HashSet<String>(); + @Thunk final SparseArray<String> mActiveSessions = new SparseArray<>(); @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; @@ -96,74 +74,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); - } - - @Thunk 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); } } @@ -171,19 +85,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)); } } @@ -192,8 +105,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))); } } @@ -202,18 +116,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); } } }; |