Merge "add a proto decoder host utility" into jb-ub-now-indigo-rose
diff --git a/res/values/attrs.xml b/res/values/attrs.xml
index 1dcc5dd..a2d3a83 100644
--- a/res/values/attrs.xml
+++ b/res/values/attrs.xml
@@ -148,6 +148,9 @@
         <attr name="key" format="string" />
         <attr name="value" format="string" />
     </declare-styleable>
+    <declare-styleable name="Include">
+        <attr name="workspace" format="reference" />
+    </declare-styleable>
 
     <!-- Only used in the device overlays -->
     <declare-styleable name="CustomClingTitleText">
diff --git a/src/com/android/launcher3/Launcher.java b/src/com/android/launcher3/Launcher.java
index f1d4c1d..5e10e8b 100644
--- a/src/com/android/launcher3/Launcher.java
+++ b/src/com/android/launcher3/Launcher.java
@@ -911,6 +911,16 @@
         if (DEBUG_RESUME_TIME) {
             Log.d(TAG, "Time spent in onResume: " + (System.currentTimeMillis() - startTime));
         }
+
+        if (mWorkspace.getCustomContentCallbacks() != null) {
+            // If we are resuming and the custom content is the current page, we call onShow().
+            // It is also poassible that onShow will instead be called slightly after first layout
+            // if PagedView#setRestorePage was set to the custom content page in onCreate().
+            if (mWorkspace.isOnOrMovingToCustomContent()) {
+                mWorkspace.getCustomContentCallbacks().onShow();
+            }
+        }
+
         mWorkspace.updateInteractionForState();
     }
 
@@ -923,6 +933,12 @@
         mPaused = true;
         mDragController.cancelDrag();
         mDragController.resetLastGestureUpTime();
+
+        // We call onHide() aggressively. The custom content callbacks should be able to
+        // debounce excess onHide calls.
+        if (mWorkspace.getCustomContentCallbacks() != null) {
+            mWorkspace.getCustomContentCallbacks().onHide();
+        }
     }
 
     protected void onFinishBindingItems() {
@@ -1659,54 +1675,40 @@
                     ((intent.getFlags() & Intent.FLAG_ACTIVITY_BROUGHT_TO_FRONT)
                         != Intent.FLAG_ACTIVITY_BROUGHT_TO_FRONT);
 
-            Runnable processIntent = new Runnable() {
-                public void run() {
-                    if (mWorkspace == null) {
-                        // Can be cases where mWorkspace is null, this prevents a NPE
-                        return;
-                    }
-                    Folder openFolder = mWorkspace.getOpenFolder();
-                    // In all these cases, only animate if we're already on home
-                    mWorkspace.exitWidgetResizeMode();
-                    if (alreadyOnHome && mState == State.WORKSPACE && !mWorkspace.isTouchActive() &&
-                            openFolder == null) {
-                        mWorkspace.moveToDefaultScreen(true);
-                    }
-
-                    closeFolder();
-                    exitSpringLoadedDragMode();
-
-                    // If we are already on home, then just animate back to the workspace,
-                    // otherwise, just wait until onResume to set the state back to Workspace
-                    if (alreadyOnHome) {
-                        showWorkspaceAndExitOverviewMode(true);
-                    } else {
-                        mOnResumeState = State.WORKSPACE;
-                    }
-
-                    final View v = getWindow().peekDecorView();
-                    if (v != null && v.getWindowToken() != null) {
-                        InputMethodManager imm = (InputMethodManager)getSystemService(
-                                INPUT_METHOD_SERVICE);
-                        imm.hideSoftInputFromWindow(v.getWindowToken(), 0);
-                    }
-
-                    // Reset the apps customize page
-                    if (mAppsCustomizeTabHost != null) {
-                        mAppsCustomizeTabHost.reset();
-                    }
-                }
-            };
-
-            if (alreadyOnHome && !mWorkspace.hasWindowFocus()) {
-                // Delay processing of the intent to allow the status bar animation to finish
-                // first in order to avoid janky animations.
-                mWorkspace.postDelayed(processIntent, 350);
-            } else {
-                // Process the intent immediately.
-                processIntent.run();
+            if (mWorkspace == null) {
+                // Can be cases where mWorkspace is null, this prevents a NPE
+                return;
+            }
+            Folder openFolder = mWorkspace.getOpenFolder();
+            // In all these cases, only animate if we're already on home
+            mWorkspace.exitWidgetResizeMode();
+            if (alreadyOnHome && mState == State.WORKSPACE && !mWorkspace.isTouchActive() &&
+                    openFolder == null) {
+                mWorkspace.moveToDefaultScreen(true);
             }
 
+            closeFolder();
+            exitSpringLoadedDragMode();
+
+            // If we are already on home, then just animate back to the workspace,
+            // otherwise, just wait until onResume to set the state back to Workspace
+            if (alreadyOnHome) {
+                showWorkspaceAndExitOverviewMode(true);
+            } else {
+                mOnResumeState = State.WORKSPACE;
+            }
+
+            final View v = getWindow().peekDecorView();
+            if (v != null && v.getWindowToken() != null) {
+                InputMethodManager imm = (InputMethodManager)getSystemService(
+                        INPUT_METHOD_SERVICE);
+                imm.hideSoftInputFromWindow(v.getWindowToken(), 0);
+            }
+
+            // Reset the apps customize page
+            if (mAppsCustomizeTabHost != null) {
+                mAppsCustomizeTabHost.reset();
+            }
         }
         if (DEBUG_RESUME_TIME) {
             Log.d(TAG, "Time spent in onNewIntent: " + (System.currentTimeMillis() - startTime));
diff --git a/src/com/android/launcher3/LauncherProvider.java b/src/com/android/launcher3/LauncherProvider.java
index 471d2d2..5a8f630 100644
--- a/src/com/android/launcher3/LauncherProvider.java
+++ b/src/com/android/launcher3/LauncherProvider.java
@@ -296,6 +296,7 @@
         private static final String TAG_SHORTCUT = "shortcut";
         private static final String TAG_FOLDER = "folder";
         private static final String TAG_EXTRA = "extra";
+        private static final String TAG_INCLUDE = "include";
 
         private final Context mContext;
         private final AppWidgetHost mAppWidgetHost;
@@ -1011,6 +1012,8 @@
             intent.addCategory(Intent.CATEGORY_LAUNCHER);
             ContentValues values = new ContentValues();
 
+            if (LOGD) Log.v(TAG, String.format("Loading favorites from resid=0x%08x", workspaceResourceId));
+
             PackageManager packageManager = mContext.getPackageManager();
             int i = 0;
             try {
@@ -1031,6 +1034,30 @@
                     boolean added = false;
                     final String name = parser.getName();
 
+                    if (TAG_INCLUDE.equals(name)) {
+                        final TypedArray a = mContext.obtainStyledAttributes(attrs, R.styleable.Include);
+
+                        final int resId = a.getResourceId(R.styleable.Include_workspace, 0);
+
+                        if (LOGD) Log.v(TAG, String.format(("%" + (2*(depth+1)) + "s<include workspace=%08x>"),
+                                "", resId));
+
+                        if (resId != 0 && resId != workspaceResourceId) {
+                            // recursively load some more favorites, why not?
+                            i += loadFavorites(db, resId);
+                            added = false;
+                            mMaxItemId = -1;
+                        } else {
+                            Log.w(TAG, String.format("Skipping <include workspace=0x%08x>", resId));
+                        }
+
+                        a.recycle();
+
+                        if (LOGD) Log.v(TAG, String.format(("%" + (2*(depth+1)) + "s</include>"), ""));
+                        continue;
+                    }
+
+                    // Assuming it's a <favorite> at this point
                     TypedArray a = mContext.obtainStyledAttributes(attrs, R.styleable.Favorite);
 
                     long container = LauncherSettings.Favorites.CONTAINER_DESKTOP;
@@ -1048,6 +1075,17 @@
                     values.put(LauncherSettings.Favorites.CELLX, x);
                     values.put(LauncherSettings.Favorites.CELLY, y);
 
+                    if (LOGD) {
+                        final String title = a.getString(R.styleable.Favorite_title);
+                        final String pkg = a.getString(R.styleable.Favorite_packageName);
+                        final String something = title != null ? title : pkg;
+                        Log.v(TAG, String.format(
+                                ("%" + (2*(depth+1)) + "s<%s%s c=%d s=%s x=%s y=%s>"),
+                                "", name,
+                                (something == null ? "" : (" \"" + something + "\"")),
+                                container, screen, x, y));
+                    }
+
                     if (TAG_FAVORITE.equals(name)) {
                         long id = addAppShortcut(db, values, a, packageManager, intent);
                         added = id >= 0;
@@ -1087,6 +1125,13 @@
                             values.clear();
                             values.put(LauncherSettings.Favorites.CONTAINER, folderId);
 
+                            if (LOGD) {
+                                final String pkg = ar.getString(R.styleable.Favorite_packageName);
+                                final String uri = ar.getString(R.styleable.Favorite_uri);
+                                Log.v(TAG, String.format(("%" + (2*(folderDepth+1)) + "s<%s \"%s\">"), "",
+                                        folder_item_name, uri != null ? uri : pkg));
+                            }
+
                             if (TAG_FAVORITE.equals(folder_item_name) && folderId >= 0) {
                                 long id =
                                     addAppShortcut(db, values, ar, packageManager, intent);
diff --git a/src/com/android/launcher3/Workspace.java b/src/com/android/launcher3/Workspace.java
index 2b7a737..5a40d44 100644
--- a/src/com/android/launcher3/Workspace.java
+++ b/src/com/android/launcher3/Workspace.java
@@ -853,13 +853,6 @@
 
     protected void onWindowVisibilityChanged (int visibility) {
         mLauncher.onWindowVisibilityChanged(visibility);
-        if (mCustomContentShowing && mCustomContentCallbacks != null) {
-            if (visibility == View.VISIBLE) {
-                mCustomContentCallbacks.onShow();
-            } else if (visibility == View.GONE) {
-                mCustomContentCallbacks.onHide();
-            }
-        }
     }
 
     @Override
@@ -1048,6 +1041,10 @@
         }
     }
 
+    protected CustomContentCallbacks getCustomContentCallbacks() {
+        return mCustomContentCallbacks;
+    }
+
     protected void setWallpaperDimension() {
         String spKey = WallpaperCropActivity.getSharedPreferencesKey();
         SharedPreferences sp = mLauncher.getSharedPreferences(spKey, Context.MODE_PRIVATE);