Merge "Fix bug where apps weren't appearing on workspace after being installed" into jb-mr2-dev

This commit is contained in:
Michael Jurka 2013-05-14 23:11:03 +00:00 committed by Android (Google) Code Review
commit 94dcefa435
2 changed files with 64 additions and 19 deletions

View File

@ -48,10 +48,23 @@ public class InstallShortcutReceiver extends BroadcastReceiver {
public static final String SHORTCUT_MIMETYPE = public static final String SHORTCUT_MIMETYPE =
"com.android.launcher/shortcut"; "com.android.launcher/shortcut";
private static Object sLock = new Object();
// The set of shortcuts that are pending install // The set of shortcuts that are pending install
private static ArrayList<PendingInstallShortcutInfo> mInstallQueue = private static ArrayList<PendingInstallShortcutInfo> mInstallQueue =
new ArrayList<PendingInstallShortcutInfo>(); 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 // Determines whether to defer installing shortcuts immediately until
// processAllPendingInstalls() is called. // processAllPendingInstalls() is called.
private static boolean mUseInstallQueue = false; private static boolean mUseInstallQueue = false;
@ -131,6 +144,10 @@ public class InstallShortcutReceiver extends BroadcastReceiver {
final int[] result = {INSTALL_SHORTCUT_SUCCESSFUL}; final int[] result = {INSTALL_SHORTCUT_SUCCESSFUL};
boolean found = false; boolean found = false;
synchronized (app) { 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 ArrayList<ItemInfo> items = LauncherModel.getItemsInLocalCoordinates(context);
final boolean exists = LauncherModel.shortcutExists(context, name, intent); 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, 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) { final SharedPreferences sharedPrefs, int[] result) {
int[] tmpCoordinates = new int[2]; int[] tmpCoordinates = new int[2];
if (findEmptyCell(context, items, tmpCoordinates, screen)) { if (findEmptyCell(context, items, tmpCoordinates, screen)) {
@ -178,24 +195,20 @@ public class InstallShortcutReceiver extends BroadcastReceiver {
// different places) // different places)
boolean duplicate = data.getBooleanExtra(Launcher.EXTRA_SHORTCUT_DUPLICATE, true); boolean duplicate = data.getBooleanExtra(Launcher.EXTRA_SHORTCUT_DUPLICATE, true);
if (duplicate || !shortcutExists) { 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") { new Thread("setNewAppsThread") {
public void run() { public void run() {
synchronized (savedNewApps) { synchronized (sLock) {
sharedPrefs.edit() // If the new app is going to fall into the same page as before,
.putInt(NEW_APPS_PAGE_KEY, screen) // then just continue adding to the current page
.putStringSet(NEW_APPS_LIST_KEY, savedNewApps) final int newAppsScreen = sharedPrefs.getInt(
.commit(); 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(); }.start();

View File

@ -82,6 +82,7 @@ public class LauncherModel extends BroadcastReceiver {
private DeferredHandler mHandler = new DeferredHandler(); private DeferredHandler mHandler = new DeferredHandler();
private LoaderTask mLoaderTask; private LoaderTask mLoaderTask;
private boolean mIsLoaderTaskRunning; private boolean mIsLoaderTaskRunning;
private volatile boolean mFlushingWorkerThread;
// Specific runnable types that are run on the main thread deferred handler, this allows us to // 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. // clear all queued binding runnables when the Launcher activity is destroyed.
@ -375,6 +376,35 @@ public class LauncherModel extends BroadcastReceiver {
runOnWorkerThread(r); 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> * 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 { 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) { } catch (InterruptedException ex) {
// Ignore // Ignore
} }