merge in ics-release history after reset to master
diff --git a/print_db.py b/print_db.py
index ebcba6c..4f90f94 100755
--- a/print_db.py
+++ b/print_db.py
@@ -9,6 +9,7 @@
SCREENS = 5
COLUMNS = 4
ROWS = 4
+HOTSEAT_SIZE = 5
CELL_SIZE = 110
DIR = "db_files"
@@ -70,6 +71,52 @@
"icon": print_icon
}
+def render_cell_info(out, cell, occupied):
+ if cell is None:
+ out.write(" <td width=%d height=%d></td>\n" %
+ (CELL_SIZE, CELL_SIZE))
+ elif cell == occupied:
+ pass
+ else:
+ cellX = cell["cellX"]
+ cellY = cell["cellY"]
+ spanX = cell["spanX"]
+ spanY = cell["spanY"]
+ intent = cell["intent"]
+ if intent:
+ title = "title=\"%s\"" % cgi.escape(cell["intent"], True)
+ else:
+ title = ""
+ out.write((" <td colspan=%d rowspan=%d width=%d height=%d"
+ + " bgcolor=#dddddd align=center valign=middle %s>") % (
+ spanX, spanY,
+ (CELL_SIZE*spanX), (CELL_SIZE*spanY),
+ title))
+ itemType = cell["itemType"]
+ if itemType == 0:
+ out.write("""<img src="icon_%d.png">\n""" % ( cell["_id"] ))
+ out.write("<br/>\n")
+ out.write(cgi.escape(cell["title"]) + " <br/><i>(app)</i>")
+ elif itemType == 1:
+ out.write("""<img src="icon_%d.png">\n""" % ( cell["_id"] ))
+ out.write("<br/>\n")
+ out.write(cgi.escape(cell["title"]) + " <br/><i>(shortcut)</i>")
+ elif itemType == 2:
+ out.write("""<i>folder</i>""")
+ elif itemType == 3:
+ out.write("""<i>live folder</i>""")
+ elif itemType == 4:
+ out.write("<i>widget %d</i><br/>\n" % cell["appWidgetId"])
+ elif itemType == 1000:
+ out.write("""<i>clock</i>""")
+ elif itemType == 1001:
+ out.write("""<i>search</i>""")
+ elif itemType == 1002:
+ out.write("""<i>photo frame</i>""")
+ else:
+ out.write("<b>unknown type: %d</b>" % itemType)
+ out.write("</td>\n")
+
def process_file(fn):
print "process_file: " + fn
conn = sqlite3.connect(fn)
@@ -119,6 +166,21 @@
out.write("""</table>
""")
+ # Hotseat
+ hotseat = []
+ for i in range(0, HOTSEAT_SIZE):
+ hotseat.append(None)
+ for row in data:
+ if row["container"] != -101:
+ continue
+ screen = row["screen"]
+ hotseat[screen] = row
+ out.write("<br/><b>Hotseat</b><br/>\n")
+ out.write("<table class=layout border=1 cellspacing=0 cellpadding=4>\n")
+ for cell in hotseat:
+ render_cell_info(out, cell, None)
+ out.write("</table>\n")
+
# Pages
screens = []
for i in range(0,SCREENS):
@@ -150,50 +212,7 @@
for m in screen:
out.write(" <tr>\n")
for cell in m:
- if cell is None:
- out.write(" <td width=%d height=%d></td>\n" %
- (CELL_SIZE, CELL_SIZE))
- elif cell == occupied:
- pass
- else:
- cellX = cell["cellX"]
- cellY = cell["cellY"]
- spanX = cell["spanX"]
- spanY = cell["spanY"]
- intent = cell["intent"]
- if intent:
- title = "title=\"%s\"" % cgi.escape(cell["intent"], True)
- else:
- title = ""
- out.write((" <td colspan=%d rowspan=%d width=%d height=%d"
- + " bgcolor=#dddddd align=center valign=middle %s>") % (
- spanX, spanY,
- (CELL_SIZE*spanX), (CELL_SIZE*spanY),
- title))
- itemType = cell["itemType"]
- if itemType == 0:
- out.write("""<img src="icon_%d.png">\n""" % ( cell["_id"] ))
- out.write("<br/>\n")
- out.write(cgi.escape(cell["title"]) + " <br/><i>(app)</i>")
- elif itemType == 1:
- out.write("""<img src="icon_%d.png">\n""" % ( cell["_id"] ))
- out.write("<br/>\n")
- out.write(cgi.escape(cell["title"]) + " <br/><i>(shortcut)</i>")
- elif itemType == 2:
- out.write("""<i>folder</i>""")
- elif itemType == 3:
- out.write("""<i>live folder</i>""")
- elif itemType == 4:
- out.write("<i>widget %d</i><br/>\n" % cell["appWidgetId"])
- elif itemType == 1000:
- out.write("""<i>clock</i>""")
- elif itemType == 1001:
- out.write("""<i>search</i>""")
- elif itemType == 1002:
- out.write("""<i>photo frame</i>""")
- else:
- out.write("<b>unknown type: %d</b>" % itemType)
- out.write("</td>\n")
+ render_cell_info(out, cell, occupied)
out.write("</tr>\n")
out.write("</table>\n")
i=i+1
diff --git a/res/drawable-hdpi/portal_container_holo.9.png b/res/drawable-hdpi/portal_container_holo.9.png
index 20e8808..a2272c9 100644
--- a/res/drawable-hdpi/portal_container_holo.9.png
+++ b/res/drawable-hdpi/portal_container_holo.9.png
Binary files differ
diff --git a/res/drawable-mdpi/portal_container_holo.9.png b/res/drawable-mdpi/portal_container_holo.9.png
index 90fb1d1..daa1773 100644
--- a/res/drawable-mdpi/portal_container_holo.9.png
+++ b/res/drawable-mdpi/portal_container_holo.9.png
Binary files differ
diff --git a/res/drawable-xhdpi/portal_container_holo.9.png b/res/drawable-xhdpi/portal_container_holo.9.png
index 3c8193b..0c9c518 100644
--- a/res/drawable-xhdpi/portal_container_holo.9.png
+++ b/res/drawable-xhdpi/portal_container_holo.9.png
Binary files differ
diff --git a/res/layout-port/search_bar.xml b/res/layout-port/search_bar.xml
index b65da0b..d548453 100644
--- a/res/layout-port/search_bar.xml
+++ b/res/layout-port/search_bar.xml
@@ -22,7 +22,7 @@
<!-- Global search icon -->
<LinearLayout
style="@style/SearchButton"
- android:layout_width="wrap_content"
+ android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true"
diff --git a/res/layout/user_folder.xml b/res/layout/user_folder.xml
index 7597bc7..814c968 100644
--- a/res/layout/user_folder.xml
+++ b/res/layout/user_folder.xml
@@ -42,7 +42,8 @@
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
- android:paddingTop="@dimen/folder_content_name_gap"
+ android:paddingTop="@dimen/folder_name_padding"
+ android:paddingBottom="@dimen/folder_name_padding"
android:background="#00000000"
android:hint="@string/folder_hint_text"
android:textSize="14sp"
diff --git a/res/values/dimens.xml b/res/values/dimens.xml
index 509b7f1..0d44db8 100644
--- a/res/values/dimens.xml
+++ b/res/values/dimens.xml
@@ -96,7 +96,7 @@
<dimen name="folder_preview_size">64dp</dimen>
<!-- The amount that the preview contents are inset from the preview background -->
<dimen name="folder_preview_padding">4dp</dimen>
- <dimen name="folder_content_name_gap">4dp</dimen>
+ <dimen name="folder_name_padding">10dp</dimen>
<dimen name="folder_width_gap">0dp</dimen>
<dimen name="folder_height_gap">0dp</dimen>
</resources>
diff --git a/src/com/android/launcher2/AppsCustomizePagedView.java b/src/com/android/launcher2/AppsCustomizePagedView.java
index 949d872..0e442ea 100644
--- a/src/com/android/launcher2/AppsCustomizePagedView.java
+++ b/src/com/android/launcher2/AppsCustomizePagedView.java
@@ -315,7 +315,11 @@
private boolean testDataReady() {
// We only do this test once, and we default to the Applications page, so we only really
// have to wait for there to be apps.
- return !mApps.isEmpty();
+ if (mContentType == AppsCustomizePagedView.ContentType.Widgets) {
+ return !mApps.isEmpty() && !mWidgets.isEmpty();
+ } else {
+ return !mApps.isEmpty();
+ }
}
/** Restores the page for an item at the specified index */
@@ -574,7 +578,7 @@
public void setContentType(ContentType type) {
mContentType = type;
- invalidatePageData(0, true);
+ invalidatePageData(0, (type != ContentType.Applications));
}
public boolean isContentType(ContentType type) {
diff --git a/src/com/android/launcher2/Folder.java b/src/com/android/launcher2/Folder.java
index 1fcfebc..a0342cf 100644
--- a/src/com/android/launcher2/Folder.java
+++ b/src/com/android/launcher2/Folder.java
@@ -97,7 +97,6 @@
private int mFolderNameHeight;
private Rect mHitRect = new Rect();
private Rect mTempRect = new Rect();
- private boolean mFirstOpen = true;
private boolean mDragInProgress = false;
private boolean mDeleteFolderOnDropCompleted = false;
private boolean mSuppressFolderDeletion = false;
@@ -364,12 +363,6 @@
}
public void animateOpen() {
- if (mFirstOpen) {
- setLayerType(LAYER_TYPE_HARDWARE, null);
- buildLayer();
- mFirstOpen = false;
- }
-
positionAndSizeAsIcon();
if (!(getParent() instanceof DragLayer)) return;
@@ -410,25 +403,14 @@
@Override
public void onAnimationEnd(Animator animation) {
mState = STATE_OPEN;
- setLayerType(LAYER_TYPE_NONE, null);
- enableHardwareLayersForChildren();
}
});
oa.setDuration(mExpandDuration);
oa.start();
}
- void enableHardwareLayersForChildren() {
- ArrayList<View> children = getItemsInReadingOrder();
- for (View child: children) {
- child.setLayerType(LAYER_TYPE_HARDWARE, null);
- }
- }
-
public void animateClosed() {
if (!(getParent() instanceof DragLayer)) return;
- setLayerType(LAYER_TYPE_HARDWARE, null);
- buildLayer();
ObjectAnimator oa;
if (mMode == PARTIAL_GROW) {
diff --git a/src/com/android/launcher2/Launcher.java b/src/com/android/launcher2/Launcher.java
index 2fade8f..22a34e6 100644
--- a/src/com/android/launcher2/Launcher.java
+++ b/src/com/android/launcher2/Launcher.java
@@ -1061,6 +1061,8 @@
void closeSystemDialogs() {
getWindow().closeAllPanels();
+ /**
+ * We should remove this code when we remove all the dialog code.
try {
dismissDialog(DIALOG_CREATE_SHORTCUT);
// Unlock the workspace if the dialog was showing
@@ -1074,6 +1076,7 @@
} catch (Exception e) {
// An exception is thrown if the dialog is not visible, which is fine
}
+ */
// Whatever we were doing is hereby canceled.
mWaitingForResult = false;
@@ -2487,6 +2490,7 @@
private void updateGlobalSearchIcon() {
final ImageView searchButton = (ImageView) findViewById(R.id.search_button);
final View searchDivider = findViewById(R.id.search_divider);
+ final View voiceButton = findViewById(R.id.voice_button);
final SearchManager searchManager =
(SearchManager) getSystemService(Context.SEARCH_SERVICE);
@@ -2497,8 +2501,10 @@
searchButton.setVisibility(View.VISIBLE);
if (searchDivider != null) searchDivider.setVisibility(View.VISIBLE);
} else {
+ // We disable both search and voice search when there is no global search provider
searchButton.setVisibility(View.GONE);
if (searchDivider != null) searchDivider.setVisibility(View.GONE);
+ voiceButton.setVisibility(View.GONE);
}
}
diff --git a/src/com/android/launcher2/LauncherApplication.java b/src/com/android/launcher2/LauncherApplication.java
index 9b24587..ba028ef 100644
--- a/src/com/android/launcher2/LauncherApplication.java
+++ b/src/com/android/launcher2/LauncherApplication.java
@@ -62,6 +62,9 @@
filter = new IntentFilter();
filter.addAction(SearchManager.INTENT_GLOBAL_SEARCH_ACTIVITY_CHANGED);
registerReceiver(mModel, filter);
+ filter = new IntentFilter();
+ filter.addAction(SearchManager.INTENT_ACTION_SEARCHABLES_CHANGED);
+ registerReceiver(mModel, filter);
// Register for changes to the favorites
ContentResolver resolver = getContentResolver();
diff --git a/src/com/android/launcher2/LauncherModel.java b/src/com/android/launcher2/LauncherModel.java
index f14140c..b7f92ca 100644
--- a/src/com/android/launcher2/LauncherModel.java
+++ b/src/com/android/launcher2/LauncherModel.java
@@ -108,6 +108,10 @@
// sFolders is all FolderInfos created by LauncherModel. Passed to bindFolders()
static final HashMap<Long, FolderInfo> sFolders = new HashMap<Long, FolderInfo>();
+
+ // sDbIconCache is the set of ItemInfos that need to have their icons updated in the database
+ static final HashMap<Object, byte[]> sDbIconCache = new HashMap<Object, byte[]>();
+
// </ only access in worker thread >
private IconCache mIconCache;
@@ -205,6 +209,9 @@
if (item != modelItem) {
// the modelItem needs to match up perfectly with item if our model is to be
// consistent with the database-- for now, just require modelItem == item
+ Log.e(TAG, "item: " + ((item != null) ? item.toString() : "null"));
+ Log.e(TAG, "modelItem: " + ((modelItem != null) ? modelItem.toString() :
+ "null"));
throw new RuntimeException("Error: ItemInfo passed to moveItemInDatabase " +
"doesn't match original");
}
@@ -251,6 +258,9 @@
if (item != modelItem) {
// the modelItem needs to match up perfectly with item if our model is to be
// consistent with the database-- for now, just require modelItem == item
+ Log.e(TAG, "item: " + ((item != null) ? item.toString() : "null"));
+ Log.e(TAG, "modelItem: " + ((modelItem != null) ? modelItem.toString() :
+ "null"));
throw new RuntimeException("Error: ItemInfo passed to moveItemInDatabase " +
"doesn't match original");
}
@@ -392,6 +402,11 @@
cr.insert(notify ? LauncherSettings.Favorites.CONTENT_URI :
LauncherSettings.Favorites.CONTENT_URI_NO_NOTIFICATION, values);
+ if (sItemsIdMap.containsKey(item.id)) {
+ // we should not be adding new items in the db with the same id
+ throw new RuntimeException("Error: ItemInfo id (" + item.id + ") passed to " +
+ "addItemToDatabase already exists." + item.toString());
+ }
sItemsIdMap.put(item.id, item);
switch (item.itemType) {
case LauncherSettings.Favorites.ITEM_TYPE_FOLDER:
@@ -456,7 +471,10 @@
if (item != modelItem) {
// the modelItem needs to match up perfectly with item if our model is to be
// consistent with the database-- for now, just require modelItem == item
- throw new RuntimeException("Error: ItemInfo passed to moveItemInDatabase " +
+ Log.e(TAG, "item: " + ((item != null) ? item.toString() : "null"));
+ Log.e(TAG, "modelItem: " + ((modelItem != null) ? modelItem.toString() :
+ "null"));
+ throw new RuntimeException("Error: ItemInfo passed to updateItemInDatabase " +
"doesn't match original");
}
}
@@ -488,6 +506,7 @@
break;
}
sItemsIdMap.remove(item.id);
+ sDbIconCache.remove(item);
}
});
}
@@ -585,7 +604,8 @@
mAllAppsLoaded = false;
mWorkspaceLoaded = false;
startLoaderFromBackground();
- } else if (SearchManager.INTENT_GLOBAL_SEARCH_ACTIVITY_CHANGED.equals(action)) {
+ } else if (SearchManager.INTENT_GLOBAL_SEARCH_ACTIVITY_CHANGED.equals(action) ||
+ SearchManager.INTENT_ACTION_SEARCHABLES_CHANGED.equals(action)) {
Callbacks callbacks = mCallbacks.get();
callbacks.bindSearchablesChanged();
}
@@ -661,13 +681,11 @@
private boolean mStopped;
private boolean mLoadAndBindStepFinished;
private HashMap<Object, CharSequence> mLabelCache;
- private HashMap<Object, byte[]> mDbIconCache;
LoaderTask(Context context, boolean isLaunching) {
mContext = context;
mIsLaunching = isLaunching;
mLabelCache = new HashMap<Object, CharSequence>();
- mDbIconCache = new HashMap<Object, byte[]>();
}
boolean isLaunching() {
@@ -733,9 +751,6 @@
final Callbacks cbk = mCallbacks.get();
final boolean loadWorkspaceFirst = cbk != null ? (!cbk.isAllAppsVisible()) : true;
- // We update the icons in the database afterwards in case they have changed
- mDbIconCache.clear();
-
keep_running: {
// Elevate priority when Home launches for the first time to avoid
// starving at boot time. Staring at a blank home is not cool.
@@ -780,10 +795,10 @@
// Update the saved icons if necessary
if (DEBUG_LOADERS) Log.d(TAG, "Comparing loaded icons to database icons");
- for (Object key : mDbIconCache.keySet()) {
- updateSavedIcon(mContext, (ShortcutInfo) key, mDbIconCache.get(key));
+ for (Object key : sDbIconCache.keySet()) {
+ updateSavedIcon(mContext, (ShortcutInfo) key, sDbIconCache.get(key));
}
- mDbIconCache.clear();
+ sDbIconCache.clear();
// Clear out this reference, otherwise we end up holding it until all of the
// callback runnables are done.
@@ -883,6 +898,7 @@
sAppWidgets.clear();
sFolders.clear();
sItemsIdMap.clear();
+ sDbIconCache.clear();
final ArrayList<Long> itemsToRemove = new ArrayList<Long>();
@@ -986,7 +1002,7 @@
// now that we've loaded everthing re-save it with the
// icon in case it disappears somehow.
- queueIconToBeChecked(mDbIconCache, info, c, iconIndex);
+ queueIconToBeChecked(sDbIconCache, info, c, iconIndex);
} else {
// Failed to load the shortcut, probably because the
// activity manager couldn't resolve it (maybe the app