am aa997294: Merge "Revert "Add temporary functor lifetime logging"" into jb-dev

* commit 'aa9972943cab627db9b10e5c9c4bb80f99f8a4bd':
  Revert "Add temporary functor lifetime logging"
diff --git a/core/java/android/view/ScaleGestureDetector.java b/core/java/android/view/ScaleGestureDetector.java
index 5d2c1a7..bbb5ade 100644
--- a/core/java/android/view/ScaleGestureDetector.java
+++ b/core/java/android/view/ScaleGestureDetector.java
@@ -220,8 +220,10 @@
                 mActiveId1 = event.getPointerId(index1);
                 if (index0 < 0 || index0 == index1) {
                     // Probably someone sending us a broken event stream.
-                    index0 = findNewActiveIndex(event, index0 == index1 ? -1 : mActiveId1, index0);
-                    mActiveId0 = event.getPointerId(index0);
+                    boolean valid = handleBrokenEventStream(event);
+                    if (!valid) {
+                        return false;
+                    }
                 }
                 mActive0MostRecent = false;
 
@@ -377,13 +379,10 @@
                     int index0 = event.findPointerIndex(mActiveId0);
                     if (index0 < 0 || mActiveId0 == mActiveId1) {
                         // Probably someone sending us a broken event stream.
-                        Log.e(TAG, "Got " + MotionEvent.actionToString(action) +
-                                " with bad state while a gesture was in progress. " +
-                                "Did you forget to pass an event to " +
-                                "ScaleGestureDetector#onTouchEvent?");
-                        index0 = findNewActiveIndex(event,
-                                mActiveId0 == mActiveId1 ? -1 : mActiveId1, index0);
-                        mActiveId0 = event.getPointerId(index0);
+                        boolean valid = handleBrokenEventStream(event);
+                        if (!valid) {
+                            return false;
+                        }
                     }
 
                     setContext(event);
@@ -483,6 +482,27 @@
         return handled;
     }
 
+    private boolean handleBrokenEventStream(MotionEvent event) {
+        Log.e(TAG, "Got " + MotionEvent.actionToString(event.getActionMasked()) +
+                " with bad state while a gesture was in progress. " +
+                "Did you forget to pass an event to " +
+                "ScaleGestureDetector#onTouchEvent?");
+        int index0 = findNewActiveIndex(event,
+                mActiveId0 == mActiveId1 ? -1 : mActiveId1,
+                event.findPointerIndex(mActiveId0));
+        if (index0 >= 0) {
+            mActiveId0 = event.getPointerId(index0);
+            return true;
+        } else {
+            mInvalidGesture = true;
+            Log.e(TAG, "Invalid MotionEvent stream detected.", new Throwable());
+            if (mGestureInProgress) {
+                mListener.onScaleEnd(this);
+            }
+            return false;
+        }
+    }
+
     private int findNewActiveIndex(MotionEvent ev, int otherActiveId, int oldIndex) {
         final int pointerCount = ev.getPointerCount();
 
diff --git a/core/java/android/widget/Gallery.java b/core/java/android/widget/Gallery.java
index 03fdc39..0a3d333 100644
--- a/core/java/android/widget/Gallery.java
+++ b/core/java/android/widget/Gallery.java
@@ -1189,15 +1189,15 @@
         case KeyEvent.KEYCODE_DPAD_LEFT:
             if (movePrevious()) {
                 playSoundEffect(SoundEffectConstants.NAVIGATION_LEFT);
+                return true;
             }
-            return true;
-
+            break;
         case KeyEvent.KEYCODE_DPAD_RIGHT:
             if (moveNext()) {
                 playSoundEffect(SoundEffectConstants.NAVIGATION_RIGHT);
+                return true;
             }
-            return true;
-
+            break;
         case KeyEvent.KEYCODE_DPAD_CENTER:
         case KeyEvent.KEYCODE_ENTER:
             mReceivedInvokeKeyDown = true;
diff --git a/core/java/android/widget/SimpleExpandableListAdapter.java b/core/java/android/widget/SimpleExpandableListAdapter.java
index 015c169..f514374 100644
--- a/core/java/android/widget/SimpleExpandableListAdapter.java
+++ b/core/java/android/widget/SimpleExpandableListAdapter.java
@@ -38,6 +38,8 @@
  */
 public class SimpleExpandableListAdapter extends BaseExpandableListAdapter {
     private List<? extends Map<String, ?>> mGroupData;
+    // Keeps track of if a group is currently expanded or not
+    private boolean[] mIsGroupExpanded;
     private int mExpandedGroupLayout;
     private int mCollapsedGroupLayout;
     private String[] mGroupFrom;
@@ -196,6 +198,8 @@
             int childLayout, int lastChildLayout, String[] childFrom,
             int[] childTo) {
         mGroupData = groupData;
+        // Initially all groups are not expanded
+        mIsGroupExpanded = new boolean[groupData.size()];
         mExpandedGroupLayout = expandedGroupLayout;
         mCollapsedGroupLayout = collapsedGroupLayout;
         mGroupFrom = groupFrom;
@@ -298,4 +302,52 @@
         return true;
     }
 
+    /**
+     * {@inheritDoc}
+     * @return 1 for the last child in a group, 0 for the other children.
+     */
+    @Override
+    public int getChildType(int groupPosition, int childPosition) {
+        final int childrenInGroup = getChildrenCount(groupPosition);
+        return childPosition == childrenInGroup - 1 ? 1 : 0;
+    }
+
+    /**
+     * {@inheritDoc}
+     * @return 2, one type for the last child in a group, one for the other children.
+     */
+    @Override
+    public int getChildTypeCount() {
+        return 2;
+    }
+
+    /**
+     * {@inheritDoc}
+     * @return 1 for an expanded group view, 0 for a collapsed one.
+     */
+    @Override
+    public int getGroupType(int groupPosition) {
+        return mIsGroupExpanded[groupPosition] ? 1 : 0;
+    }
+
+    /**
+     * {@inheritDoc}
+     * @return 2, one for a collapsed group view, one for an expanded one.
+     */
+    @Override
+    public int getGroupTypeCount() {
+        return 2;
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public void onGroupCollapsed(int groupPosition) {
+        mIsGroupExpanded[groupPosition] = false;
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public void onGroupExpanded(int groupPosition) {
+        mIsGroupExpanded[groupPosition] = true;
+    }
 }
diff --git a/core/java/com/android/internal/os/ProcessStats.java b/core/java/com/android/internal/os/ProcessStats.java
index e0e9a29..9490437 100644
--- a/core/java/com/android/internal/os/ProcessStats.java
+++ b/core/java/com/android/internal/os/ProcessStats.java
@@ -154,7 +154,7 @@
 
     private boolean mFirst = true;
 
-    private byte[] mBuffer = new byte[256];
+    private byte[] mBuffer = new byte[4096];
 
     /**
      * The time in microseconds that the CPU has been running at each speed.
@@ -556,7 +556,7 @@
     private long[] getCpuSpeedTimes(long[] out) {
         long[] tempTimes = out;
         long[] tempSpeeds = mCpuSpeeds;
-        final int MAX_SPEEDS = 20;
+        final int MAX_SPEEDS = 60;
         if (out == null) {
             tempTimes = new long[MAX_SPEEDS]; // Hopefully no more than that
             tempSpeeds = new long[MAX_SPEEDS];
diff --git a/core/java/com/android/internal/view/menu/ActionMenuPresenter.java b/core/java/com/android/internal/view/menu/ActionMenuPresenter.java
index 73324c0..cf6029e 100644
--- a/core/java/com/android/internal/view/menu/ActionMenuPresenter.java
+++ b/core/java/com/android/internal/view/menu/ActionMenuPresenter.java
@@ -278,7 +278,7 @@
      */
     public boolean showOverflowMenu() {
         if (mReserveOverflow && !isOverflowMenuShowing() && mMenu != null && mMenuView != null &&
-                mPostedOpenRunnable == null) {
+                mPostedOpenRunnable == null && !mMenu.getNonActionItems().isEmpty()) {
             OverflowPopup popup = new OverflowPopup(mContext, mMenu, mOverflowButton, true);
             mPostedOpenRunnable = new OpenOverflowRunnable(popup);
             // Post this for later; we might still need a layout for the anchor to be right.
diff --git a/core/tests/overlaytests/OverlayTestOverlay/Android.mk b/core/tests/overlaytests/OverlayTestOverlay/Android.mk
index cf32c9f..b1327f7 100644
--- a/core/tests/overlaytests/OverlayTestOverlay/Android.mk
+++ b/core/tests/overlaytests/OverlayTestOverlay/Android.mk
@@ -9,6 +9,4 @@
 
 LOCAL_PACKAGE_NAME := com.android.overlaytest.overlay
 
-LOCAL_AAPT_FLAGS := -o
-
 include $(BUILD_PACKAGE)
diff --git a/core/tests/overlaytests/OverlayTestOverlay/res/drawable/default_wallpaper.jpg b/core/tests/overlaytests/OverlayTestOverlay/res/drawable-nodpi/default_wallpaper.jpg
similarity index 100%
rename from core/tests/overlaytests/OverlayTestOverlay/res/drawable/default_wallpaper.jpg
rename to core/tests/overlaytests/OverlayTestOverlay/res/drawable-nodpi/default_wallpaper.jpg
Binary files differ
diff --git a/core/tests/overlaytests/runtests.sh b/core/tests/overlaytests/runtests.sh
index 0ad9efb..0a721ad40 100755
--- a/core/tests/overlaytests/runtests.sh
+++ b/core/tests/overlaytests/runtests.sh
@@ -18,7 +18,6 @@
 
 log=$(mktemp)
 trap "atexit" EXIT
-failures=0
 
 function compile_module()
 {
@@ -38,6 +37,37 @@
 	$adb wait-for-device logcat | grep -m 1 -e 'PowerManagerService.*bootCompleted' >/dev/null
 }
 
+function mkdir_if_needed()
+{
+	local path="$1"
+
+	if [[ "${path:0:1}" != "/" ]]; then
+		echo "mkdir_if_needed: error: path '$path' does not begin with /" | tee -a $log
+		exit 1
+	fi
+
+	local basename=$(basename "$path")
+	local dirname=$(dirname "$path")
+	local t=$($adb shell ls -l $dirname | tr -d '\r' | grep -e "${basename}$" | grep -oe '^.')
+
+	case "$t" in
+		d) # File exists, and is a directory ...
+			# do nothing
+			;;
+		l) # ... (or symbolic link possibly to a directory).
+			# do nothing
+			;;
+		"") # File does not exist.
+			mkdir_if_needed "$dirname"
+			$adb shell mkdir "$path"
+			;;
+		*) # File exists, but is not a directory.
+			echo "mkdir_if_needed: file '$path' exists, but is not a directory" | tee -a $log
+			exit 1
+			;;
+	esac
+}
+
 function disable_overlay()
 {
 	echo "Disabling overlay"
@@ -48,6 +78,8 @@
 function enable_overlay()
 {
 	echo "Enabling overlay"
+	mkdir_if_needed "/system/vendor"
+	mkdir_if_needed "/vendor/overlay/framework"
 	$adb shell ln -s /data/app/com.android.overlaytest.overlay.apk /vendor/overlay/framework/framework-res.apk
 }
 
@@ -59,13 +91,21 @@
 	$adb shell am instrument -w -e class $class com.android.overlaytest/android.test.InstrumentationTestRunner | tee -a $log
 }
 
+function remount()
+{
+	echo "Remounting file system writable"
+	$adb remount | tee -a $log
+}
+
 function sync()
 {
 	echo "Syncing to device"
-	$adb remount | tee -a $log
 	$adb sync data | tee -a $log
 }
 
+# some commands require write access, remount once and for all
+remount
+
 # build and sync
 compile_module "$PWD/OverlayTest/Android.mk"
 compile_module "$PWD/OverlayTestOverlay/Android.mk"
diff --git a/libs/androidfw/ResourceTypes.cpp b/libs/androidfw/ResourceTypes.cpp
index f3a1d9a..8cce191 100644
--- a/libs/androidfw/ResourceTypes.cpp
+++ b/libs/androidfw/ResourceTypes.cpp
@@ -5159,7 +5159,8 @@
     const uint32_t pkg_id = pkg->package->id << 24;
 
     for (size_t typeIndex = 0; typeIndex < typeCount; ++typeIndex) {
-        ssize_t offset = -1;
+        ssize_t first = -1;
+        ssize_t last = -1;
         const Type* typeConfigs = pkg->getType(typeIndex);
         ssize_t mapIndex = map.add();
         if (mapIndex < 0) {
@@ -5167,12 +5168,14 @@
         }
         Vector<uint32_t>& vector = map.editItemAt(mapIndex);
         for (size_t entryIndex = 0; entryIndex < typeConfigs->entryCount; ++entryIndex) {
-            uint32_t resID = (0xff000000 & ((pkg->package->id)<<24))
+            uint32_t resID = pkg_id
                 | (0x00ff0000 & ((typeIndex+1)<<16))
                 | (0x0000ffff & (entryIndex));
             resource_name resName;
             if (!this->getResourceName(resID, &resName)) {
                 ALOGW("idmap: resource 0x%08x has spec but lacks values, skipping\n", resID);
+                // add dummy value, or trimming leading/trailing zeroes later will fail
+                vector.push(0);
                 continue;
             }
 
@@ -5185,13 +5188,13 @@
                                                               overlayPackage.string(),
                                                               overlayPackage.size());
             if (overlayResID != 0) {
-                // overlay package has package ID == 0, use original package's ID instead
-                overlayResID |= pkg_id;
+                overlayResID = pkg_id | (0x00ffffff & overlayResID);
+                last = Res_GETENTRY(resID);
+                if (first == -1) {
+                    first = Res_GETENTRY(resID);
+                }
             }
             vector.push(overlayResID);
-            if (overlayResID != 0 && offset == -1) {
-                offset = Res_GETENTRY(resID);
-            }
 #if 0
             if (overlayResID != 0) {
                 ALOGD("%s/%s 0x%08x -> 0x%08x\n",
@@ -5202,13 +5205,16 @@
 #endif
         }
 
-        if (offset != -1) {
-            // shave off leading and trailing entries which lack overlay values
-            vector.removeItemsAt(0, offset);
-            vector.insertAt((uint32_t)offset, 0, 1);
-            while (vector.top() == 0) {
-                vector.pop();
+        if (first != -1) {
+            // shave off trailing entries which lack overlay values
+            const size_t last_past_one = last + 1;
+            if (last_past_one < vector.size()) {
+                vector.removeItemsAt(last_past_one, vector.size() - last_past_one);
             }
+            // shave off leading entries which lack overlay values
+            vector.removeItemsAt(0, first);
+            // store offset to first overlaid resource ID of this type
+            vector.insertAt((uint32_t)first, 0, 1);
             // reserve space for number and offset of entries, and the actual entries
             *outSize += (2 + vector.size()) * sizeof(uint32_t);
         } else {
@@ -5246,6 +5252,10 @@
         if (N == 0) {
             continue;
         }
+        if (N == 1) { // vector expected to hold (offset) + (N > 0 entries)
+            ALOGW("idmap: type %d supposedly has entries, but no entries found\n", i);
+            return UNKNOWN_ERROR;
+        }
         *data++ = htodl(N - 1); // do not count the offset (which is vector's first element)
         for (size_t j = 0; j < N; ++j) {
             const uint32_t& overlayResID = vector.itemAt(j);
diff --git a/packages/SystemUI/src/com/android/systemui/ImageWallpaper.java b/packages/SystemUI/src/com/android/systemui/ImageWallpaper.java
index c60c806..2c94c2b 100644
--- a/packages/SystemUI/src/com/android/systemui/ImageWallpaper.java
+++ b/packages/SystemUI/src/com/android/systemui/ImageWallpaper.java
@@ -287,6 +287,13 @@
                 updateWallpaperLocked();
             }
 
+            if (mBackground == null) {
+                // If we somehow got to this point after we have last flushed
+                // the wallpaper, well we really need it to draw again.  So
+                // seems like we need to reload it.  Ouch.
+                updateWallpaperLocked();
+            }
+
             SurfaceHolder sh = getSurfaceHolder();
             final Rect frame = sh.getSurfaceFrame();
             final int dw = frame.width();
@@ -308,13 +315,6 @@
             mLastXTranslation = xPixels;
             mLastYTranslation = yPixels;
 
-            if (mBackground == null) {
-                // If we somehow got to this point after we have last flushed
-                // the wallpaper, well we really need it to draw again.  So
-                // seems like we need to reload it.  Ouch.
-                updateWallpaperLocked();
-            }
-
             if (mIsHwAccelerated) {
                 if (!drawWallpaperWithOpenGL(sh, availw, availh, xPixels, yPixels)) {
                     drawWallpaperWithCanvas(sh, availw, availh, xPixels, yPixels);
diff --git a/policy/src/com/android/internal/policy/impl/PhoneWindow.java b/policy/src/com/android/internal/policy/impl/PhoneWindow.java
index 4b91422..610d566 100644
--- a/policy/src/com/android/internal/policy/impl/PhoneWindow.java
+++ b/policy/src/com/android/internal/policy/impl/PhoneWindow.java
@@ -1657,7 +1657,9 @@
      */
     private void restorePanelState(SparseArray<Parcelable> icicles) {
         PanelFeatureState st;
-        for (int curFeatureId = icicles.size() - 1; curFeatureId >= 0; curFeatureId--) {
+        int curFeatureId;
+        for (int i = icicles.size() - 1; i >= 0; i--) {
+            curFeatureId = icicles.keyAt(i);
             st = getPanelState(curFeatureId, false /* required */);
             if (st == null) {
                 // The panel must not have been required, and is currently not around, skip it
diff --git a/services/java/com/android/server/pm/Settings.java b/services/java/com/android/server/pm/Settings.java
index d0eda2d..da0ec33 100644
--- a/services/java/com/android/server/pm/Settings.java
+++ b/services/java/com/android/server/pm/Settings.java
@@ -1248,7 +1248,7 @@
 
                     // Avoid any application that has a space in its path
                     // or that is handled by the system.
-                    if (dataPath.indexOf(" ") >= 0 || ai.uid <= Process.FIRST_APPLICATION_UID)
+                    if (dataPath.indexOf(" ") >= 0 || ai.uid < Process.FIRST_APPLICATION_UID)
                         continue;
 
                     // we store on each line the following information for now:
diff --git a/tools/aapt/Bundle.h b/tools/aapt/Bundle.h
index daeadc0..d7cb61a 100644
--- a/tools/aapt/Bundle.h
+++ b/tools/aapt/Bundle.h
@@ -53,7 +53,6 @@
           mWantUTF16(false), mValues(false),
           mCompressionMethod(0), mOutputAPKFile(NULL),
           mManifestPackageNameOverride(NULL), mInstrumentationPackageNameOverride(NULL),
-          mIsOverlayPackage(false),
           mAutoAddOverlay(false), mGenDependencies(false),
           mAssetSourceDir(NULL), 
           mCrunchedOutputDir(NULL), mProguardFile(NULL),
@@ -107,8 +106,6 @@
     void setManifestPackageNameOverride(const char * val) { mManifestPackageNameOverride = val; }
     const char* getInstrumentationPackageNameOverride() const { return mInstrumentationPackageNameOverride; }
     void setInstrumentationPackageNameOverride(const char * val) { mInstrumentationPackageNameOverride = val; }
-    bool getIsOverlayPackage() const { return mIsOverlayPackage; }
-    void setIsOverlayPackage(bool val) { mIsOverlayPackage = val; }
     bool getAutoAddOverlay() { return mAutoAddOverlay; }
     void setAutoAddOverlay(bool val) { mAutoAddOverlay = val; }
     bool getGenDependencies() { return mGenDependencies; }
@@ -250,7 +247,6 @@
     const char* mOutputAPKFile;
     const char* mManifestPackageNameOverride;
     const char* mInstrumentationPackageNameOverride;
-    bool        mIsOverlayPackage;
     bool        mAutoAddOverlay;
     bool        mGenDependencies;
     const char* mAssetSourceDir;
diff --git a/tools/aapt/Main.cpp b/tools/aapt/Main.cpp
index 50c828d..d5d2230 100644
--- a/tools/aapt/Main.cpp
+++ b/tools/aapt/Main.cpp
@@ -69,7 +69,6 @@
         "        [-F apk-file] [-J R-file-dir] \\\n"
         "        [--product product1,product2,...] \\\n"
         "        [-c CONFIGS] [--preferred-configurations CONFIGS] \\\n"
-        "        [-o] \\\n"
         "        [raw-files-dir [raw-files-dir] ...]\n"
         "\n"
         "   Package the android resources.  It will read assets and resources that are\n"
@@ -110,7 +109,6 @@
         "   -j  specify a jar or zip file containing classes to include\n"
         "   -k  junk path of file(s) added\n"
         "   -m  make package directories under location specified by -J\n"
-        "   -o  create overlay package (ie only resources; expects <overlay-package> in manifest)\n"
 #if 0
         "   -p  pseudolocalize the default configuration\n"
 #endif
@@ -292,9 +290,6 @@
             case 'm':
                 bundle.setMakePackageDirs(true);
                 break;
-            case 'o':
-                bundle.setIsOverlayPackage(true);
-                break;
 #if 0
             case 'p':
                 bundle.setPseudolocalize(true);
diff --git a/tools/aapt/ResourceTable.cpp b/tools/aapt/ResourceTable.cpp
index 0195727..d98fe65 100644
--- a/tools/aapt/ResourceTable.cpp
+++ b/tools/aapt/ResourceTable.cpp
@@ -2749,6 +2749,12 @@
             const bool filterable = (typeName != mipmap16);
 
             const size_t N = t != NULL ? t->getOrderedConfigs().size() : 0;
+
+            // Until a non-NO_ENTRY value has been written for a resource,
+            // that resource is invalid; validResources[i] represents
+            // the item at t->getOrderedConfigs().itemAt(i).
+            Vector<bool> validResources;
+            validResources.insertAt(false, 0, N);
             
             // First write the typeSpec chunk, containing information about
             // each resource entry in this type.
@@ -2885,6 +2891,7 @@
                         if (amt < 0) {
                             return amt;
                         }
+                        validResources.editItemAt(ei) = true;
                     } else {
                         index[ei] = htodl(ResTable_type::NO_ENTRY);
                     }
@@ -2895,6 +2902,14 @@
                     (((uint8_t*)data->editData()) + typeStart);
                 tHeader->header.size = htodl(data->getSize()-typeStart);
             }
+
+            for (size_t i = 0; i < N; ++i) {
+                if (!validResources[i]) {
+                    sp<ConfigList> c = t->getOrderedConfigs().itemAt(i);
+                    fprintf(stderr, "warning: no entries written for %s/%s\n",
+                            String8(typeName).string(), String8(c->getName()).string());
+                }
+            }
         }
 
         // Fill in the rest of the package information.
@@ -3723,9 +3738,7 @@
 {
     sp<Package> p = mPackages.valueFor(package);
     if (p == NULL) {
-        if (mBundle->getIsOverlayPackage()) {
-            p = new Package(package, 0x00);
-        } else if (mIsAppPackage) {
+        if (mIsAppPackage) {
             if (mHaveAppPackage) {
                 fprintf(stderr, "Adding multiple application package resources; only one is allowed.\n"
                                 "Use -x to create extended resources.\n");