summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorMichael Jurka <mikejurka@google.com>2013-05-14 23:11:03 +0000
committerAndroid (Google) Code Review <android-gerrit@google.com>2013-05-14 23:11:04 +0000
commit94dcefa43564a5f6de4ea1be91b624110d024ed0 (patch)
tree3cae4e22f8e70f6a63f4980d05437b1305236c69 /src
parentcdbbab76e1e6e2819c16e0c2d3b528cf4ecd48c5 (diff)
parentc7700af21f7b1df939fce22f4ab5072b3ea29b66 (diff)
downloadandroid_packages_apps_Trebuchet-94dcefa43564a5f6de4ea1be91b624110d024ed0.tar.gz
android_packages_apps_Trebuchet-94dcefa43564a5f6de4ea1be91b624110d024ed0.tar.bz2
android_packages_apps_Trebuchet-94dcefa43564a5f6de4ea1be91b624110d024ed0.zip
Merge "Fix bug where apps weren't appearing on workspace after being installed" into jb-mr2-dev
Diffstat (limited to 'src')
-rw-r--r--src/com/android/launcher2/InstallShortcutReceiver.java47
-rw-r--r--src/com/android/launcher2/LauncherModel.java36
2 files changed, 64 insertions, 19 deletions
diff --git a/src/com/android/launcher2/InstallShortcutReceiver.java b/src/com/android/launcher2/InstallShortcutReceiver.java
index 20a19660e..23c896418 100644
--- a/src/com/android/launcher2/InstallShortcutReceiver.java
+++ b/src/com/android/launcher2/InstallShortcutReceiver.java
@@ -48,10 +48,23 @@ public class InstallShortcutReceiver extends BroadcastReceiver {
public static final String SHORTCUT_MIMETYPE =
"com.android.launcher/shortcut";
+ private static Object sLock = new Object();
+
// The set of shortcuts that are pending install
private static ArrayList<PendingInstallShortcutInfo> mInstallQueue =
new ArrayList<PendingInstallShortcutInfo>();
+ private static void addToStringSet(SharedPreferences sharedPrefs,
+ SharedPreferences.Editor editor, String key, String value) {
+ Set<String> strings = sharedPrefs.getStringSet(key, null);
+ if (strings == null) {
+ strings = new HashSet<String>(0);
+ } else {
+ strings = new HashSet<String>(strings);
+ }
+ strings.add(value);
+ editor.putStringSet(key, strings);
+ }
// Determines whether to defer installing shortcuts immediately until
// processAllPendingInstalls() is called.
private static boolean mUseInstallQueue = false;
@@ -131,6 +144,10 @@ public class InstallShortcutReceiver extends BroadcastReceiver {
final int[] result = {INSTALL_SHORTCUT_SUCCESSFUL};
boolean found = false;
synchronized (app) {
+ // Flush the LauncherModel worker thread, so that if we just did another
+ // processInstallShortcut, we give it time for its shortcut to get added to the
+ // database (getItemsInLocalCoordinates reads the database)
+ app.getModel().flushWorkerThread();
final ArrayList<ItemInfo> items = LauncherModel.getItemsInLocalCoordinates(context);
final boolean exists = LauncherModel.shortcutExists(context, name, intent);
@@ -160,7 +177,7 @@ public class InstallShortcutReceiver extends BroadcastReceiver {
}
private static boolean installShortcut(Context context, Intent data, ArrayList<ItemInfo> items,
- String name, Intent intent, final int screen, boolean shortcutExists,
+ String name, final Intent intent, final int screen, boolean shortcutExists,
final SharedPreferences sharedPrefs, int[] result) {
int[] tmpCoordinates = new int[2];
if (findEmptyCell(context, items, tmpCoordinates, screen)) {
@@ -178,24 +195,20 @@ public class InstallShortcutReceiver extends BroadcastReceiver {
// different places)
boolean duplicate = data.getBooleanExtra(Launcher.EXTRA_SHORTCUT_DUPLICATE, true);
if (duplicate || !shortcutExists) {
- // If the new app is going to fall into the same page as before, then just
- // continue adding to the current page
- int newAppsScreen = sharedPrefs.getInt(NEW_APPS_PAGE_KEY, screen);
- Set<String> newApps = new HashSet<String>();
- if (newAppsScreen == screen) {
- newApps = sharedPrefs.getStringSet(NEW_APPS_LIST_KEY, newApps);
- }
- synchronized (newApps) {
- newApps.add(intent.toUri(0).toString());
- }
- final Set<String> savedNewApps = newApps;
new Thread("setNewAppsThread") {
public void run() {
- synchronized (savedNewApps) {
- sharedPrefs.edit()
- .putInt(NEW_APPS_PAGE_KEY, screen)
- .putStringSet(NEW_APPS_LIST_KEY, savedNewApps)
- .commit();
+ synchronized (sLock) {
+ // If the new app is going to fall into the same page as before,
+ // then just continue adding to the current page
+ final int newAppsScreen = sharedPrefs.getInt(
+ NEW_APPS_PAGE_KEY, screen);
+ SharedPreferences.Editor editor = sharedPrefs.edit();
+ if (newAppsScreen == screen) {
+ addToStringSet(sharedPrefs,
+ editor, NEW_APPS_LIST_KEY, intent.toUri(0));
+ }
+ editor.putInt(NEW_APPS_PAGE_KEY, screen);
+ editor.commit();
}
}
}.start();
diff --git a/src/com/android/launcher2/LauncherModel.java b/src/com/android/launcher2/LauncherModel.java
index 00770b28a..99ebd962e 100644
--- a/src/com/android/launcher2/LauncherModel.java
+++ b/src/com/android/launcher2/LauncherModel.java
@@ -82,6 +82,7 @@ public class LauncherModel extends BroadcastReceiver {
private DeferredHandler mHandler = new DeferredHandler();
private LoaderTask mLoaderTask;
private boolean mIsLoaderTaskRunning;
+ private volatile boolean mFlushingWorkerThread;
// Specific runnable types that are run on the main thread deferred handler, this allows us to
// clear all queued binding runnables when the Launcher activity is destroyed.
@@ -375,6 +376,35 @@ public class LauncherModel extends BroadcastReceiver {
runOnWorkerThread(r);
}
+ public void flushWorkerThread() {
+ mFlushingWorkerThread = true;
+ Runnable waiter = new Runnable() {
+ public void run() {
+ synchronized (this) {
+ notifyAll();
+ mFlushingWorkerThread = false;
+ }
+ }
+ };
+
+ synchronized(waiter) {
+ runOnWorkerThread(waiter);
+ if (mLoaderTask != null) {
+ synchronized(mLoaderTask) {
+ mLoaderTask.notify();
+ }
+ }
+ boolean success = false;
+ while (!success) {
+ try {
+ waiter.wait();
+ success = true;
+ } catch (InterruptedException e) {
+ }
+ }
+ }
+ }
+
/**
* Move an item in the DB to a new <container, screen, cellX, cellY>
*/
@@ -1004,9 +1034,11 @@ public class LauncherModel extends BroadcastReceiver {
}
});
- while (!mStopped && !mLoadAndBindStepFinished) {
+ while (!mStopped && !mLoadAndBindStepFinished && !mFlushingWorkerThread) {
try {
- this.wait();
+ // Just in case mFlushingWorkerThread changes but we aren't woken up,
+ // wait no longer than 1sec at a time
+ this.wait(1000);
} catch (InterruptedException ex) {
// Ignore
}