Merge "Pass additional inputs when spawning apps via the Zygote and add SELinux permission checks."
diff --git a/api/current.txt b/api/current.txt
index 2914942..b06a51d 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -412,7 +412,7 @@
     field public static final int editorExtras = 16843300; // 0x1010224
     field public static final int ellipsize = 16842923; // 0x10100ab
     field public static final int ems = 16843096; // 0x1010158
-    field public static final deprecated int enabled = 16842766; // 0x101000e
+    field public static final int enabled = 16842766; // 0x101000e
     field public static final int endColor = 16843166; // 0x101019e
     field public static final int endYear = 16843133; // 0x101017d
     field public static final int enterFadeDuration = 16843532; // 0x101030c
@@ -19290,6 +19290,7 @@
   public class CdmaCellLocation extends android.telephony.CellLocation {
     ctor public CdmaCellLocation();
     ctor public CdmaCellLocation(android.os.Bundle);
+    method public static double convertQuartSecToDecDegrees(int);
     method public void fillInNotifierBundle(android.os.Bundle);
     method public int getBaseStationId();
     method public int getBaseStationLatitude();
diff --git a/cmds/installd/Android.mk b/cmds/installd/Android.mk
index f277339..3e722ea 100644
--- a/cmds/installd/Android.mk
+++ b/cmds/installd/Android.mk
@@ -34,6 +34,12 @@
 LOCAL_STATIC_LIBRARIES := \
     libdiskusage
 
+ifeq ($(HAVE_SELINUX),true)
+LOCAL_C_INCLUDES += external/libselinux/include
+LOCAL_SHARED_LIBRARIES += libselinux
+LOCAL_CFLAGS := -DHAVE_SELINUX
+endif # HAVE_SELINUX
+
 LOCAL_MODULE := installd
 
 LOCAL_MODULE_TAGS := optional
diff --git a/cmds/installd/commands.c b/cmds/installd/commands.c
index dd92bbe..0dd8156 100644
--- a/cmds/installd/commands.c
+++ b/cmds/installd/commands.c
@@ -17,6 +17,10 @@
 #include "installd.h"
 #include <diskusage/dirsize.h>
 
+#ifdef HAVE_SELINUX
+#include <selinux/android.h>
+#endif
+
 /* Directory records that are used in execution of commands. */
 dir_rec_t android_data_dir;
 dir_rec_t android_asec_dir;
@@ -58,6 +62,15 @@
         unlink(pkgdir);
         return -errno;
     }
+
+#ifdef HAVE_SELINUX
+    if (selinux_android_setfilecon(pkgdir, pkgname, uid) < 0) {
+        LOGE("cannot setfilecon dir '%s': %s\n", pkgdir, strerror(errno));
+        unlink(pkgdir);
+        return -errno;
+    }
+#endif
+
     if (mkdir(libdir, 0755) < 0) {
         ALOGE("cannot create dir '%s': %s\n", libdir, strerror(errno));
         unlink(pkgdir);
@@ -75,6 +88,16 @@
         unlink(pkgdir);
         return -errno;
     }
+
+#ifdef HAVE_SELINUX
+    if (selinux_android_setfilecon(libdir, pkgname, AID_SYSTEM) < 0) {
+        LOGE("cannot setfilecon dir '%s': %s\n", libdir, strerror(errno));
+        unlink(libdir);
+        unlink(pkgdir);
+        return -errno;
+    }
+#endif
+
     return 0;
 }
 
@@ -135,6 +158,15 @@
         unlink(pkgdir);
         return -errno;
     }
+
+#ifdef HAVE_SELINUX
+    if (selinux_android_setfilecon(pkgdir, pkgname, uid) < 0) {
+        LOGE("cannot setfilecon dir '%s': %s\n", pkgdir, strerror(errno));
+        unlink(pkgdir);
+        return -errno;
+    }
+#endif
+
     return 0;
 }
 
@@ -284,12 +316,18 @@
         ALOGE("failed to chgrp '%s': %s\n", pkgpath, strerror(errno));
         return -1;
     }
-
     if (chmod(pkgpath, S_IRUSR|S_IWUSR|S_IRGRP) < 0) {
         ALOGE("failed to chmod '%s': %s\n", pkgpath, strerror(errno));
         return -1;
     }
 
+#ifdef HAVE_SELINUX
+    if (selinux_android_setfilecon(pkgpath, pkgname, s.st_uid) < 0) {
+        LOGE("cannot setfilecon dir '%s': %s\n", pkgpath, strerror(errno));
+        return -1;
+    }
+#endif
+
     return 0;
 }
 
diff --git a/core/java/android/app/Application.java b/core/java/android/app/Application.java
index dd9ea26..3a67cec 100644
--- a/core/java/android/app/Application.java
+++ b/core/java/android/app/Application.java
@@ -64,11 +64,12 @@
     }
 
     /**
-     * Called when the application is starting, before any other application
-     * objects have been created.  Implementations should be as quick as
-     * possible (for example using lazy initialization of state) since the time
-     * spent in this function directly impacts the performance of starting the
-     * first activity, service, or receiver in a process.
+     * Called when the application is starting, before any activity, service,
+     * or receiver objects (excluding content providers) have been created.
+     * Implementations should be as quick as possible (for example using 
+     * lazy initialization of state) since the time spent in this function
+     * directly impacts the performance of starting the first activity,
+     * service, or receiver in a process.
      * If you override this method, be sure to call super.onCreate().
      */
     public void onCreate() {
diff --git a/core/java/android/app/ApplicationThreadNative.java b/core/java/android/app/ApplicationThreadNative.java
index c4a4fea..310d033 100644
--- a/core/java/android/app/ApplicationThreadNative.java
+++ b/core/java/android/app/ApplicationThreadNative.java
@@ -369,6 +369,7 @@
 
         case SCHEDULE_LOW_MEMORY_TRANSACTION:
         {
+            data.enforceInterface(IApplicationThread.descriptor);
             scheduleLowMemory();
             return true;
         }
diff --git a/core/java/android/app/FragmentManager.java b/core/java/android/app/FragmentManager.java
index 1abb7de..7e1daa4 100644
--- a/core/java/android/app/FragmentManager.java
+++ b/core/java/android/app/FragmentManager.java
@@ -1538,6 +1538,9 @@
                     FragmentManagerImpl.VIEW_STATE_TAG, f.mSavedViewState);
         }
         if (!f.mUserVisibleHint) {
+            if (result == null) {
+                result = new Bundle();
+            }
             // Only add this if it's not the default value
             result.putBoolean(FragmentManagerImpl.USER_VISIBLE_HINT_TAG, f.mUserVisibleHint);
         }
@@ -1887,7 +1890,7 @@
         if (mActive != null) {
             for (int i=0; i<mAdded.size(); i++) {
                 Fragment f = mAdded.get(i);
-                if (f != null && !f.mHidden) {
+                if (f != null && !f.mHidden && f.mUserVisibleHint) {
                     if (f.onContextItemSelected(item)) {
                         return true;
                     }
diff --git a/core/java/android/app/admin/DevicePolicyManager.java b/core/java/android/app/admin/DevicePolicyManager.java
old mode 100644
new mode 100755
index 4ed0766..0b58396
--- a/core/java/android/app/admin/DevicePolicyManager.java
+++ b/core/java/android/app/admin/DevicePolicyManager.java
@@ -1008,13 +1008,15 @@
     /**
      * Ask the user date be wiped.  This will cause the device to reboot,
      * erasing all user data while next booting up.  External storage such
-     * as SD cards will not be erased.
+     * as SD cards will be also erased if the flag {@link #WIPE_EXTERNAL_STORAGE}
+     * is set.
      *
      * <p>The calling device admin must have requested
      * {@link DeviceAdminInfo#USES_POLICY_WIPE_DATA} to be able to call
      * this method; if it has not, a security exception will be thrown.
      *
-     * @param flags Bit mask of additional options: currently must be 0.
+     * @param flags Bit mask of additional options: currently 0 and
+     *              {@link #WIPE_EXTERNAL_STORAGE} are supported.
      */
     public void wipeData(int flags) {
         if (mService != null) {
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/view/VolumePanel.java b/core/java/android/view/VolumePanel.java
index 48fe0df..1072953 100644
--- a/core/java/android/view/VolumePanel.java
+++ b/core/java/android/view/VolumePanel.java
@@ -400,7 +400,10 @@
         if (LOGD) Log.d(TAG, "onVolumeChanged(streamType: " + streamType + ", flags: " + flags + ")");
 
         if ((flags & AudioManager.FLAG_SHOW_UI) != 0) {
-            if (mActiveStreamType == -1) {
+                // If the activePanel is none - or - the one we are updating is not the current active panel
+                // then it is likely that the audio stream being updated has been swapped by an app
+                // we need to reorder the sliders to bring the new active one to the front
+            if (mActiveStreamType == -1 || streamType != mActiveStreamType) {
                 reorderSliders(streamType);
             }
             onShowVolumeChanged(streamType, flags);
diff --git a/core/java/android/webkit/WebSettings.java b/core/java/android/webkit/WebSettings.java
index f947f95..e2074ec 100644
--- a/core/java/android/webkit/WebSettings.java
+++ b/core/java/android/webkit/WebSettings.java
@@ -181,6 +181,8 @@
     private boolean         mBlockNetworkImage = false;
     private boolean         mBlockNetworkLoads;
     private boolean         mJavaScriptEnabled = false;
+    private boolean         mAllowUniversalAccessFromFileURLs = true;
+    private boolean         mAllowFileAccessFromFileURLs = true;
     private boolean         mHardwareAccelSkia = false;
     private boolean         mShowVisualIndicator = false;
     private PluginState     mPluginState = PluginState.OFF;
@@ -1264,6 +1266,47 @@
     }
 
     /**
+     * Sets whether JavaScript running in the context of a file scheme URL
+     * should be allowed to access content from any origin. This includes
+     * access to content from other file scheme URLs. See
+     * {@link #setAllowFileAccessFromFileURLs}. To enable the most restrictive,
+     * and therefore secure policy, this setting should be disabled.
+     * <p>
+     * The default value is true.
+     *
+     * @param flag whether JavaScript running in the context of a file scheme
+     *             URL should be allowed to access content from any origin
+     * @hide
+     */
+    public synchronized void setAllowUniversalAccessFromFileURLs(boolean flag) {
+        if (mAllowUniversalAccessFromFileURLs != flag) {
+            mAllowUniversalAccessFromFileURLs = flag;
+            postSync();
+        }
+    }
+
+    /**
+     * Sets whether JavaScript running in the context of a file scheme URL
+     * should be allowed to access content from other file scheme URLs. To
+     * enable the most restrictive, and therefore secure policy, this setting
+     * should be disabled. Note that the value of this setting is ignored if
+     * the value of {@link #getAllowUniversalAccessFromFileURLs} is true.
+     * <p>
+     * The default value is true.
+     *
+     * @param flag whether JavaScript running in the context of a file scheme
+     *             URL should be allowed to access content from other file
+     *             scheme URLs
+     * @hide
+     */
+    public synchronized void setAllowFileAccessFromFileURLs(boolean flag) {
+        if (mAllowFileAccessFromFileURLs != flag) {
+            mAllowFileAccessFromFileURLs = flag;
+            postSync();
+        }
+    }
+
+    /**
      * Tell the WebView to use Skia's hardware accelerated rendering path
      * @param flag True if the WebView should use Skia's hw-accel path
      * @hide
@@ -1500,6 +1543,33 @@
     }
 
     /**
+     * Gets whether JavaScript running in the context of a file scheme URL can
+     * access content from any origin. This includes access to content from
+     * other file scheme URLs.
+     *
+     * @return whether JavaScript running in the context of a file scheme URL
+     *         can access content from any origin
+     * @see #setAllowUniversalAccessFromFileURLs
+     * @hide
+     */
+    public synchronized boolean getAllowUniversalAccessFromFileURLs() {
+        return mAllowUniversalAccessFromFileURLs;
+    }
+
+    /**
+     * Gets whether JavaScript running in the context of a file scheme URL can
+     * access content from other file scheme URLs.
+     *
+     * @return whether JavaScript running in the context of a file scheme URL
+     *         can access content from other file scheme URLs
+     * @see #setAllowFileAccessFromFileURLs
+     * @hide
+     */
+    public synchronized boolean getAllowFileAccessFromFileURLs() {
+        return mAllowFileAccessFromFileURLs;
+    }
+
+    /**
      * Return true if plugins are enabled.
      * @return True if plugins are enabled.
      * @deprecated This method has been replaced by {@link #getPluginState}
diff --git a/core/java/android/widget/Gallery.java b/core/java/android/widget/Gallery.java
index 5e37fa8..ea23a3a 100644
--- a/core/java/android/widget/Gallery.java
+++ b/core/java/android/widget/Gallery.java
@@ -1187,15 +1187,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/GridView.java b/core/java/android/widget/GridView.java
index 5d406de..428af83 100644
--- a/core/java/android/widget/GridView.java
+++ b/core/java/android/widget/GridView.java
@@ -2095,8 +2095,13 @@
             int height = view.getHeight();
             if (height > 0) {
                 final int numColumns = mNumColumns;
-                final int whichRow = mFirstPosition / numColumns;
                 final int rowCount = (mItemCount + numColumns - 1) / numColumns;
+                // In case of stackFromBottom the calculation of whichRow needs
+                // to take into account that counting from the top the first row
+                // might not be entirely filled.
+                final int oddItemsOnFirstRow = isStackFromBottom() ? ((rowCount * numColumns) -
+                        mItemCount) : 0;
+                final int whichRow = (mFirstPosition + oddItemsOnFirstRow) / numColumns;
                 return Math.max(whichRow * 100 - (top * 100) / height +
                         (int) ((float) mScrollY / getHeight() * rowCount * 100), 0);
             }
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/app/ShutdownThread.java b/core/java/com/android/internal/app/ShutdownThread.java
index 77d0c97..96a6428 100644
--- a/core/java/com/android/internal/app/ShutdownThread.java
+++ b/core/java/com/android/internal/app/ShutdownThread.java
@@ -76,6 +76,8 @@
     private PowerManager.WakeLock mCpuWakeLock;
     private PowerManager.WakeLock mScreenWakeLock;
     private Handler mHandler;
+
+    private static AlertDialog sConfirmDialog;
     
     private ShutdownThread() {
     }
@@ -108,7 +110,10 @@
 
         if (confirm) {
             final CloseDialogReceiver closer = new CloseDialogReceiver(context);
-            final AlertDialog dialog = new AlertDialog.Builder(context)
+            if (sConfirmDialog != null) {
+                sConfirmDialog.dismiss();
+            }
+            sConfirmDialog = new AlertDialog.Builder(context)
                     .setTitle(com.android.internal.R.string.power_off)
                     .setMessage(resourceId)
                     .setPositiveButton(com.android.internal.R.string.yes, new DialogInterface.OnClickListener() {
@@ -118,10 +123,10 @@
                     })
                     .setNegativeButton(com.android.internal.R.string.no, null)
                     .create();
-            closer.dialog = dialog;
-            dialog.setOnDismissListener(closer);
-            dialog.getWindow().setType(WindowManager.LayoutParams.TYPE_KEYGUARD_DIALOG);
-            dialog.show();
+            closer.dialog = sConfirmDialog;
+            sConfirmDialog.setOnDismissListener(closer);
+            sConfirmDialog.getWindow().setType(WindowManager.LayoutParams.TYPE_KEYGUARD_DIALOG);
+            sConfirmDialog.show();
         } else {
             beginShutdownSequence(context);
         }
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 530809b..97911dd 100644
--- a/core/java/com/android/internal/view/menu/ActionMenuPresenter.java
+++ b/core/java/com/android/internal/view/menu/ActionMenuPresenter.java
@@ -277,7 +277,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/res/res/layout/transient_notification.xml b/core/res/res/layout/transient_notification.xml
index 21d58aa..5523807 100644
--- a/core/res/res/layout/transient_notification.xml
+++ b/core/res/res/layout/transient_notification.xml
@@ -29,6 +29,7 @@
         android:layout_width="wrap_content"
         android:layout_height="wrap_content"
         android:layout_weight="1"
+        android:layout_gravity="center_horizontal"
         android:textAppearance="@style/TextAppearance.Small"
         android:textColor="@color/bright_foreground_dark"
         android:shadowColor="#BB000000"
diff --git a/core/res/res/values/attrs.xml b/core/res/res/values/attrs.xml
index af59198..c46283f 100755
--- a/core/res/res/values/attrs.xml
+++ b/core/res/res/values/attrs.xml
@@ -3021,7 +3021,11 @@
              inputType attributes are found,  the inputType flags will override the value of
              singleLine.) } -->
         <attr name="singleLine" format="boolean" />
-        <!-- Specifies whether the TextView is enabled or not. {@deprecated Use state_enabled instead}. -->
+        <!-- Specifies whether the widget is enabled. The interpretation of the enabled state varies by subclass.
+             For example, a non-enabled EditText prevents the user from editing the contained text, and
+             a non-enabled Button prevents the user from tapping the button. 
+             The appearance of enabled and non-enabled widgets may differ, if the drawables referenced
+             from evaluating state_enabled differ. -->
         <attr name="enabled" format="boolean" />
         <!-- If the text is selectable, select it all when the view takes
              focus instead of moving the cursor to the start or end. -->
@@ -3052,7 +3056,7 @@
             <!-- Input is numeric. -->
             <flag name="integer" value="0x01" />
             <!-- Input is numeric, with sign allowed. -->
-            <flag name="signed" value="0x003" />
+            <flag name="signed" value="0x03" />
             <!-- Input is numeric, with decimals allowed. -->
             <flag name="decimal" value="0x05" />
         </attr>
diff --git a/core/tests/coretests/apks/install_complete_package_info/Android.mk b/core/tests/coretests/apks/install_complete_package_info/Android.mk
new file mode 100644
index 0000000..1edccb4
--- /dev/null
+++ b/core/tests/coretests/apks/install_complete_package_info/Android.mk
@@ -0,0 +1,11 @@
+LOCAL_PATH:= $(call my-dir)
+include $(CLEAR_VARS)
+
+LOCAL_MODULE_TAGS := tests
+
+LOCAL_SRC_FILES := $(call all-subdir-java-files)
+
+LOCAL_PACKAGE_NAME := FrameworkCoreTests_install_complete_package_info
+
+include $(BUILD_PACKAGE)
+
diff --git a/core/tests/coretests/apks/install_complete_package_info/AndroidManifest.xml b/core/tests/coretests/apks/install_complete_package_info/AndroidManifest.xml
new file mode 100644
index 0000000..4b01736
--- /dev/null
+++ b/core/tests/coretests/apks/install_complete_package_info/AndroidManifest.xml
@@ -0,0 +1,54 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2011 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<manifest
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    package="com.android.frameworks.coretests.install_complete_package_info">
+
+<!--
+     This manifest declares at least one of each of the components that
+     can be retrieved by PackageManager.getInstalledPackages.
+     All the implementing classes are empty implementations
+-->
+
+    <uses-feature
+        android:name="com.android.frameworks.coretests.nonexistent" />
+    <uses-configuration
+        android:reqFiveWayNav="false" />
+
+    <instrumentation
+        android:name="android.test.InstrumentationTestRunner"
+        android:targetPackage="com.android.frameworks.coretests"
+        android:label="Frameworks Core Tests" />
+
+    <permission
+        android:label="test permission"
+        android:name="test_permission"
+        android:protectionLevel="normal" />
+
+    <application
+        android:hasCode="true">
+        <activity
+            android:name="com.android.frameworks.coretests.TestActivity">
+        </activity>
+        <provider
+            android:name="com.android.frameworks.coretests.TestProvider"
+            android:authorities="com.android.frameworks.coretests.testprovider" />
+        <receiver
+            android:name="com.android.frameworks.coretests.TestReceiver" />
+        <service
+            android:name="com.android.frameworks.coretests.TestService" />
+    </application>
+</manifest>
diff --git a/core/tests/coretests/apks/install_complete_package_info/src/com/android/frameworks/coretests/TestActivity.java b/core/tests/coretests/apks/install_complete_package_info/src/com/android/frameworks/coretests/TestActivity.java
new file mode 100644
index 0000000..10d0551
--- /dev/null
+++ b/core/tests/coretests/apks/install_complete_package_info/src/com/android/frameworks/coretests/TestActivity.java
@@ -0,0 +1,24 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package com.android.frameworks.coretests;
+
+import android.app.Activity;
+
+public class TestActivity extends Activity {
+
+}
diff --git a/core/tests/coretests/apks/install_complete_package_info/src/com/android/frameworks/coretests/TestProvider.java b/core/tests/coretests/apks/install_complete_package_info/src/com/android/frameworks/coretests/TestProvider.java
new file mode 100644
index 0000000..59f9f10
--- /dev/null
+++ b/core/tests/coretests/apks/install_complete_package_info/src/com/android/frameworks/coretests/TestProvider.java
@@ -0,0 +1,57 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package com.android.frameworks.coretests;
+
+import android.content.ContentProvider;
+import android.content.ContentValues;
+import android.database.Cursor;
+import android.net.Uri;
+
+public class TestProvider extends ContentProvider {
+
+    @Override
+    public boolean onCreate() {
+        return false;
+    }
+
+    @Override
+    public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs,
+            String sortOrder) {
+        return null;
+    }
+
+    @Override
+    public String getType(Uri uri) {
+        return null;
+    }
+
+    @Override
+    public Uri insert(Uri uri, ContentValues values) {
+        return null;
+    }
+
+    @Override
+    public int delete(Uri uri, String selection, String[] selectionArgs) {
+        return 0;
+    }
+
+    @Override
+    public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) {
+        return 0;
+    }
+}
diff --git a/core/tests/coretests/apks/install_complete_package_info/src/com/android/frameworks/coretests/TestReceiver.java b/core/tests/coretests/apks/install_complete_package_info/src/com/android/frameworks/coretests/TestReceiver.java
new file mode 100644
index 0000000..21f6263
--- /dev/null
+++ b/core/tests/coretests/apks/install_complete_package_info/src/com/android/frameworks/coretests/TestReceiver.java
@@ -0,0 +1,57 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package com.android.frameworks.coretests;
+
+import android.content.ContentProvider;
+import android.content.ContentValues;
+import android.database.Cursor;
+import android.net.Uri;
+
+public class TestReceiver extends ContentProvider {
+
+    @Override
+    public boolean onCreate() {
+        return false;
+    }
+
+    @Override
+    public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs,
+            String sortOrder) {
+        return null;
+    }
+
+    @Override
+    public String getType(Uri uri) {
+        return null;
+    }
+
+    @Override
+    public Uri insert(Uri uri, ContentValues values) {
+        return null;
+    }
+
+    @Override
+    public int delete(Uri uri, String selection, String[] selectionArgs) {
+        return 0;
+    }
+
+    @Override
+    public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) {
+        return 0;
+    }
+}
diff --git a/core/tests/coretests/apks/install_complete_package_info/src/com/android/frameworks/coretests/TestService.java b/core/tests/coretests/apks/install_complete_package_info/src/com/android/frameworks/coretests/TestService.java
new file mode 100644
index 0000000..b330e75
--- /dev/null
+++ b/core/tests/coretests/apks/install_complete_package_info/src/com/android/frameworks/coretests/TestService.java
@@ -0,0 +1,30 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package com.android.frameworks.coretests;
+
+import android.app.Service;
+import android.content.Intent;
+import android.os.IBinder;
+
+public class TestService extends Service {
+
+    @Override
+    public IBinder onBind(Intent intent) {
+        return null;
+    }
+}
diff --git a/core/tests/coretests/src/android/content/pm/PackageManagerTests.java b/core/tests/coretests/src/android/content/pm/PackageManagerTests.java
index 9575ced..276f4f3 100755
--- a/core/tests/coretests/src/android/content/pm/PackageManagerTests.java
+++ b/core/tests/coretests/src/android/content/pm/PackageManagerTests.java
@@ -23,6 +23,7 @@
 import android.content.Context;
 import android.content.Intent;
 import android.content.IntentFilter;
+import android.content.pm.PackageInfo;
 import android.content.pm.PackageManager;
 import android.content.pm.PackageManager.NameNotFoundException;
 import android.content.res.Resources;
@@ -50,6 +51,8 @@
 import java.io.IOException;
 import java.io.InputStream;
 
+import java.util.List;
+
 public class PackageManagerTests extends AndroidTestCase {
     private static final boolean localLOGV = true;
     public static final String TAG="PackageManagerTests";
@@ -3130,6 +3133,92 @@
         assertNotNull("Verifier device identity should not be null", id);
     }
 
+    public void testGetInstalledPackages() {
+        List<PackageInfo> packages = getPm().getInstalledPackages(0);
+        assertNotNull("installed packages cannot be null", packages);
+        assertTrue("installed packages cannot be empty", packages.size() > 0);
+    }
+
+    public void testGetUnInstalledPackages() {
+        List<PackageInfo> packages = getPm().getInstalledPackages(
+                PackageManager.GET_UNINSTALLED_PACKAGES);
+        assertNotNull("installed packages cannot be null", packages);
+        assertTrue("installed packages cannot be empty", packages.size() > 0);
+    }
+
+    /**
+     * Test that getInstalledPackages returns all the data specified in
+     * flags.
+     */
+    public void testGetInstalledPackagesAll() {
+        int flags = PackageManager.GET_ACTIVITIES | PackageManager.GET_GIDS
+                | PackageManager.GET_CONFIGURATIONS | PackageManager.GET_INSTRUMENTATION
+                | PackageManager.GET_PERMISSIONS | PackageManager.GET_PROVIDERS
+                | PackageManager.GET_RECEIVERS | PackageManager.GET_SERVICES
+                | PackageManager.GET_SIGNATURES | PackageManager.GET_UNINSTALLED_PACKAGES;
+
+        List<PackageInfo> packages = getPm().getInstalledPackages(flags);
+        assertNotNull("installed packages cannot be null", packages);
+        assertTrue("installed packages cannot be empty", packages.size() > 0);
+
+        PackageInfo packageInfo = null;
+
+        // Find the package with all components specified in the AndroidManifest
+        // to ensure no null values
+        for (PackageInfo pi : packages) {
+            if ("com.android.frameworks.coretests.install_complete_package_info"
+                    .equals(pi.packageName)) {
+                packageInfo = pi;
+                break;
+            }
+        }
+        assertNotNull("activities should not be null", packageInfo.activities);
+        assertNotNull("configPreferences should not be null", packageInfo.configPreferences);
+        assertNotNull("instrumentation should not be null", packageInfo.instrumentation);
+        assertNotNull("permissions should not be null", packageInfo.permissions);
+        assertNotNull("providers should not be null", packageInfo.providers);
+        assertNotNull("receivers should not be null", packageInfo.receivers);
+        assertNotNull("services should not be null", packageInfo.services);
+        assertNotNull("signatures should not be null", packageInfo.signatures);
+    }
+
+    /**
+     * Test that getInstalledPackages returns all the data specified in
+     * flags when the GET_UNINSTALLED_PACKAGES flag is set.
+     */
+    public void testGetUnInstalledPackagesAll() {
+        int flags = PackageManager.GET_UNINSTALLED_PACKAGES
+                | PackageManager.GET_ACTIVITIES | PackageManager.GET_GIDS
+                | PackageManager.GET_CONFIGURATIONS | PackageManager.GET_INSTRUMENTATION
+                | PackageManager.GET_PERMISSIONS | PackageManager.GET_PROVIDERS
+                | PackageManager.GET_RECEIVERS | PackageManager.GET_SERVICES
+                | PackageManager.GET_SIGNATURES | PackageManager.GET_UNINSTALLED_PACKAGES;
+
+        List<PackageInfo> packages = getPm().getInstalledPackages(flags);
+        assertNotNull("installed packages cannot be null", packages);
+        assertTrue("installed packages cannot be empty", packages.size() > 0);
+
+        PackageInfo packageInfo = null;
+
+        // Find the package with all components specified in the AndroidManifest
+        // to ensure no null values
+        for (PackageInfo pi : packages) {
+            if ("com.android.frameworks.coretests.install_complete_package_info"
+                    .equals(pi.packageName)) {
+                packageInfo = pi;
+                break;
+            }
+        }
+        assertNotNull("activities should not be null", packageInfo.activities);
+        assertNotNull("configPreferences should not be null", packageInfo.configPreferences);
+        assertNotNull("instrumentation should not be null", packageInfo.instrumentation);
+        assertNotNull("permissions should not be null", packageInfo.permissions);
+        assertNotNull("providers should not be null", packageInfo.providers);
+        assertNotNull("receivers should not be null", packageInfo.receivers);
+        assertNotNull("services should not be null", packageInfo.services);
+        assertNotNull("signatures should not be null", packageInfo.signatures);
+    }
+
     /*---------- Recommended install location tests ----*/
     /*
      * TODO's
diff --git a/core/tests/overlaytests/OverlayTestOverlay/Android.mk b/core/tests/overlaytests/OverlayTestOverlay/Android.mk
index cf32c9f..b1327f71 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/drm/common/DrmEngineBase.cpp b/drm/common/DrmEngineBase.cpp
index 9b16c36..0ef58f3 100644
--- a/drm/common/DrmEngineBase.cpp
+++ b/drm/common/DrmEngineBase.cpp
@@ -129,6 +129,11 @@
     return onOpenDecryptSession(uniqueId, decryptHandle, uri);
 }
 
+status_t DrmEngineBase::openDecryptSession(int uniqueId, DecryptHandle* decryptHandle,
+        const DrmBuffer& buf, const String8& mimeType) {
+    return onOpenDecryptSession(uniqueId, decryptHandle, buf, mimeType);
+}
+
 status_t DrmEngineBase::closeDecryptSession(int uniqueId, DecryptHandle* decryptHandle) {
     return onCloseDecryptSession(uniqueId, decryptHandle);
 }
diff --git a/drm/common/IDrmManagerService.cpp b/drm/common/IDrmManagerService.cpp
index 3ed8ade..f5352bb 100644
--- a/drm/common/IDrmManagerService.cpp
+++ b/drm/common/IDrmManagerService.cpp
@@ -640,6 +640,33 @@
     return handle;
 }
 
+DecryptHandle* BpDrmManagerService::openDecryptSession(
+            int uniqueId, const DrmBuffer& buf, const String8& mimeType) {
+    ALOGV("Entering BpDrmManagerService::openDecryptSession");
+    Parcel data, reply;
+
+    data.writeInterfaceToken(IDrmManagerService::getInterfaceDescriptor());
+    data.writeInt32(uniqueId);
+    if (buf.data != NULL && buf.length > 0) {
+        data.writeInt32(buf.length);
+        data.write(buf.data, buf.length);
+    } else {
+        data.writeInt32(0);
+    }
+    data.writeString8(mimeType);
+
+    remote()->transact(OPEN_DECRYPT_SESSION_FOR_STREAMING, data, &reply);
+
+    DecryptHandle* handle = NULL;
+    if (0 != reply.dataAvail()) {
+        handle = new DecryptHandle();
+        readDecryptHandleFromParcelData(handle, reply);
+    } else {
+        ALOGV("no decryptHandle is generated in service side");
+    }
+    return handle;
+}
+
 status_t BpDrmManagerService::closeDecryptSession(int uniqueId, DecryptHandle* decryptHandle) {
     ALOGV("closeDecryptSession");
     Parcel data, reply;
@@ -1297,6 +1324,30 @@
         return DRM_NO_ERROR;
     }
 
+    case OPEN_DECRYPT_SESSION_FOR_STREAMING:
+    {
+        ALOGV("BnDrmManagerService::onTransact :OPEN_DECRYPT_SESSION_FOR_STREAMING");
+        CHECK_INTERFACE(IDrmManagerService, data, reply);
+
+        const int uniqueId = data.readInt32();
+        const int bufferSize = data.readInt32();
+        DrmBuffer buf((bufferSize > 0) ? (char *)data.readInplace(bufferSize) : NULL,
+                bufferSize);
+        const String8 mimeType(data.readString8());
+
+        DecryptHandle* handle = openDecryptSession(uniqueId, buf, mimeType);
+
+        if (handle != NULL) {
+            writeDecryptHandleToParcelData(handle, reply);
+            clearDecryptHandle(handle);
+            delete handle;
+            handle = NULL;
+        } else {
+            ALOGV("NULL decryptHandle is returned");
+        }
+        return DRM_NO_ERROR;
+    }
+
     case CLOSE_DECRYPT_SESSION:
     {
         ALOGV("BnDrmManagerService::onTransact :CLOSE_DECRYPT_SESSION");
diff --git a/drm/drmserver/DrmManager.cpp b/drm/drmserver/DrmManager.cpp
index 3abf3d3..c528ffc 100644
--- a/drm/drmserver/DrmManager.cpp
+++ b/drm/drmserver/DrmManager.cpp
@@ -481,6 +481,36 @@
     return handle;
 }
 
+DecryptHandle* DrmManager::openDecryptSession(
+        int uniqueId, const DrmBuffer& buf, const String8& mimeType) {
+    Mutex::Autolock _l(mDecryptLock);
+    status_t result = DRM_ERROR_CANNOT_HANDLE;
+    Vector<String8> plugInIdList = mPlugInManager.getPlugInIdList();
+
+    DecryptHandle* handle = new DecryptHandle();
+    if (NULL != handle) {
+        handle->decryptId = mDecryptSessionId + 1;
+
+        for (size_t index = 0; index < plugInIdList.size(); index++) {
+            String8 plugInId = plugInIdList.itemAt(index);
+            IDrmEngine& rDrmEngine = mPlugInManager.getPlugIn(plugInId);
+            result = rDrmEngine.openDecryptSession(uniqueId, handle, buf, mimeType);
+
+            if (DRM_NO_ERROR == result) {
+                ++mDecryptSessionId;
+                mDecryptSessionMap.add(mDecryptSessionId, &rDrmEngine);
+                break;
+            }
+        }
+    }
+    if (DRM_NO_ERROR != result) {
+        delete handle;
+        handle = NULL;
+        ALOGV("DrmManager::openDecryptSession: no capable plug-in found");
+    }
+    return handle;
+}
+
 status_t DrmManager::closeDecryptSession(int uniqueId, DecryptHandle* decryptHandle) {
     Mutex::Autolock _l(mDecryptLock);
     status_t result = DRM_ERROR_UNKNOWN;
diff --git a/drm/drmserver/DrmManagerService.cpp b/drm/drmserver/DrmManagerService.cpp
index df17ac5..9f899c3 100644
--- a/drm/drmserver/DrmManagerService.cpp
+++ b/drm/drmserver/DrmManagerService.cpp
@@ -227,6 +227,16 @@
     return NULL;
 }
 
+DecryptHandle* DrmManagerService::openDecryptSession(
+            int uniqueId, const DrmBuffer& buf, const String8& mimeType) {
+    ALOGV("Entering DrmManagerService::openDecryptSession for streaming");
+    if (isProtectedCallAllowed()) {
+        return mDrmManager->openDecryptSession(uniqueId, buf, mimeType);
+    }
+
+    return NULL;
+}
+
 status_t DrmManagerService::closeDecryptSession(int uniqueId, DecryptHandle* decryptHandle) {
     ALOGV("Entering closeDecryptSession");
     return mDrmManager->closeDecryptSession(uniqueId, decryptHandle);
diff --git a/drm/libdrmframework/DrmManagerClient.cpp b/drm/libdrmframework/DrmManagerClient.cpp
index c9c0d57..a48671c 100644
--- a/drm/libdrmframework/DrmManagerClient.cpp
+++ b/drm/libdrmframework/DrmManagerClient.cpp
@@ -124,6 +124,11 @@
     return mDrmManagerClientImpl->openDecryptSession(mUniqueId, uri);
 }
 
+sp<DecryptHandle> DrmManagerClient::openDecryptSession(
+            const DrmBuffer& buf, const String8& mimeType) {
+    return mDrmManagerClientImpl->openDecryptSession(mUniqueId, buf, mimeType);
+}
+
 status_t DrmManagerClient::closeDecryptSession(sp<DecryptHandle> &decryptHandle) {
     return mDrmManagerClientImpl->closeDecryptSession(mUniqueId, decryptHandle);
 }
diff --git a/drm/libdrmframework/DrmManagerClientImpl.cpp b/drm/libdrmframework/DrmManagerClientImpl.cpp
index b222b8f..a4a5b10 100644
--- a/drm/libdrmframework/DrmManagerClientImpl.cpp
+++ b/drm/libdrmframework/DrmManagerClientImpl.cpp
@@ -268,6 +268,11 @@
     return handle;
 }
 
+sp<DecryptHandle> DrmManagerClientImpl::openDecryptSession(
+            int uniqueId, const DrmBuffer& buf, const String8& mimeType) {
+    return getDrmManagerService()->openDecryptSession(uniqueId, buf, mimeType);
+}
+
 status_t DrmManagerClientImpl::closeDecryptSession(
         int uniqueId, sp<DecryptHandle> &decryptHandle) {
     status_t status = DRM_ERROR_UNKNOWN;
diff --git a/drm/libdrmframework/include/DrmManager.h b/drm/libdrmframework/include/DrmManager.h
index ac2b946..5c498d7 100644
--- a/drm/libdrmframework/include/DrmManager.h
+++ b/drm/libdrmframework/include/DrmManager.h
@@ -115,6 +115,9 @@
 
     DecryptHandle* openDecryptSession(int uniqueId, const char* uri);
 
+    DecryptHandle* openDecryptSession(int uniqueId, const DrmBuffer& buf,
+            const String8& mimeType);
+
     status_t closeDecryptSession(int uniqueId, DecryptHandle* decryptHandle);
 
     status_t initializeDecryptUnit(int uniqueId, DecryptHandle* decryptHandle,
diff --git a/drm/libdrmframework/include/DrmManagerClientImpl.h b/drm/libdrmframework/include/DrmManagerClientImpl.h
index e3338d9..3f66860 100644
--- a/drm/libdrmframework/include/DrmManagerClientImpl.h
+++ b/drm/libdrmframework/include/DrmManagerClientImpl.h
@@ -316,6 +316,18 @@
     sp<DecryptHandle> openDecryptSession(int uniqueId, const char* uri);
 
     /**
+     * Open the decrypt session to decrypt the given protected content
+     *
+     * @param[in] uniqueId Unique identifier for a session
+     * @param[in] buf Data to initiate decrypt session
+     * @param[in] mimeType Mime type of the protected content
+     * @return
+     *     Handle for the decryption session
+     */
+    sp<DecryptHandle> openDecryptSession(int uniqueId, const DrmBuffer& buf,
+            const String8& mimeType);
+
+    /**
      * Close the decrypt session for the given handle
      *
      * @param[in] uniqueId Unique identifier for a session
diff --git a/drm/libdrmframework/include/DrmManagerService.h b/drm/libdrmframework/include/DrmManagerService.h
index 9cb5804..9de8c82 100644
--- a/drm/libdrmframework/include/DrmManagerService.h
+++ b/drm/libdrmframework/include/DrmManagerService.h
@@ -102,6 +102,9 @@
 
     DecryptHandle* openDecryptSession(int uniqueId, const char* uri);
 
+    DecryptHandle* openDecryptSession(int uniqueId, const DrmBuffer& buf,
+            const String8& mimeType);
+
     status_t closeDecryptSession(int uniqueId, DecryptHandle* decryptHandle);
 
     status_t initializeDecryptUnit(int uniqueId, DecryptHandle* decryptHandle,
diff --git a/drm/libdrmframework/include/IDrmManagerService.h b/drm/libdrmframework/include/IDrmManagerService.h
index b9618bb..bb8d980 100644
--- a/drm/libdrmframework/include/IDrmManagerService.h
+++ b/drm/libdrmframework/include/IDrmManagerService.h
@@ -70,6 +70,7 @@
         GET_ALL_SUPPORT_INFO,
         OPEN_DECRYPT_SESSION,
         OPEN_DECRYPT_SESSION_FROM_URI,
+        OPEN_DECRYPT_SESSION_FOR_STREAMING,
         CLOSE_DECRYPT_SESSION,
         INITIALIZE_DECRYPT_UNIT,
         DECRYPT,
@@ -143,6 +144,9 @@
 
     virtual DecryptHandle* openDecryptSession(int uniqueId, const char* uri) = 0;
 
+    virtual DecryptHandle* openDecryptSession(
+            int uniqueId, const DrmBuffer& buf, const String8& mimeType) = 0;
+
     virtual status_t closeDecryptSession(int uniqueId, DecryptHandle* decryptHandle) = 0;
 
     virtual status_t initializeDecryptUnit(int uniqueId, DecryptHandle* decryptHandle,
@@ -226,6 +230,9 @@
 
     virtual DecryptHandle* openDecryptSession(int uniqueId, const char* uri);
 
+    virtual DecryptHandle* openDecryptSession(
+            int uniqueId, const DrmBuffer& buf, const String8& mimeType);
+
     virtual status_t closeDecryptSession(int uniqueId, DecryptHandle* decryptHandle);
 
     virtual status_t initializeDecryptUnit(int uniqueId, DecryptHandle* decryptHandle,
diff --git a/drm/libdrmframework/plugins/common/include/DrmEngineBase.h b/drm/libdrmframework/plugins/common/include/DrmEngineBase.h
index 4a5afcf..c726f03 100644
--- a/drm/libdrmframework/plugins/common/include/DrmEngineBase.h
+++ b/drm/libdrmframework/plugins/common/include/DrmEngineBase.h
@@ -85,6 +85,9 @@
     status_t openDecryptSession(
             int uniqueId, DecryptHandle* decryptHandle, const char* uri);
 
+    status_t openDecryptSession(int uniqueId, DecryptHandle* decryptHandle,
+            const DrmBuffer& buf, const String8& mimeType);
+
     status_t closeDecryptSession(int uniqueId, DecryptHandle* decryptHandle);
 
     status_t initializeDecryptUnit(int uniqueId, DecryptHandle* decryptHandle,
@@ -390,6 +393,21 @@
             int uniqueId, DecryptHandle* decryptHandle, const char* uri) = 0;
 
     /**
+     * Open the decrypt session to decrypt the given protected content
+     *
+     * @param[in] uniqueId Unique identifier for a session
+     * @param[in] decryptHandle Handle for the current decryption session
+     * @param[in] buf Data to initiate decrypt session
+     * @param[in] mimeType Mime type of the protected content
+     * @return
+     *     DRM_ERROR_CANNOT_HANDLE for failure and DRM_NO_ERROR for success
+     */
+    virtual status_t onOpenDecryptSession(int uniqueId, DecryptHandle* decryptHandle,
+            const DrmBuffer& buf, const String8& mimeType) {
+        return DRM_ERROR_CANNOT_HANDLE;
+    }
+
+    /**
      * Close the decrypt session for the given handle
      *
      * @param[in] uniqueId Unique identifier for a session
diff --git a/drm/libdrmframework/plugins/common/include/IDrmEngine.h b/drm/libdrmframework/plugins/common/include/IDrmEngine.h
index 77460f6..2ebbb71 100644
--- a/drm/libdrmframework/plugins/common/include/IDrmEngine.h
+++ b/drm/libdrmframework/plugins/common/include/IDrmEngine.h
@@ -339,6 +339,19 @@
         int uniqueId, DecryptHandle* decryptHandle, const char* uri) = 0;
 
     /**
+     * Open the decrypt session to decrypt the given protected content
+     *
+     * @param[in] uniqueId Unique identifier for a session
+     * @param[in] decryptHandle Handle for the current decryption session
+     * @param[in] buf Data to initiate decrypt session
+     * @param[in] mimeType Mime type of the protected content
+     * @return
+     *     DRM_ERROR_CANNOT_HANDLE for failure and DRM_NO_ERROR for success
+     */
+    virtual status_t openDecryptSession(int uniqueId, DecryptHandle* decryptHandle,
+            const DrmBuffer& buf, const String8& mimeType) = 0;
+
+    /**
      * Close the decrypt session for the given handle
      *
      * @param[in] uniqueId Unique identifier for a session
diff --git a/include/drm/DrmManagerClient.h b/include/drm/DrmManagerClient.h
index b8fe46d..0cb503c 100644
--- a/include/drm/DrmManagerClient.h
+++ b/include/drm/DrmManagerClient.h
@@ -81,6 +81,16 @@
     sp<DecryptHandle> openDecryptSession(const char* uri);
 
     /**
+     * Open the decrypt session to decrypt the given protected content
+     *
+     * @param[in] buf Data to initiate decrypt session
+     * @param[in] mimeType Mime type of the protected content
+     * @return
+     *     Handle for the decryption session
+     */
+    sp<DecryptHandle> openDecryptSession(const DrmBuffer& buf, const String8& mimeType);
+
+    /**
      * Close the decrypt session for the given handle
      *
      * @param[in] decryptHandle Handle for the decryption session
diff --git a/include/gui/SurfaceTexture.h b/include/gui/SurfaceTexture.h
index a8c7672..511b3ec 100644
--- a/include/gui/SurfaceTexture.h
+++ b/include/gui/SurfaceTexture.h
@@ -38,6 +38,12 @@
 class IGraphicBufferAlloc;
 class String8;
 
+class BufferQueue : public RefBase {
+public:
+    BufferQueue(bool allowSynchronousMode) {};
+    status_t setBufferCount(int bufferCount) { return 0; }
+};
+
 class SurfaceTexture : public BnSurfaceTexture {
 public:
     enum { MIN_UNDEQUEUED_BUFFERS = 2 };
@@ -69,7 +75,8 @@
     // fences should be used to synchronize access to buffers if that behavior
     // is enabled at compile-time.
     SurfaceTexture(GLuint tex, bool allowSynchronousMode = true,
-            GLenum texTarget = GL_TEXTURE_EXTERNAL_OES, bool useFenceSync = true);
+            GLenum texTarget = GL_TEXTURE_EXTERNAL_OES, bool useFenceSync = true,
+            const sp<BufferQueue> &bufferQueue = 0);
 
     virtual ~SurfaceTexture();
 
diff --git a/include/private/hwui/DrawGlInfo.h b/include/private/hwui/DrawGlInfo.h
index 1e9912b..e33823e 100644
--- a/include/private/hwui/DrawGlInfo.h
+++ b/include/private/hwui/DrawGlInfo.h
@@ -31,6 +31,10 @@
     int clipRight;
     int clipBottom;
 
+    // Input: current width/height of destination surface
+    int width;
+    int height;
+
     // Input: is the render target an FBO
     bool isLayer;
 
@@ -42,6 +46,34 @@
     float dirtyTop;
     float dirtyRight;
     float dirtyBottom;
+
+    /**
+     * Values used as the "what" parameter of the functor.
+     */
+    enum Mode {
+        // Indicates that the functor is called to perform a draw
+        kModeDraw,
+        // Indicates the the functor is called only to perform
+        // processing and that no draw should be attempted
+        kModeProcess
+    };
+
+    /**
+     * Values used by OpenGL functors to tell the framework
+     * what to do next.
+     */
+    enum Status {
+        // The functor is done
+        kStatusDone = 0x0,
+        // The functor is requesting a redraw (the clip rect
+        // used by the redraw is specified by DrawGlInfo.)
+        // The rest of the UI might redraw too.
+        kStatusDraw = 0x1,
+        // The functor needs to be invoked again but will
+        // not redraw. Only the functor is invoked again
+        // (unless another functor requests a redraw.)
+        kStatusInvoke = 0x2
+    };
 }; // struct DrawGlInfo
 
 }; // namespace uirenderer
diff --git a/include/utils/Trace.h b/include/utils/Trace.h
new file mode 100644
index 0000000..a0112d0
--- /dev/null
+++ b/include/utils/Trace.h
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_TRACE_H
+#define ANDROID_TRACE_H
+
+#define ATRACE_TAG_NEVER    0           // The "never" tag is never enabled.
+#define ATRACE_TAG_ALWAYS   (1<<0)      // The "always" tag is always enabled.
+#define ATRACE_TAG_GRAPHICS (1<<1)
+#define ATRACE_TAG_INPUT    (1<<2)
+#define ATRACE_TAG_VIEW     (1<<3)
+#define ATRACE_TAG_WEBVIEW  (1<<4)
+
+#define ATRACE_CALL()
+
+#define ATRACE_INT(name, value)
+
+#define ATRACE_ENABLED() false
+
+namespace android {
+
+class ScopedTrace {
+
+public:
+    inline ScopedTrace(uint64_t tag, const char* name) {}
+};
+
+}; // namespace android
+
+#endif // ANDROID_TRACE_H
diff --git a/libs/binder/Parcel.cpp b/libs/binder/Parcel.cpp
index 3400e97..2480dec 100644
--- a/libs/binder/Parcel.cpp
+++ b/libs/binder/Parcel.cpp
@@ -1047,10 +1047,11 @@
 {
   int32_t exception_code = readAligned<int32_t>();
   if (exception_code == EX_HAS_REPLY_HEADER) {
+    int32_t header_start = dataPosition();
     int32_t header_size = readAligned<int32_t>();
     // Skip over fat responses headers.  Not used (or propagated) in
     // native code
-    setDataPosition(dataPosition() + header_size);
+    setDataPosition(header_start + header_size);
     // And fat response headers are currently only used when there are no
     // exceptions, so return no error:
     return 0;
diff --git a/libs/gui/SurfaceTexture.cpp b/libs/gui/SurfaceTexture.cpp
index c80d93d..5a643d3 100644
--- a/libs/gui/SurfaceTexture.cpp
+++ b/libs/gui/SurfaceTexture.cpp
@@ -115,7 +115,7 @@
 }
 
 SurfaceTexture::SurfaceTexture(GLuint tex, bool allowSynchronousMode,
-        GLenum texTarget, bool useFenceSync) :
+        GLenum texTarget, bool useFenceSync, const sp<BufferQueue> &bufferQueue) :
     mDefaultWidth(1),
     mDefaultHeight(1),
     mPixelFormat(PIXEL_FORMAT_RGBA_8888),
diff --git a/libs/rs/driver/rsdCore.cpp b/libs/rs/driver/rsdCore.cpp
index b514e21..4b61167 100644
--- a/libs/rs/driver/rsdCore.cpp
+++ b/libs/rs/driver/rsdCore.cpp
@@ -274,10 +274,9 @@
     for (uint32_t ct = 0; ct < dc->mWorkers.mCount; ct++) {
         dc->mWorkers.mLaunchSignals[ct].set();
     }
-    int status;
     void *res;
     for (uint32_t ct = 0; ct < dc->mWorkers.mCount; ct++) {
-        status = pthread_join(dc->mWorkers.mThreadId[ct], &res);
+        pthread_join(dc->mWorkers.mThreadId[ct], &res);
     }
     rsAssert(android_atomic_acquire_load(&dc->mWorkers.mRunningCount) == 0);
 
diff --git a/libs/utils/ResourceTypes.cpp b/libs/utils/ResourceTypes.cpp
index 15b83bb..5aded24 100644
--- a/libs/utils/ResourceTypes.cpp
+++ b/libs/utils/ResourceTypes.cpp
@@ -4333,7 +4333,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) {
@@ -4341,12 +4342,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;
             }
 
@@ -4359,13 +4362,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",
@@ -4376,13 +4379,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 {
@@ -4420,6 +4426,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/media/java/android/media/MediaFile.java b/media/java/android/media/MediaFile.java
index e275aa6..d674374 100644
--- a/media/java/android/media/MediaFile.java
+++ b/media/java/android/media/MediaFile.java
@@ -172,6 +172,7 @@
 
     static {
         addFileType("MP3", FILE_TYPE_MP3, "audio/mpeg", MtpConstants.FORMAT_MP3);
+        addFileType("MPGA", FILE_TYPE_MP3, "audio/mpeg", MtpConstants.FORMAT_MP3);
         addFileType("M4A", FILE_TYPE_M4A, "audio/mp4", MtpConstants.FORMAT_MPEG);
         addFileType("WAV", FILE_TYPE_WAV, "audio/x-wav", MtpConstants.FORMAT_WAV);
         addFileType("AMR", FILE_TYPE_AMR, "audio/amr");
diff --git a/media/jni/android_media_MediaScanner.cpp b/media/jni/android_media_MediaScanner.cpp
index 5d27966..f930a03 100644
--- a/media/jni/android_media_MediaScanner.cpp
+++ b/media/jni/android_media_MediaScanner.cpp
@@ -19,6 +19,7 @@
 #define LOG_TAG "MediaScannerJNI"
 #include <utils/Log.h>
 #include <utils/threads.h>
+#include <utils/Unicode.h>
 #include <media/mediascanner.h>
 #include <media/stagefright/StagefrightMediaScanner.h>
 
@@ -56,53 +57,6 @@
     return OK;
 }
 
-// stolen from dalvik/vm/checkJni.cpp
-static bool isValidUtf8(const char* bytes) {
-    while (*bytes != '\0') {
-        unsigned char utf8 = *(bytes++);
-        // Switch on the high four bits.
-        switch (utf8 >> 4) {
-        case 0x00:
-        case 0x01:
-        case 0x02:
-        case 0x03:
-        case 0x04:
-        case 0x05:
-        case 0x06:
-        case 0x07:
-            // Bit pattern 0xxx. No need for any extra bytes.
-            break;
-        case 0x08:
-        case 0x09:
-        case 0x0a:
-        case 0x0b:
-        case 0x0f:
-            /*
-             * Bit pattern 10xx or 1111, which are illegal start bytes.
-             * Note: 1111 is valid for normal UTF-8, but not the
-             * modified UTF-8 used here.
-             */
-            return false;
-        case 0x0e:
-            // Bit pattern 1110, so there are two additional bytes.
-            utf8 = *(bytes++);
-            if ((utf8 & 0xc0) != 0x80) {
-                return false;
-            }
-            // Fall through to take care of the final byte.
-        case 0x0c:
-        case 0x0d:
-            // Bit pattern 110x, so there is one additional byte.
-            utf8 = *(bytes++);
-            if ((utf8 & 0xc0) != 0x80) {
-                return false;
-            }
-            break;
-        }
-    }
-    return true;
-}
-
 class MyMediaScannerClient : public MediaScannerClient
 {
 public:
@@ -170,8 +124,11 @@
             mEnv->ExceptionClear();
             return NO_MEMORY;
         }
+
+        // Check if the value is valid UTF-8 string and replace
+        // any un-printable characters with '?' when it's not.
         char *cleaned = NULL;
-        if (!isValidUtf8(value)) {
+        if (utf8_length(value) == -1) {
             cleaned = strdup(value);
             char *chp = cleaned;
             char ch;
diff --git a/media/libmedia/MediaProfiles.cpp b/media/libmedia/MediaProfiles.cpp
index c905762..d02ac1a 100644
--- a/media/libmedia/MediaProfiles.cpp
+++ b/media/libmedia/MediaProfiles.cpp
@@ -514,16 +514,16 @@
         // Check high and low from either camcorder profile or timelapse profile
         // but not both. Default, check camcorder profile
         size_t j = 0;
-        size_t n = 2;
+        size_t o = 2;
         if (isTimelapseProfile(quality)) {
             // Check timelapse profile instead.
             j = 2;
-            n = kNumRequiredProfiles;
+            o = kNumRequiredProfiles;
         } else {
             // Must be camcorder profile.
             CHECK(isCamcorderProfile(quality));
         }
-        for (; j < n; ++j) {
+        for (; j < o; ++j) {
             info = &(mRequiredProfileRefs[refIndex].mRefs[j]);
             if ((j % 2 == 0 && product > info->mResolutionProduct) ||  // low
                 (j % 2 != 0 && product < info->mResolutionProduct)) {  // high
diff --git a/media/libstagefright/Android.mk b/media/libstagefright/Android.mk
index 690deac..ba54dcb 100644
--- a/media/libstagefright/Android.mk
+++ b/media/libstagefright/Android.mk
@@ -95,10 +95,12 @@
 # currently must follow the same logic to determine how webkit was built and
 # if it's safe to link against libchromium.net
 
-# V8 also requires an ARMv7 CPU, and since we must use jsc, we cannot
+# On ARM, V8 also requires an ARMv7 CPU, and since we must use jsc, we cannot
 # use the Chrome http stack either.
-ifneq ($(strip $(ARCH_ARM_HAVE_ARMV7A)),true)
-  USE_ALT_HTTP := true
+ifeq ($(TARGET_ARCH),arm)
+  ifneq ($(strip $(ARCH_ARM_HAVE_ARMV7A)),true)
+    USE_ALT_HTTP := true
+  endif
 endif
 
 # See if the user has specified a stack they want to use
diff --git a/media/libstagefright/codecs/aacenc/basic_op/oper_32b.c b/media/libstagefright/codecs/aacenc/basic_op/oper_32b.c
index 982f4fd..cc01927 100644
--- a/media/libstagefright/codecs/aacenc/basic_op/oper_32b.c
+++ b/media/libstagefright/codecs/aacenc/basic_op/oper_32b.c
@@ -344,8 +344,8 @@
 */
 Word32 pow2_xy(Word32 x, Word32 y)
 {
-  Word32 iPart;
-  Word32 fPart;
+  UWord32 iPart;
+  UWord32 fPart;
   Word32 res;
   Word32 tmp, tmp2;
   Word32 shift, shift2;
diff --git a/media/libstagefright/codecs/aacenc/src/aacenc.c b/media/libstagefright/codecs/aacenc/src/aacenc.c
index ad2f29a..d1c8621 100644
--- a/media/libstagefright/codecs/aacenc/src/aacenc.c
+++ b/media/libstagefright/codecs/aacenc/src/aacenc.c
@@ -357,9 +357,9 @@
 		if(config.sampleRate%8000 == 0)
 			tmp =480;
 		/* check the bitrate */
-		if(config.bitRate!=0 && (config.bitRate/config.nChannelsOut < 4000) ||
+		if(config.bitRate!=0 && ((config.bitRate/config.nChannelsOut < 4000) ||
            (config.bitRate/config.nChannelsOut > 160000) ||
-		   (config.bitRate > config.sampleRate*6*config.nChannelsOut))
+		   (config.bitRate > config.sampleRate*6*config.nChannelsOut)))
 		{
 			config.bitRate = 640*config.sampleRate/tmp*config.nChannelsOut;
 
diff --git a/media/libstagefright/codecs/aacenc/src/adj_thr.c b/media/libstagefright/codecs/aacenc/src/adj_thr.c
index 07b33b7..ccfe883 100644
--- a/media/libstagefright/codecs/aacenc/src/adj_thr.c
+++ b/media/libstagefright/codecs/aacenc/src/adj_thr.c
@@ -20,13 +20,16 @@
 
 *******************************************************************************/
 
+/* Include system headers before local headers - the local headers
+ * redefine __inline, which can mess up definitions in libc headers if
+ * they happen to use __inline. */
+#include <string.h>
 #include "basic_op.h"
 #include "oper_32b.h"
 #include "adj_thr_data.h"
 #include "adj_thr.h"
 #include "qc_data.h"
 #include "line_pe.h"
-#include <string.h>
 
 
 #define  minSnrLimit    0x6666 /* 1 dB */
diff --git a/media/libstagefright/codecs/avc/common/src/deblock.cpp b/media/libstagefright/codecs/avc/common/src/deblock.cpp
index 5ed4c82..de2d2b63 100644
--- a/media/libstagefright/codecs/avc/common/src/deblock.cpp
+++ b/media/libstagefright/codecs/avc/common/src/deblock.cpp
@@ -294,7 +294,8 @@
     int     filterLeftMbEdgeFlag = (mb_x != 0);
     int     filterTopMbEdgeFlag  = (mb_y != 0);
     int     pitch = video->currPic->pitch;
-    int     indexA, indexB, tmp;
+    int     indexA, indexB;
+    int     *tmp;
     int     Alpha, Beta, Alpha_c, Beta_c;
     int     mbNum = mb_y * video->PicWidthInMbs + mb_x;
     int     *clipTable, *clipTable_c, *qp_clip_tab;
@@ -386,7 +387,7 @@
     /* Save Alpha,  Beta and clipTable for future use, with the obselete variables filterLeftMbEdgeFlag, mbNum amd tmp */
     filterLeftMbEdgeFlag = Alpha;
     mbNum = Beta;
-    tmp = (int)clipTable;
+    tmp = clipTable;
 
     indexA = MbQ->QPc + video->FilterOffsetA;
     indexB = MbQ->QPc + video->FilterOffsetB;
@@ -486,7 +487,7 @@
     /* Note that Alpha_c, Beta_c and clipTable_c for chroma is already calculated */
     Alpha = filterLeftMbEdgeFlag;
     Beta = mbNum;
-    clipTable = (int *)tmp;
+    clipTable = tmp;
 
     GetStrength_HorizontalEdges(Strength + 4, MbQ); // Strength for 4 blks in 1 stripe, 0 => vertical edge
 
diff --git a/media/libstagefright/codecs/avc/enc/src/avcenc_api.cpp b/media/libstagefright/codecs/avc/enc/src/avcenc_api.cpp
index d39885d..6d43142 100644
--- a/media/libstagefright/codecs/avc/enc/src/avcenc_api.cpp
+++ b/media/libstagefright/codecs/avc/enc/src/avcenc_api.cpp
@@ -573,7 +573,7 @@
     recon->pitch = currFS->frame.pitch;
     recon->disp_order = currFS->PicOrderCnt;
     recon->coding_order = currFS->FrameNum;
-    recon->id = (uint32) currFS->base_dpb; /* use the pointer as the id */
+    recon->id = (intptr_t) currFS->base_dpb; /* use the pointer as the id */
 
     currFS->IsOutputted |= 1;
 
diff --git a/media/libstagefright/codecs/avc/enc/src/motion_comp.cpp b/media/libstagefright/codecs/avc/enc/src/motion_comp.cpp
index ac62d78..a390f88 100644
--- a/media/libstagefright/codecs/avc/enc/src/motion_comp.cpp
+++ b/media/libstagefright/codecs/avc/enc/src/motion_comp.cpp
@@ -198,7 +198,7 @@
     out_offset = 24 - blkwidth;
 
     //switch(x_pos&0x3){
-    switch (((uint32)ref)&0x3)
+    switch (((intptr_t)ref)&0x3)
     {
         case 1:
             offset =  picpitch - blkwidth - 3;
@@ -268,9 +268,9 @@
 void eHorzInterp1MC(uint8 *in, int inpitch, uint8 *out, int outpitch,
                     int blkwidth, int blkheight, int dx)
 {
-    uint8 *p_ref;
+    uint8 *p_ref, *tmp;
     uint32 *p_cur;
-    uint32 tmp, pkres;
+    uint32 pkres;
     int result, curr_offset, ref_offset;
     int j;
     int32 r0, r1, r2, r3, r4, r5;
@@ -288,14 +288,14 @@
         r13 = 0;
         for (j = blkheight; j > 0; j--)
         {
-            tmp = (uint32)(p_ref + blkwidth);
+            tmp = p_ref + blkwidth;
             r0 = p_ref[0];
             r1 = p_ref[2];
             r0 |= (r1 << 16);           /* 0,c,0,a */
             r1 = p_ref[1];
             r2 = p_ref[3];
             r1 |= (r2 << 16);           /* 0,d,0,b */
-            while ((uint32)p_ref < tmp)
+            while (p_ref < tmp)
             {
                 r2 = *(p_ref += 4); /* move pointer to e */
                 r3 = p_ref[2];
@@ -360,8 +360,8 @@
                 p_ref -= (ref_offset + blkwidth);   /* input */
                 p_cur -= (outpitch >> 2);
 
-                tmp = (uint32)(p_ref + blkwidth);
-                for (; (uint32)p_ref < tmp;)
+                tmp = p_ref + blkwidth;
+                for (; p_ref < tmp;)
                 {
 
                     r0 = *p_ref++;
@@ -434,14 +434,14 @@
         r13 = 0;
         for (j = blkheight; j > 0; j--)
         {
-            tmp = (uint32)(p_ref + blkwidth);
+            tmp = p_ref + blkwidth;
             r0 = p_ref[0];
             r1 = p_ref[2];
             r0 |= (r1 << 16);           /* 0,c,0,a */
             r1 = p_ref[1];
             r2 = p_ref[3];
             r1 |= (r2 << 16);           /* 0,d,0,b */
-            while ((uint32)p_ref < tmp)
+            while (p_ref < tmp)
             {
                 r2 = *(p_ref += 4); /* move pointer to e */
                 r3 = p_ref[2];
@@ -494,8 +494,8 @@
                 p_ref -= (ref_offset + blkwidth);   /* input */
                 p_cur -= (outpitch >> 2);
 
-                tmp = (uint32)(p_ref + blkwidth);
-                for (; (uint32)p_ref < tmp;)
+                tmp = p_ref + blkwidth;
+                for (; p_ref < tmp;)
                 {
 
                     r0 = *p_ref++;
@@ -558,9 +558,9 @@
 void eHorzInterp2MC(int *in, int inpitch, uint8 *out, int outpitch,
                     int blkwidth, int blkheight, int dx)
 {
-    int *p_ref;
+    int *p_ref, *tmp;
     uint32 *p_cur;
-    uint32 tmp, pkres;
+    uint32 pkres;
     int result, result2, curr_offset, ref_offset;
     int j, r0, r1, r2, r3, r4, r5;
 
@@ -575,8 +575,8 @@
 
         for (j = blkheight; j > 0 ; j--)
         {
-            tmp = (uint32)(p_ref + blkwidth);
-            for (; (uint32)p_ref < tmp;)
+            tmp = p_ref + blkwidth;
+            for (; p_ref < tmp;)
             {
 
                 r0 = p_ref[-2];
@@ -654,8 +654,8 @@
     {
         for (j = blkheight; j > 0 ; j--)
         {
-            tmp = (uint32)(p_ref + blkwidth);
-            for (; (uint32)p_ref < tmp;)
+            tmp = p_ref + blkwidth;
+            for (; p_ref < tmp;)
             {
 
                 r0 = p_ref[-2];
@@ -717,9 +717,8 @@
 void eHorzInterp3MC(uint8 *in, int inpitch, int *out, int outpitch,
                     int blkwidth, int blkheight)
 {
-    uint8 *p_ref;
+    uint8 *p_ref, *tmp;
     int   *p_cur;
-    uint32 tmp;
     int result, curr_offset, ref_offset;
     int j, r0, r1, r2, r3, r4, r5;
 
@@ -730,8 +729,8 @@
 
     for (j = blkheight; j > 0 ; j--)
     {
-        tmp = (uint32)(p_ref + blkwidth);
-        for (; (uint32)p_ref < tmp;)
+        tmp = p_ref + blkwidth;
+        for (; p_ref < tmp;)
         {
 
             r0 = p_ref[-2];
@@ -782,15 +781,14 @@
 void eVertInterp1MC(uint8 *in, int inpitch, uint8 *out, int outpitch,
                     int blkwidth, int blkheight, int dy)
 {
-    uint8 *p_cur, *p_ref;
-    uint32 tmp;
+    uint8 *p_cur, *p_ref, *tmp;
     int result, curr_offset, ref_offset;
     int j, i;
     int32 r0, r1, r2, r3, r4, r5, r6, r7, r8, r13;
     uint8  tmp_in[24][24];
 
     /* not word-aligned */
-    if (((uint32)in)&0x3)
+    if (((intptr_t)in)&0x3)
     {
         eCreateAlign(in, inpitch, -2, &tmp_in[0][0], blkwidth, blkheight + 5);
         in = &tmp_in[2][0];
@@ -811,8 +809,8 @@
             r13 = 0;
             p_ref = in;
             p_cur -= outpitch;  /* compensate for the first offset */
-            tmp = (uint32)(p_ref + ref_offset); /* limit */
-            while ((uint32)p_ref < tmp)  /* the loop un-rolled  */
+            tmp = p_ref + ref_offset; /* limit */
+            while (p_ref < tmp)  /* the loop un-rolled  */
             {
                 r0 = *((uint32*)(p_ref - (inpitch << 1))); /* load 4 bytes */
                 p_ref += inpitch;
@@ -885,8 +883,8 @@
                     p_ref = in + i;
                     p_cur -= outpitch;  /* compensate for the first offset */
 
-                    tmp = (uint32)(p_ref + ref_offset); /* limit */
-                    while ((uint32)p_ref < tmp)
+                    tmp = p_ref + ref_offset; /* limit */
+                    while (p_ref < tmp)
                     {                           /* loop un-rolled */
                         r0 = *(p_ref - (inpitch << 1));
                         r1 = *(p_ref - inpitch);
@@ -959,8 +957,8 @@
             r13 = 0;
             p_ref = in;
             p_cur -= outpitch;  /* compensate for the first offset */
-            tmp = (uint32)(p_ref + ref_offset); /* limit */
-            while ((uint32)p_ref < tmp)  /* the loop un-rolled  */
+            tmp = p_ref + ref_offset; /* limit */
+            while (p_ref < tmp)  /* the loop un-rolled  */
             {
                 r0 = *((uint32*)(p_ref - (inpitch << 1))); /* load 4 bytes */
                 p_ref += inpitch;
@@ -1023,8 +1021,8 @@
                 {
                     p_ref = in + i;
                     p_cur -= outpitch;  /* compensate for the first offset */
-                    tmp = (uint32)(p_ref + ref_offset); /* limit */
-                    while ((uint32)p_ref < tmp)
+                    tmp = p_ref + ref_offset; /* limit */
+                    while (p_ref < tmp)
                     {                           /* loop un-rolled */
                         r0 = *(p_ref - (inpitch << 1));
                         r1 = *(p_ref - inpitch);
@@ -1086,8 +1084,7 @@
                     int blkwidth, int blkheight)
 {
     int *p_cur;
-    uint8 *p_ref;
-    uint32 tmp;
+    uint8 *p_ref, *tmp;
     int result, curr_offset, ref_offset;
     int j, r0, r1, r2, r3, r4, r5;
 
@@ -1100,8 +1097,8 @@
         p_cur -= outpitch; /* compensate for the first offset */
         p_ref = in++;
 
-        tmp = (uint32)(p_ref + ref_offset); /* limit */
-        while ((uint32)p_ref < tmp)
+        tmp = p_ref + ref_offset; /* limit */
+        while (p_ref < tmp)
         {                           /* loop un-rolled */
             r0 = *(p_ref - (inpitch << 1));
             r1 = *(p_ref - inpitch);
@@ -1152,8 +1149,7 @@
                     int blkwidth, int blkheight, int dy)
 {
     uint8 *p_cur;
-    int *p_ref;
-    uint32 tmp;
+    int *p_ref, *tmp;
     int result, result2, curr_offset, ref_offset;
     int j, r0, r1, r2, r3, r4, r5;
 
@@ -1170,8 +1166,8 @@
             p_cur -= outpitch; /* compensate for the first offset */
             p_ref = in++;
 
-            tmp = (uint32)(p_ref + ref_offset); /* limit */
-            while ((uint32)p_ref < tmp)
+            tmp = p_ref + ref_offset; /* limit */
+            while (p_ref < tmp)
             {                           /* loop un-rolled */
                 r0 = *(p_ref - (inpitch << 1));
                 r1 = *(p_ref - inpitch);
@@ -1250,8 +1246,8 @@
             p_cur -= outpitch; /* compensate for the first offset */
             p_ref = in++;
 
-            tmp = (uint32)(p_ref + ref_offset); /* limit */
-            while ((uint32)p_ref < tmp)
+            tmp = p_ref + ref_offset; /* limit */
+            while (p_ref < tmp)
             {                           /* loop un-rolled */
                 r0 = *(p_ref - (inpitch << 1));
                 r1 = *(p_ref - inpitch);
@@ -1313,11 +1309,11 @@
 {
     int j, i;
     int result;
-    uint8 *p_cur, *p_ref, *p_tmp8;
+    uint8 *p_cur, *p_ref, *p_tmp8, *tmp;
     int curr_offset, ref_offset;
     uint8 tmp_res[24][24], tmp_in[24][24];
     uint32 *p_tmp;
-    uint32 tmp, pkres, tmp_result;
+    uint32 pkres, tmp_result;
     int32 r0, r1, r2, r3, r4, r5;
     int32 r6, r7, r8, r9, r10, r13;
 
@@ -1337,7 +1333,7 @@
     for (j = blkheight; j > 0; j--)
     {
         r13 = 0;
-        tmp = (uint32)(p_ref + blkwidth);
+        tmp = p_ref + blkwidth;
 
         //r0 = *((uint32*)p_ref);   /* d,c,b,a */
         //r1 = (r0>>8)&0xFF00FF;    /* 0,d,0,b */
@@ -1350,7 +1346,7 @@
         r2 = p_ref[3];
         r1 |= (r2 << 16);           /* 0,d,0,b */
 
-        while ((uint32)p_ref < tmp)
+        while (p_ref < tmp)
         {
             //r2 = *((uint32*)(p_ref+=4));/* h,g,f,e */
             //r3 = (r2>>8)&0xFF00FF;  /* 0,h,0,f */
@@ -1406,8 +1402,8 @@
             /* move back to the beginning of the line */
             p_ref -= (ref_offset + blkwidth);   /* input */
             p_tmp -= 6; /* intermediate output */
-            tmp = (uint32)(p_ref + blkwidth);
-            while ((uint32)p_ref < tmp)
+            tmp = p_ref + blkwidth;
+            while (p_ref < tmp)
             {
                 r0 = *p_ref++;
                 r1 = *p_ref++;
@@ -1465,7 +1461,7 @@
 
     /*  perform vertical interpolation */
     /* not word-aligned */
-    if (((uint32)in2)&0x3)
+    if (((intptr_t)in2)&0x3)
     {
         eCreateAlign(in2, inpitch, -2, &tmp_in[0][0], blkwidth, blkheight + 5);
         in2 = &tmp_in[2][0];
@@ -1485,8 +1481,8 @@
         p_tmp8 = &(tmp_res[0][j]); /* intermediate result */
         p_tmp8 -= 24;  /* compensate for the first offset */
         p_cur -= outpitch;  /* compensate for the first offset */
-        tmp = (uint32)(p_ref + pkres); /* limit */
-        while ((uint32)p_ref < tmp)  /* the loop un-rolled  */
+        tmp = p_ref + pkres; /* limit */
+        while (p_ref < tmp)  /* the loop un-rolled  */
         {
             /* Read 1 byte at a time is too slow, too many read and pack ops, need to call CreateAlign */
             /*p_ref8 = p_ref-(inpitch<<1);          r0 = p_ref8[0];         r1 = p_ref8[2];
@@ -1579,8 +1575,8 @@
                 p_tmp8 = &(tmp_res[0][j+i]); /* intermediate result */
                 p_tmp8 -= 24;  /* compensate for the first offset */
                 p_cur -= outpitch;  /* compensate for the first offset */
-                tmp = (uint32)(p_ref + pkres); /* limit */
-                while ((uint32)p_ref < tmp)  /* the loop un-rolled  */
+                tmp = p_ref + pkres; /* limit */
+                while (p_ref < tmp)  /* the loop un-rolled  */
                 {
                     r0 = *(p_ref - (inpitch << 1));
                     r1 = *(p_ref - inpitch);
@@ -1659,7 +1655,7 @@
     uint32 temp;
     uint8 byte;
 
-    if (((uint32)in)&3)
+    if (((intptr_t)in)&3)
     {
         for (j = blkheight; j > 0; j--)
         {
@@ -1720,7 +1716,7 @@
         else start = ref + x_pos;
 
         /* word-align start */
-        offset = (uint32)start & 0x3;
+        offset = (intptr_t)start & 0x3;
         if (offset) start -= offset;
 
         word1 = *((uint32*)start);
@@ -1746,7 +1742,7 @@
         else    start = ref + picpitch * (picheight - 1) + x_pos;
 
         /* word-align start */
-        offset = (uint32)start & 0x3;
+        offset = (intptr_t)start & 0x3;
         if (offset) start -= offset;
 
         word1 = *((uint32*)start);
@@ -2121,7 +2117,7 @@
     uint16 temp;
     uint8 byte;
 
-    if (((uint32)pRef)&1)
+    if (((intptr_t)pRef)&1)
     {
         for (j = blkheight; j > 0; j--)
         {
diff --git a/media/libstagefright/codecs/avc/enc/src/sad_inline.h b/media/libstagefright/codecs/avc/enc/src/sad_inline.h
index f39794f..3f18483 100644
--- a/media/libstagefright/codecs/avc/enc/src/sad_inline.h
+++ b/media/libstagefright/codecs/avc/enc/src/sad_inline.h
@@ -80,7 +80,7 @@
 
         x9 = 0x80808080; /* const. */
 
-        x8 = (uint32)ref & 0x3;
+        x8 = (intptr_t)ref & 0x3;
         if (x8 == 3)
             goto SadMBOffset3;
         if (x8 == 2)
diff --git a/media/libstagefright/codecs/common/Android.mk b/media/libstagefright/codecs/common/Android.mk
index af8795a..77fe934 100644
--- a/media/libstagefright/codecs/common/Android.mk
+++ b/media/libstagefright/codecs/common/Android.mk
@@ -16,17 +16,6 @@
 
 LOCAL_CFLAGS := $(VO_CFLAGS)
 
-ifeq ($(VOTT), v5)
-LOCAL_CFLAGS += -DARM -DASM_OPT
-LOCAL_C_INCLUDES += $(LOCAL_PATH)/src/asm/ARMV5E
-endif
-
-ifeq ($(VOTT), v7)
-LOCAL_CFLAGS += -DARM -DARMV7 -DASM_OPT
-LOCAL_C_INCLUDES += $(LOCAL_PATH)/src/asm/ARMV5E
-LOCAL_C_INCLUDES += $(LOCAL_PATH)/src/asm/ARMV7
-endif
-
 include $(BUILD_SHARED_LIBRARY)
 
 
diff --git a/media/libstagefright/matroska/MatroskaExtractor.cpp b/media/libstagefright/matroska/MatroskaExtractor.cpp
index 4fbf47e..9ba0e82 100644
--- a/media/libstagefright/matroska/MatroskaExtractor.cpp
+++ b/media/libstagefright/matroska/MatroskaExtractor.cpp
@@ -768,12 +768,12 @@
         }
 
         BlockIterator iter(this, info->mTrackNum);
-        int32_t i = 0;
+        int32_t j = 0;
         int64_t thumbnailTimeUs = 0;
         size_t maxBlockSize = 0;
-        while (!iter.eos() && i < 20) {
+        while (!iter.eos() && j < 20) {
             if (iter.block()->IsKey()) {
-                ++i;
+                ++j;
 
                 size_t blockSize = 0;
                 for (int i = 0; i < iter.block()->GetFrameCount(); ++i) {
diff --git a/packages/SettingsProvider/src/com/android/providers/settings/DatabaseHelper.java b/packages/SettingsProvider/src/com/android/providers/settings/DatabaseHelper.java
index a5e3483..56fe106 100644
--- a/packages/SettingsProvider/src/com/android/providers/settings/DatabaseHelper.java
+++ b/packages/SettingsProvider/src/com/android/providers/settings/DatabaseHelper.java
@@ -1460,7 +1460,13 @@
                     "true".equalsIgnoreCase(
                             SystemProperties.get("ro.com.android.dataroaming",
                                     "false")) ? 1 : 0);
-    
+
+            // Mobile Data default, based on build
+            loadSetting(stmt, Settings.Secure.MOBILE_DATA,
+                    "true".equalsIgnoreCase(
+                            SystemProperties.get("ro.com.android.mobiledata",
+                                    "true")) ? 1 : 0);
+
             loadBooleanSetting(stmt, Settings.Secure.INSTALL_NON_MARKET_APPS,
                     R.bool.def_install_non_market_apps);
     
diff --git a/packages/SystemUI/src/com/android/systemui/ImageWallpaper.java b/packages/SystemUI/src/com/android/systemui/ImageWallpaper.java
index 724679f..f9debce 100644
--- a/packages/SystemUI/src/com/android/systemui/ImageWallpaper.java
+++ b/packages/SystemUI/src/com/android/systemui/ImageWallpaper.java
@@ -282,6 +282,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();
@@ -303,13 +310,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 f1fe43b..2864d22 100644
--- a/policy/src/com/android/internal/policy/impl/PhoneWindow.java
+++ b/policy/src/com/android/internal/policy/impl/PhoneWindow.java
@@ -1653,7 +1653,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/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
index 0de76a7..7923709 100755
--- a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
+++ b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
@@ -1083,9 +1083,9 @@
         try {
             int sw = mWindowManager.getSwitchState(SW_LID);
             if (sw > 0) {
-                mLidOpen = LID_OPEN;
-            } else if (sw == 0) {
                 mLidOpen = LID_CLOSED;
+            } else if (sw == 0) {
+                mLidOpen = LID_OPEN;
             } else {
                 mLidOpen = LID_ABSENT;
             }
diff --git a/services/input/InputDispatcher.cpp b/services/input/InputDispatcher.cpp
index 0bef0db..b9da093 100644
--- a/services/input/InputDispatcher.cpp
+++ b/services/input/InputDispatcher.cpp
@@ -1390,28 +1390,35 @@
             // New window supports splitting.
             isSplit = true;
         } else if (isSplit) {
-            // New window does not support splitting but we have already split events.
-            // Assign the pointer to the first foreground window we find.
-            // (May be NULL which is why we put this code block before the next check.)
-            newTouchedWindowHandle = mTempTouchState.getFirstForegroundWindowHandle();
+            // Ignore the new window.
+            newTouchedWindowHandle = NULL;
         }
 
-        // If we did not find a touched window then fail.
+        // Handle the case where we did not find a window.
         if (newTouchedWindowHandle == NULL) {
-            if (mFocusedApplicationHandle != NULL) {
+            // Try to assign the pointer to the first foreground window we find, if there is one.
+            newTouchedWindowHandle = mTempTouchState.getFirstForegroundWindowHandle();
+            if (newTouchedWindowHandle == NULL) {
+                // There is no touched window.  If this is an initial down event
+                // then wait for a window to appear that will handle the touch.  This is
+                // to ensure that we report an ANR in the case where an application has started
+                // but not yet put up a window and the user is starting to get impatient.
+                if (maskedAction == AMOTION_EVENT_ACTION_DOWN
+                        && mFocusedApplicationHandle != NULL) {
 #if DEBUG_FOCUS
-                ALOGD("Waiting because there is no touched window but there is a "
-                        "focused application that may eventually add a new window: %s.",
-                        getApplicationWindowLabelLocked(mFocusedApplicationHandle, NULL).string());
+                    ALOGD("Waiting because there is no touched window but there is a "
+                            "focused application that may eventually add a new window: %s.",
+                            getApplicationWindowLabelLocked(
+                                    mFocusedApplicationHandle, NULL).string());
 #endif
-                injectionResult = handleTargetsNotReadyLocked(currentTime, entry,
-                        mFocusedApplicationHandle, NULL, nextWakeupTime);
-                goto Unresponsive;
+                    injectionResult = handleTargetsNotReadyLocked(currentTime, entry,
+                            mFocusedApplicationHandle, NULL, nextWakeupTime);
+                    goto Unresponsive;
+                }
+                ALOGI("Dropping event because there is no touched window.");
+                injectionResult = INPUT_EVENT_INJECTION_FAILED;
+                goto Failed;
             }
-
-            ALOGI("Dropping event because there is no touched window or focused application.");
-            injectionResult = INPUT_EVENT_INJECTION_FAILED;
-            goto Failed;
         }
 
         // Set target flags.
diff --git a/services/input/InputReader.cpp b/services/input/InputReader.cpp
index 8324d95..91e375d 100644
--- a/services/input/InputReader.cpp
+++ b/services/input/InputReader.cpp
@@ -644,9 +644,13 @@
         for (size_t i = 0; i < numDevices; i++) {
             InputDevice* device = mDevices.valueAt(i);
             if (! device->isIgnored() && sourcesMatchMask(device->getSources(), sourceMask)) {
-                result = (device->*getStateFunc)(sourceMask, code);
-                if (result >= AKEY_STATE_DOWN) {
-                    return result;
+                // If any device reports AKEY_STATE_DOWN or AKEY_STATE_VIRTUAL, return that
+                // value.  Otherwise, return AKEY_STATE_UP as long as one device reports it.
+                int32_t currentResult = (device->*getStateFunc)(sourceMask, code);
+                if (currentResult >= AKEY_STATE_DOWN) {
+                    return currentResult;
+                } else if (currentResult == AKEY_STATE_UP) {
+                    result = currentResult;
                 }
             }
         }
@@ -1000,9 +1004,13 @@
     for (size_t i = 0; i < numMappers; i++) {
         InputMapper* mapper = mMappers[i];
         if (sourcesMatchMask(mapper->getSources(), sourceMask)) {
-            result = (mapper->*getStateFunc)(sourceMask, code);
-            if (result >= AKEY_STATE_DOWN) {
-                return result;
+            // If any mapper reports AKEY_STATE_DOWN or AKEY_STATE_VIRTUAL, return that
+            // value.  Otherwise, return AKEY_STATE_UP as long as one mapper reports it.
+            int32_t currentResult = (mapper->*getStateFunc)(sourceMask, code);
+            if (currentResult >= AKEY_STATE_DOWN) {
+                return currentResult;
+            } else if (currentResult == AKEY_STATE_UP) {
+                result = currentResult;
             }
         }
     }
@@ -2874,7 +2882,7 @@
             mOrientedRanges.distance.min =
                     mRawPointerAxes.distance.minValue * mDistanceScale;
             mOrientedRanges.distance.max =
-                    mRawPointerAxes.distance.minValue * mDistanceScale;
+                    mRawPointerAxes.distance.maxValue * mDistanceScale;
             mOrientedRanges.distance.flat = 0;
             mOrientedRanges.distance.fuzz =
                     mRawPointerAxes.distance.fuzz * mDistanceScale;
diff --git a/services/java/com/android/server/DevicePolicyManagerService.java b/services/java/com/android/server/DevicePolicyManagerService.java
index d8e3d59..c7158aa 100644
--- a/services/java/com/android/server/DevicePolicyManagerService.java
+++ b/services/java/com/android/server/DevicePolicyManagerService.java
@@ -1684,6 +1684,7 @@
         // Note: we can only do the wipe via ExternalStorageFormatter if the volume is not emulated.
         if ((forceExtWipe || wipeExtRequested) && !Environment.isExternalStorageEmulated()) {
             Intent intent = new Intent(ExternalStorageFormatter.FORMAT_AND_FACTORY_RESET);
+            intent.putExtra(ExternalStorageFormatter.EXTRA_ALWAYS_RESET, true);
             intent.setComponent(ExternalStorageFormatter.COMPONENT_NAME);
             mWakeLock.acquire(10000);
             mContext.startService(intent);
diff --git a/services/java/com/android/server/MountService.java b/services/java/com/android/server/MountService.java
index 5425813..540dda4 100644
--- a/services/java/com/android/server/MountService.java
+++ b/services/java/com/android/server/MountService.java
@@ -1218,6 +1218,7 @@
             for(MountServiceBinderListener bl : mListeners) {
                 if (bl.mListener == listener) {
                     mListeners.remove(mListeners.indexOf(bl));
+                    listener.asBinder().unlinkToDeath(bl, 0);
                     return;
                 }
             }
diff --git a/services/java/com/android/server/PowerManagerService.java b/services/java/com/android/server/PowerManagerService.java
index 2a0d2a0..5848cc9 100644
--- a/services/java/com/android/server/PowerManagerService.java
+++ b/services/java/com/android/server/PowerManagerService.java
@@ -1103,6 +1103,8 @@
                         ? "SCREEN_BRIGHT_BIT " : "")
                 + (((state & SCREEN_ON_BIT) != 0)
                         ? "SCREEN_ON_BIT " : "")
+                + (((state & BUTTON_BRIGHT_BIT) != 0)
+                        ? "BUTTON_BRIGHT_BIT " : "")
                 + (((state & BATTERY_LOW_BIT) != 0)
                         ? "BATTERY_LOW_BIT " : "");
     }
diff --git a/services/java/com/android/server/SystemServer.java b/services/java/com/android/server/SystemServer.java
index 3ae62ad..ce133f0 100644
--- a/services/java/com/android/server/SystemServer.java
+++ b/services/java/com/android/server/SystemServer.java
@@ -79,7 +79,7 @@
         EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_SYSTEM_RUN,
             SystemClock.uptimeMillis());
 
-        Looper.prepare();
+        Looper.prepareMainLooper();
 
         android.os.Process.setThreadPriority(
                 android.os.Process.THREAD_PRIORITY_FOREGROUND);
diff --git a/services/java/com/android/server/WallpaperManagerService.java b/services/java/com/android/server/WallpaperManagerService.java
index 4925a4e..cca6536 100644
--- a/services/java/com/android/server/WallpaperManagerService.java
+++ b/services/java/com/android/server/WallpaperManagerService.java
@@ -169,6 +169,7 @@
     WallpaperConnection mWallpaperConnection;
     long mLastDiedTime;
     boolean mWallpaperUpdating;
+    boolean mDesiredDimensionChanging;
     
     class WallpaperConnection extends IWallpaperConnection.Stub
             implements ServiceConnection {
@@ -213,6 +214,13 @@
         
         public void attachEngine(IWallpaperEngine engine) {
             mEngine = engine;
+             if (engine != null && mDesiredDimensionChanging) {
+                 try {
+                     engine.setDesiredSize(mWidth, mHeight);
+                     mDesiredDimensionChanging = false;
+                 } catch (RemoteException e) {
+                 }
+             }
         }
         
         public ParcelFileDescriptor setWallpaper(String name) {
@@ -395,6 +403,7 @@
 
         synchronized (mLock) {
             if (width != mWidth || height != mHeight) {
+                boolean desiredDimensionPropagated = false;
                 mWidth = width;
                 mHeight = height;
                 saveSettingsLocked();
@@ -403,11 +412,15 @@
                         try {
                             mWallpaperConnection.mEngine.setDesiredSize(
                                     width, height);
+                            desiredDimensionPropagated = true;
                         } catch (RemoteException e) {
                         }
                         notifyCallbacksLocked();
                     }
                 }
+                if (!desiredDimensionPropagated) {
+                    mDesiredDimensionChanging = true;
+                }
             }
         }
     }
diff --git a/services/java/com/android/server/am/ActivityManagerService.java b/services/java/com/android/server/am/ActivityManagerService.java
index 5044554..0a4d19f 100644
--- a/services/java/com/android/server/am/ActivityManagerService.java
+++ b/services/java/com/android/server/am/ActivityManagerService.java
@@ -1757,7 +1757,7 @@
                 if (cr.binding != null && cr.binding.service != null
                         && cr.binding.service.app != null
                         && cr.binding.service.app.lruSeq != mLruSeq) {
-                    updateLruProcessInternalLocked(cr.binding.service.app, oomAdj,
+                    updateLruProcessInternalLocked(cr.binding.service.app, false,
                             updateActivityTime, i+1);
                 }
             }
@@ -1765,7 +1765,7 @@
         if (app.conProviders.size() > 0) {
             for (ContentProviderRecord cpr : app.conProviders.keySet()) {
                 if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq) {
-                    updateLruProcessInternalLocked(cpr.proc, oomAdj,
+                    updateLruProcessInternalLocked(cpr.proc, false,
                             updateActivityTime, i+1);
                 }
             }
diff --git a/services/java/com/android/server/am/ActivityStack.java b/services/java/com/android/server/am/ActivityStack.java
old mode 100644
new mode 100755
index 351dbb8..86d3a1a
--- a/services/java/com/android/server/am/ActivityStack.java
+++ b/services/java/com/android/server/am/ActivityStack.java
@@ -1314,7 +1314,10 @@
         // If we are sleeping, and there is no resumed activity, and the top
         // activity is paused, well that is the state we want.
         if ((mService.mSleeping || mService.mShuttingDown)
-                && mLastPausedActivity == next && next.state == ActivityState.PAUSED) {
+                && mLastPausedActivity == next
+                && (next.state == ActivityState.PAUSED
+                    || next.state == ActivityState.STOPPED
+                    || next.state == ActivityState.STOPPING)) {
             // Make sure we have executed any pending transitions, since there
             // should be nothing left to do at this point.
             mService.mWindowManager.executeAppTransition();
diff --git a/services/java/com/android/server/am/UriPermission.java b/services/java/com/android/server/am/UriPermission.java
index e3347cb..c5b1c7b 100644
--- a/services/java/com/android/server/am/UriPermission.java
+++ b/services/java/com/android/server/am/UriPermission.java
@@ -59,11 +59,11 @@
         if ((modeFlagsToClear&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
             globalModeFlags &= ~Intent.FLAG_GRANT_WRITE_URI_PERMISSION;
             modeFlags &= ~Intent.FLAG_GRANT_WRITE_URI_PERMISSION;
-            if (readOwners.size() > 0) {
+            if (writeOwners.size() > 0) {
                 for (UriPermissionOwner r : writeOwners) {
                     r.removeWritePermission(this);
                 }
-                readOwners.clear();
+                writeOwners.clear();
             }
         }
     }
diff --git a/services/java/com/android/server/pm/PackageManagerService.java b/services/java/com/android/server/pm/PackageManagerService.java
index 6b61c47..938d93a 100644
--- a/services/java/com/android/server/pm/PackageManagerService.java
+++ b/services/java/com/android/server/pm/PackageManagerService.java
@@ -2573,7 +2573,7 @@
                     }
                 }
 
-                if (pi != null && !list.append(pi)) {
+                if (pi != null && list.append(pi)) {
                     break;
                 }
             }
@@ -2620,7 +2620,7 @@
                     }
                 }
 
-                if (ai != null && !list.append(ai)) {
+                if (ai != null && list.append(ai)) {
                     break;
                 }
             }
diff --git a/services/java/com/android/server/pm/Settings.java b/services/java/com/android/server/pm/Settings.java
index 36442a0..f0f5414 100644
--- a/services/java/com/android/server/pm/Settings.java
+++ b/services/java/com/android/server/pm/Settings.java
@@ -971,7 +971,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:
@@ -2261,4 +2261,4 @@
         pw.println("Settings parse messages:");
         pw.print(mReadMessages.toString());
     }
-}
\ No newline at end of file
+}
diff --git a/services/java/com/android/server/pm/UserManager.java b/services/java/com/android/server/pm/UserManager.java
index 76fa5ab..d15e12c 100644
--- a/services/java/com/android/server/pm/UserManager.java
+++ b/services/java/com/android/server/pm/UserManager.java
@@ -136,6 +136,7 @@
                 }
             }
             updateUserIds();
+            fis.close();
         } catch (IOException ioe) {
             fallbackToSingleUser();
         } catch (XmlPullParserException pe) {
diff --git a/services/java/com/android/server/wm/WindowManagerService.java b/services/java/com/android/server/wm/WindowManagerService.java
old mode 100644
new mode 100755
index 3f72dec..c833919
--- a/services/java/com/android/server/wm/WindowManagerService.java
+++ b/services/java/com/android/server/wm/WindowManagerService.java
@@ -3359,17 +3359,7 @@
                 continue;
             }
 
-            if (!haveGroup) {
-                // We ignore any hidden applications on the top.
-                if (wtoken.hiddenRequested || wtoken.willBeHidden) {
-                    if (DEBUG_ORIENTATION) Slog.v(TAG, "Skipping " + wtoken
-                            + " -- hidden on top");
-                    continue;
-                }
-                haveGroup = true;
-                curGroup = wtoken.groupId;
-                lastOrientation = wtoken.requestedOrientation;
-            } else if (curGroup != wtoken.groupId) {
+            if (haveGroup == true && curGroup != wtoken.groupId) {
                 // If we have hit a new application group, and the bottom
                 // of the previous group didn't explicitly say to use
                 // the orientation behind it, and the last app was
@@ -3382,6 +3372,20 @@
                     return lastOrientation;
                 }
             }
+
+            // We ignore any hidden applications on the top.
+            if (wtoken.hiddenRequested || wtoken.willBeHidden) {
+                if (DEBUG_ORIENTATION) Slog.v(TAG, "Skipping " + wtoken
+                        + " -- hidden on top");
+                continue;
+            }
+
+            if (!haveGroup) {
+                haveGroup = true;
+                curGroup = wtoken.groupId;
+                lastOrientation = wtoken.requestedOrientation;
+            } 
+
             int or = wtoken.requestedOrientation;
             // If this application is fullscreen, and didn't explicitly say
             // to use the orientation behind it, then just take whatever
diff --git a/telephony/java/android/telephony/cdma/CdmaCellLocation.java b/telephony/java/android/telephony/cdma/CdmaCellLocation.java
index 84db830..6cfae6a 100644
--- a/telephony/java/android/telephony/cdma/CdmaCellLocation.java
+++ b/telephony/java/android/telephony/cdma/CdmaCellLocation.java
@@ -81,14 +81,26 @@
     }
 
     /**
-     * @return cdma base station latitude, Integer.MAX_VALUE if unknown
+     * Latitude is a decimal number as specified in 3GPP2 C.S0005-A v6.0.
+     * (http://www.3gpp2.org/public_html/specs/C.S0005-A_v6.0.pdf)
+     * It is represented in units of 0.25 seconds and ranges from -1296000
+     * to 1296000, both values inclusive (corresponding to a range of -90
+     * to +90 degrees). Integer.MAX_VALUE is considered invalid value.
+     *
+     * @return cdma base station latitude in units of 0.25 seconds, Integer.MAX_VALUE if unknown
      */
     public int getBaseStationLatitude() {
         return this.mBaseStationLatitude;
     }
 
     /**
-     * @return cdma base station longitude, Integer.MAX_VALUE if unknown
+     * Longitude is a decimal number as specified in 3GPP2 C.S0005-A v6.0.
+     * (http://www.3gpp2.org/public_html/specs/C.S0005-A_v6.0.pdf)
+     * It is represented in units of 0.25 seconds and ranges from -2592000
+     * to 2592000, both values inclusive (corresponding to a range of -180
+     * to +180 degrees). Integer.MAX_VALUE is considered invalid value.
+     *
+     * @return cdma base station longitude in units of 0.25 seconds, Integer.MAX_VALUE if unknown
      */
     public int getBaseStationLongitude() {
         return this.mBaseStationLongitude;
@@ -215,6 +227,22 @@
                 this.mNetworkId == -1);
     }
 
+    /**
+     * Converts latitude or longitude from 0.25 seconds (as defined in the
+     * 3GPP2 C.S0005-A v6.0 standard) to decimal degrees
+     *
+     * @param quartSec latitude or longitude in 0.25 seconds units
+     * @return latitude or longitude in decimal degrees units
+     * @throws IllegalArgumentException if value is less than -2592000,
+     *                                  greater than 2592000, or is not a number.
+     */
+    public static double convertQuartSecToDecDegrees(int quartSec) {
+        if(Double.isNaN(quartSec) || quartSec < -2592000 || quartSec > 2592000){
+            // Invalid value
+            throw new IllegalArgumentException("Invalid coordiante value:" + quartSec);
+        }
+        return ((double)quartSec) / (3600 * 4);
+    }
 
 }
 
diff --git a/telephony/java/com/android/internal/telephony/Connection.java b/telephony/java/com/android/internal/telephony/Connection.java
index 07f90cd..021602f 100644
--- a/telephony/java/com/android/internal/telephony/Connection.java
+++ b/telephony/java/com/android/internal/telephony/Connection.java
@@ -28,6 +28,10 @@
     public static int PRESENTATION_UNKNOWN = 3;    // no specified or unknown by network
     public static int PRESENTATION_PAYPHONE = 4;   // show pay phone info
 
+    //Caller Name Display
+    protected String cnapName;
+    protected int cnapNamePresentation  = PRESENTATION_ALLOWED;
+
     private static String LOG_TAG = "TelephonyConnection";
 
     public enum DisconnectCause {
@@ -84,11 +88,11 @@
     public abstract String getAddress();
 
     /**
-     * Gets CDMA CNAP name associated with connection.
+     * Gets CNAP name associated with connection.
      * @return cnap name or null if unavailable
      */
     public String getCnapName() {
-        return null;
+        return cnapName;
     }
 
     /**
@@ -100,12 +104,12 @@
     }
 
     /**
-     * Gets CDMA CNAP presentation associated with connection.
+     * Gets CNAP presentation associated with connection.
      * @return cnap name or null if unavailable
      */
 
     public int getCnapNamePresentation() {
-       return 0;
+       return cnapNamePresentation;
     };
 
     /**
diff --git a/telephony/java/com/android/internal/telephony/cat/CommandDetails.java b/telephony/java/com/android/internal/telephony/cat/CommandDetails.java
index e3f0798..bb875be 100644
--- a/telephony/java/com/android/internal/telephony/cat/CommandDetails.java
+++ b/telephony/java/com/android/internal/telephony/cat/CommandDetails.java
@@ -48,13 +48,14 @@
     }
 
     public CommandDetails(Parcel in) {
-        compRequired = true;
+        compRequired = in.readInt() != 0;
         commandNumber = in.readInt();
         typeOfCommand = in.readInt();
         commandQualifier = in.readInt();
     }
 
     public void writeToParcel(Parcel dest, int flags) {
+        dest.writeInt(compRequired ? 1 : 0);
         dest.writeInt(commandNumber);
         dest.writeInt(typeOfCommand);
         dest.writeInt(commandQualifier);
@@ -103,4 +104,4 @@
     ComprehensionTlvTag getTag() {
         return ComprehensionTlvTag.ITEM_ICON_ID_LIST;
     }
-}
\ No newline at end of file
+}
diff --git a/telephony/java/com/android/internal/telephony/cdma/CdmaConnection.java b/telephony/java/com/android/internal/telephony/cdma/CdmaConnection.java
index 8fb136e..e013d84 100755
--- a/telephony/java/com/android/internal/telephony/cdma/CdmaConnection.java
+++ b/telephony/java/com/android/internal/telephony/cdma/CdmaConnection.java
@@ -50,7 +50,6 @@
     String postDialString;      // outgoing calls only
     boolean isIncoming;
     boolean disconnected;
-    String cnapName;
     int index;          // index in CdmaCallTracker.connections[], -1 if unassigned
 
     /*
@@ -76,7 +75,6 @@
     DisconnectCause cause = DisconnectCause.NOT_DISCONNECTED;
     PostDialState postDialState = PostDialState.NOT_STARTED;
     int numberPresentation = Connection.PRESENTATION_ALLOWED;
-    int cnapNamePresentation  = Connection.PRESENTATION_ALLOWED;
 
 
     Handler h;
@@ -229,14 +227,6 @@
         return address;
     }
 
-    public String getCnapName() {
-        return cnapName;
-    }
-
-    public int getCnapNamePresentation() {
-        return cnapNamePresentation;
-    }
-
     public CdmaCall getCall() {
         return parent;
     }
diff --git a/telephony/java/com/android/internal/telephony/gsm/GSMPhone.java b/telephony/java/com/android/internal/telephony/gsm/GSMPhone.java
index e1f4c4b..5c95e7d 100644
--- a/telephony/java/com/android/internal/telephony/gsm/GSMPhone.java
+++ b/telephony/java/com/android/internal/telephony/gsm/GSMPhone.java
@@ -1240,7 +1240,7 @@
                 // If the radio shuts off or resets while one of these
                 // is pending, we need to clean up.
 
-                for (int i = 0, s = mPendingMMIs.size() ; i < s; i++) {
+                for (int i = mPendingMMIs.size() - 1; i >= 0; i--) {
                     if (mPendingMMIs.get(i).isPendingUSSD()) {
                         mPendingMMIs.get(i).onUssdFinishedError();
                     }
diff --git a/telephony/java/com/android/internal/telephony/gsm/GsmConnection.java b/telephony/java/com/android/internal/telephony/gsm/GsmConnection.java
index c1ad7b3..a879dac 100644
--- a/telephony/java/com/android/internal/telephony/gsm/GsmConnection.java
+++ b/telephony/java/com/android/internal/telephony/gsm/GsmConnection.java
@@ -26,6 +26,7 @@
 import android.util.Log;
 import android.telephony.PhoneNumberUtils;
 import android.telephony.ServiceState;
+import android.text.TextUtils;
 
 import com.android.internal.telephony.*;
 
@@ -125,6 +126,8 @@
 
         isIncoming = dc.isMT;
         createTime = System.currentTimeMillis();
+        cnapName = dc.name;
+        cnapNamePresentation = dc.namePresentation;
         numberPresentation = dc.numberPresentation;
         uusInfo = dc.uusInfo;
 
@@ -151,6 +154,9 @@
         index = -1;
 
         isIncoming = false;
+        cnapName = null;
+        cnapNamePresentation = Connection.PRESENTATION_ALLOWED;
+        numberPresentation = Connection.PRESENTATION_ALLOWED;
         createTime = System.currentTimeMillis();
 
         this.parent = parent;
@@ -437,6 +443,21 @@
             changed = true;
         }
 
+        // A null cnapName should be the same as ""
+        if (TextUtils.isEmpty(dc.name)) {
+            if (!TextUtils.isEmpty(cnapName)) {
+                changed = true;
+                cnapName = "";
+            }
+        } else if (!dc.name.equals(cnapName)) {
+            changed = true;
+            cnapName = dc.name;
+        }
+
+        if (Phone.DEBUG_PHONE) log("--dssds----"+cnapName);
+        cnapNamePresentation = dc.namePresentation;
+        numberPresentation = dc.numberPresentation;
+
         if (newParent != parent) {
             if (parent != null) {
                 parent.detach(this);
diff --git a/tools/aapt/AaptAssets.cpp b/tools/aapt/AaptAssets.cpp
index 3d6537a..22f495a 100644
--- a/tools/aapt/AaptAssets.cpp
+++ b/tools/aapt/AaptAssets.cpp
@@ -56,55 +56,93 @@
     return true;
 }
 
+// The default to use if no other ignore pattern is defined.
+const char * const gDefaultIgnoreAssets =
+    "!.svn:!.git:!.ds_store:!*.scc:.*:<dir>_*:!CVS:!thumbs.db:!picasa.ini:!*~";
+// The ignore pattern that can be passed via --ignore-assets in Main.cpp
+const char * gUserIgnoreAssets = NULL;
+
 static bool isHidden(const char *root, const char *path)
 {
-    const char *ext  = NULL;
-    const char *type = NULL;
+    // Patterns syntax:
+    // - Delimiter is :
+    // - Entry can start with the flag ! to avoid printing a warning
+    //   about the file being ignored.
+    // - Entry can have the flag "<dir>" to match only directories
+    //   or <file> to match only files. Default is to match both.
+    // - Entry can be a simplified glob "<prefix>*" or "*<suffix>"
+    //   where prefix/suffix must have at least 1 character (so that
+    //   we don't match a '*' catch-all pattern.)
+    // - The special filenames "." and ".." are always ignored.
+    // - Otherwise the full string is matched.
+    // - match is not case-sensitive.
 
-    // Skip all hidden files.
-    if (path[0] == '.') {
-        // Skip ., .. and  .svn but don't chatter about it.
-        if (strcmp(path, ".") == 0
-            || strcmp(path, "..") == 0
-            || strcmp(path, ".svn") == 0) {
-            return true;
-        }
-        type = "hidden";
-    } else if (path[0] == '_') {
-        // skip directories starting with _ (don't chatter about it)
-        String8 subdirName(root);
-        subdirName.appendPath(path);
-        if (getFileType(subdirName.string()) == kFileTypeDirectory) {
-            return true;
-        }
-    } else if (strcmp(path, "CVS") == 0) {
-        // Skip CVS but don't chatter about it.
+    if (strcmp(path, ".") == 0 || strcmp(path, "..") == 0) {
         return true;
-    } else if (strcasecmp(path, "thumbs.db") == 0
-               || strcasecmp(path, "picasa.ini") == 0) {
-        // Skip suspected image indexes files.
-        type = "index";
-    } else if (path[strlen(path)-1] == '~') {
-        // Skip suspected emacs backup files.
-        type = "backup";
-    } else if ((ext = strrchr(path, '.')) != NULL && strcmp(ext, ".scc") == 0) {
-        // Skip VisualSourceSafe files and don't chatter about it
-        return true;
-    } else {
-        // Let everything else through.
-        return false;
     }
 
-    /* If we get this far, "type" should be set and the file
-     * should be skipped.
-     */
-    String8 subdirName(root);
-    subdirName.appendPath(path);
-    fprintf(stderr, "    (skipping %s %s '%s')\n", type,
-            getFileType(subdirName.string())==kFileTypeDirectory ? "dir":"file",
-            subdirName.string());
+    const char *delim = ":";
+    const char *p = gUserIgnoreAssets;
+    if (!p || !p[0]) {
+        p = getenv("ANDROID_AAPT_IGNORE");
+    }
+    if (!p || !p[0]) {
+        p = gDefaultIgnoreAssets;
+    }
+    char *patterns = strdup(p);
 
-    return true;
+    bool ignore = false;
+    bool chatty = true;
+    char *matchedPattern = NULL;
+
+    String8 fullPath(root);
+    fullPath.appendPath(path);
+    FileType type = getFileType(fullPath);
+
+    int plen = strlen(path);
+
+    // Note: we don't have strtok_r under mingw.
+    for(char *token = strtok(patterns, delim);
+            !ignore && token != NULL;
+            token = strtok(NULL, delim)) {
+        chatty = token[0] != '!';
+        if (!chatty) token++; // skip !
+        if (strncasecmp(token, "<dir>" , 5) == 0) {
+            if (type != kFileTypeDirectory) continue;
+            token += 5;
+        }
+        if (strncasecmp(token, "<file>", 6) == 0) {
+            if (type != kFileTypeRegular) continue;
+            token += 6;
+        }
+
+        matchedPattern = token;
+        int n = strlen(token);
+
+        if (token[0] == '*') {
+            // Match *suffix
+            token++;
+            n--;
+            if (n <= plen) {
+                ignore = strncasecmp(token, path + plen - n, n) == 0;
+            }
+        } else if (n > 1 && token[n - 1] == '*') {
+            // Match prefix*
+            ignore = strncasecmp(token, path, n - 1) == 0;
+        } else {
+            ignore = strcasecmp(token, path) == 0;
+        }
+    }
+
+    if (ignore && chatty) {
+        fprintf(stderr, "    (skipping %s '%s' due to ANDROID_AAPT_IGNORE pattern '%s')\n",
+                type == kFileTypeDirectory ? "dir" : "file",
+                path,
+                matchedPattern ? matchedPattern : "");
+    }
+
+    free(patterns);
+    return ignore;
 }
 
 // =========================================================================
diff --git a/tools/aapt/AaptAssets.h b/tools/aapt/AaptAssets.h
index d5345b2..52751c7 100644
--- a/tools/aapt/AaptAssets.h
+++ b/tools/aapt/AaptAssets.h
@@ -22,6 +22,10 @@
 
 using namespace android;
 
+
+extern const char * const gDefaultIgnoreAssets;
+extern const char * gUserIgnoreAssets;
+
 bool valid_symbol_name(const String8& str);
 
 class AaptAssets;
diff --git a/tools/aapt/Android.mk b/tools/aapt/Android.mk
index cb55a9c..eeddd4b 100644
--- a/tools/aapt/Android.mk
+++ b/tools/aapt/Android.mk
@@ -29,6 +29,10 @@
 
 
 LOCAL_CFLAGS += -Wno-format-y2k
+ifeq (darwin,$(HOST_OS))
+LOCAL_CFLAGS += -D_DARWIN_UNLIMITED_STREAMS
+endif
+
 
 LOCAL_C_INCLUDES += external/expat/lib
 LOCAL_C_INCLUDES += external/libpng
diff --git a/tools/aapt/Bundle.h b/tools/aapt/Bundle.h
index 2d1060b..e402d70 100644
--- a/tools/aapt/Bundle.h
+++ b/tools/aapt/Bundle.h
@@ -41,7 +41,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),
@@ -96,8 +95,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; }
@@ -235,7 +232,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..9570c66 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
@@ -178,7 +176,11 @@
         "   --non-constant-id\n"
         "       Make the resources ID non constant. This is required to make an R java class\n"
         "       that does not contain the final value but is used to make reusable compiled\n"
-        "       libraries that need to access resources.\n");
+        "       libraries that need to access resources.\n"
+        "   --ignore-assets\n"
+        "       Assets to be ignored. Default pattern is:\n"
+        "       %s\n",
+        gDefaultIgnoreAssets);
 }
 
 /*
@@ -292,9 +294,6 @@
             case 'm':
                 bundle.setMakePackageDirs(true);
                 break;
-            case 'o':
-                bundle.setIsOverlayPackage(true);
-                break;
 #if 0
             case 'p':
                 bundle.setPseudolocalize(true);
@@ -556,7 +555,16 @@
                     bundle.setNonConstantId(true);
                 } else if (strcmp(cp, "-no-crunch") == 0) {
                     bundle.setUseCrunchCache(true);
-                }else {
+                } else if (strcmp(cp, "-ignore-assets") == 0) {
+                    argc--;
+                    argv++;
+                    if (!argc) {
+                        fprintf(stderr, "ERROR: No argument supplied for '--ignore-assets' option\n");
+                        wantUsage = true;
+                        goto bail;
+                    }
+                    gUserIgnoreAssets = argv[0];
+                } else {
                     fprintf(stderr, "ERROR: Unknown option '-%s'\n", cp);
                     wantUsage = true;
                     goto bail;
diff --git a/tools/aapt/ResourceTable.cpp b/tools/aapt/ResourceTable.cpp
index fdb39ca..d051c29 100644
--- a/tools/aapt/ResourceTable.cpp
+++ b/tools/aapt/ResourceTable.cpp
@@ -2253,7 +2253,6 @@
         bool failed = false;
         while (pos < end && !failed) {
             const char16_t* start = pos;
-            end++;
             while (pos < end && *pos != '|') {
                 pos++;
             }
@@ -2661,6 +2660,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.
@@ -2797,6 +2802,7 @@
                         if (amt < 0) {
                             return amt;
                         }
+                        validResources.editItemAt(ei) = true;
                     } else {
                         index[ei] = htodl(ResTable_type::NO_ENTRY);
                     }
@@ -2807,6 +2813,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.
@@ -3609,9 +3623,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");
diff --git a/tools/layoutlib/bridge/.classpath b/tools/layoutlib/bridge/.classpath
index 9fb000e..a5db7b1 100644
--- a/tools/layoutlib/bridge/.classpath
+++ b/tools/layoutlib/bridge/.classpath
@@ -3,7 +3,7 @@
 	<classpathentry excluding="org/kxml2/io/" kind="src" path="src"/>
 	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
 	<classpathentry kind="var" path="ANDROID_PLAT_SRC/prebuilt/common/layoutlib_api/layoutlib_api-prebuilt.jar"/>
-	<classpathentry kind="var" path="ANDROID_PLAT_SRC/prebuilt/common/kxml2/kxml2-2.3.0.jar" sourcepath="/ANDROID_PLAT_SRC/dalvik/libcore/xml/src/main/java"/>
+	<classpathentry kind="var" path="ANDROID_PLAT_SRC/prebuilts/misc/common/kxml2/kxml2-2.3.0.jar" sourcepath="/ANDROID_PLAT_SRC/dalvik/libcore/xml/src/main/java"/>
 	<classpathentry kind="var" path="ANDROID_PLAT_SRC/out/host/common/obj/JAVA_LIBRARIES/temp_layoutlib_intermediates/javalib.jar" sourcepath="/ANDROID_PLAT_SRC/frameworks/base"/>
 	<classpathentry kind="var" path="ANDROID_PLAT_SRC/prebuilt/common/ninepatch/ninepatch-prebuilt.jar"/>
 	<classpathentry kind="var" path="ANDROID_PLAT_SRC/prebuilt/common/tools-common/tools-common-prebuilt.jar"/>
diff --git a/tools/layoutlib/bridge/tests/.classpath b/tools/layoutlib/bridge/tests/.classpath
index 027bc67..2b32e09 100644
--- a/tools/layoutlib/bridge/tests/.classpath
+++ b/tools/layoutlib/bridge/tests/.classpath
@@ -4,7 +4,7 @@
 	<classpathentry kind="src" path="res"/>
 	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
 	<classpathentry combineaccessrules="false" kind="src" path="/layoutlib_bridge"/>
-	<classpathentry kind="var" path="ANDROID_PLAT_SRC/prebuilt/common/kxml2/kxml2-2.3.0.jar" sourcepath="/ANDROID_PLAT_SRC/dalvik/libcore/xml/src/main/java"/>
+	<classpathentry kind="var" path="ANDROID_PLAT_SRC/prebuilts/misc/common/kxml2/kxml2-2.3.0.jar" sourcepath="/ANDROID_PLAT_SRC/dalvik/libcore/xml/src/main/java"/>
 	<classpathentry kind="var" path="ANDROID_PLAT_SRC/out/host/common/obj/JAVA_LIBRARIES/temp_layoutlib_intermediates/javalib.jar" sourcepath="/ANDROID_PLAT_SRC/frameworks/base"/>
 	<classpathentry kind="con" path="org.eclipse.jdt.junit.JUNIT_CONTAINER/3"/>
 	<classpathentry kind="output" path="bin"/>
diff --git a/tools/layoutlib/create/src/com/android/tools/layoutlib/create/AsmAnalyzer.java b/tools/layoutlib/create/src/com/android/tools/layoutlib/create/AsmAnalyzer.java
index b197ea7..1549cf4 100644
--- a/tools/layoutlib/create/src/com/android/tools/layoutlib/create/AsmAnalyzer.java
+++ b/tools/layoutlib/create/src/com/android/tools/layoutlib/create/AsmAnalyzer.java
@@ -45,7 +45,7 @@
 public class AsmAnalyzer {
 
     // Note: a bunch of stuff has package-level access for unit tests. Consider it private.
-    
+
     /** Output logger. */
     private final Log mLog;
     /** The input source JAR to parse. */
@@ -59,11 +59,11 @@
 
     /**
      * Creates a new analyzer.
-     * 
+     *
      * @param log The log output.
      * @param osJarPath The input source JARs to parse.
      * @param gen The generator to fill with the class list and dependency list.
-     * @param deriveFrom Keep all classes that derive from these one (these included). 
+     * @param deriveFrom Keep all classes that derive from these one (these included).
      * @param includeGlobs Glob patterns of classes to keep, e.g. "com.foo.*"
      *        ("*" does not matches dots whilst "**" does, "." and "$" are interpreted as-is)
      */
@@ -81,16 +81,13 @@
      * Fills the generator with classes & dependencies found.
      */
     public void analyze() throws IOException, LogAbortException {
-
-        AsmAnalyzer visitor = this;
-        
         Map<String, ClassReader> zipClasses = parseZip(mOsSourceJar);
         mLog.info("Found %d classes in input JAR%s.", zipClasses.size(),
                 mOsSourceJar.size() > 1 ? "s" : "");
-        
+
         Map<String, ClassReader> found = findIncludes(zipClasses);
         Map<String, ClassReader> deps = findDeps(zipClasses, found);
-        
+
         if (mGen != null) {
             mGen.setKeep(found);
             mGen.setDeps(deps);
@@ -117,10 +114,10 @@
                 }
             }
         }
-        
+
         return classes;
     }
-    
+
     /**
      * Utility that returns the fully qualified binary class name for a ClassReader.
      * E.g. it returns something like android.view.View.
@@ -132,7 +129,7 @@
             return classReader.getClassName().replace('/', '.');
         }
     }
-    
+
     /**
      * Utility that returns the fully qualified binary class name from a path-like FQCN.
      * E.g. it returns android.view.View from android/view/View.
@@ -144,7 +141,7 @@
             return className.replace('/', '.');
         }
     }
-    
+
     /**
      * Process the "includes" arrays.
      * <p/>
@@ -162,11 +159,11 @@
         for (String s : mDeriveFrom) {
             findClassesDerivingFrom(s, zipClasses, found);
         }
-        
+
         return found;
     }
 
-    
+
     /**
      * Uses ASM to find the class reader for the given FQCN class name.
      * If found, insert it in the in_out_found map.
@@ -215,7 +212,7 @@
         globPattern += "$";
 
         Pattern regexp = Pattern.compile(globPattern);
-        
+
         for (Entry<String, ClassReader> entry : zipClasses.entrySet()) {
             String class_name = entry.getKey();
             if (regexp.matcher(class_name).matches()) {
@@ -229,10 +226,9 @@
      * determine if they are derived from the given FQCN super class name.
      * Inserts the super class and all the class objects found in the map.
      */
-    void findClassesDerivingFrom(String super_name, Map<String, ClassReader> zipClasses,
-            Map<String, ClassReader> inOutFound) throws LogAbortException {
-        ClassReader super_clazz = findClass(super_name, zipClasses, inOutFound);
-
+    void findClassesDerivingFrom(String super_name,
+            Map<String, ClassReader> zipClasses,
+            Map<String, ClassReader> inOutFound) {
         for (Entry<String, ClassReader> entry : zipClasses.entrySet()) {
             String className = entry.getKey();
             if (super_name.equals(className)) {
@@ -284,7 +280,7 @@
         for (ClassReader cr : inOutKeepClasses.values()) {
             cr.accept(visitor, 0 /* flags */);
         }
-        
+
         while (new_deps.size() > 0 || new_keep.size() > 0) {
             deps.putAll(new_deps);
             inOutKeepClasses.putAll(new_keep);
@@ -308,12 +304,12 @@
         return deps;
     }
 
-    
+
 
     // ----------------------------------
-    
+
     /**
-     * Visitor to collect all the type dependencies from a class. 
+     * Visitor to collect all the type dependencies from a class.
      */
     public class DependencyVisitor
         implements ClassVisitor, FieldVisitor, MethodVisitor, SignatureVisitor, AnnotationVisitor {
@@ -333,7 +329,7 @@
          * Creates a new visitor that will find all the dependencies for the visited class.
          * Types which are already in the zipClasses, keepClasses or inDeps are not marked.
          * New dependencies are marked in outDeps.
-         * 
+         *
          * @param zipClasses All classes found in the source JAR.
          * @param inKeep Classes from which dependencies are to be found.
          * @param inDeps Dependencies already known.
@@ -350,7 +346,7 @@
             mInDeps = inDeps;
             mOutDeps = outDeps;
         }
-        
+
         /**
          * Considers the given class name as a dependency.
          * If it does, add to the mOutDeps map.
@@ -361,7 +357,7 @@
             }
 
             className = internalToBinaryClassName(className);
-            
+
             // exclude classes that have already been found
             if (mInKeep.containsKey(className) ||
                     mOutKeep.containsKey(className) ||
@@ -384,7 +380,7 @@
             } catch (ClassNotFoundException e) {
                 // ignore
             }
-            
+
             // accept this class:
             // - android classes are added to dependencies
             // - non-android classes are added to the list of classes to keep as-is (they don't need
@@ -395,7 +391,7 @@
                 mOutKeep.put(className, cr);
             }
         }
-        
+
         /**
          * Considers this array of names using considerName().
          */
@@ -450,7 +446,7 @@
             }
         }
 
-        
+
         // ---------------------------------------------------
         // --- ClassVisitor, FieldVisitor
         // ---------------------------------------------------
@@ -460,7 +456,7 @@
                 String signature, String superName, String[] interfaces) {
             // signature is the signature of this class. May be null if the class is not a generic
             // one, and does not extend or implement generic classes or interfaces.
-            
+
             if (signature != null) {
                 considerSignature(signature);
             }
@@ -468,7 +464,7 @@
             // superName is the internal of name of the super class (see getInternalName).
             // For interfaces, the super class is Object. May be null but only for the Object class.
             considerName(superName);
-            
+
             // interfaces is the internal names of the class's interfaces (see getInternalName).
             // May be null.
             considerNames(interfaces);
@@ -513,7 +509,7 @@
             // signature is the method's signature. May be null if the method parameters, return
             // type and exceptions do not use generic types.
             considerSignature(signature);
-            
+
             return this; // returns this to visit the method
         }
 
@@ -525,7 +521,7 @@
             // pass
         }
 
-        
+
         // ---------------------------------------------------
         // --- MethodVisitor
         // ---------------------------------------------------
@@ -601,7 +597,7 @@
 
         // instruction that invokes a method
         public void visitMethodInsn(int opcode, String owner, String name, String desc) {
-            
+
             // owner is the internal name of the method's owner class
             considerName(owner);
             // desc is the method's descriptor (see Type).
@@ -610,7 +606,7 @@
 
         // instruction multianewarray, whatever that is
         public void visitMultiANewArrayInsn(String desc, int dims) {
-            
+
             // desc an array type descriptor.
             considerDesc(desc);
         }
@@ -624,7 +620,7 @@
 
         public void visitTableSwitchInsn(int min, int max, Label dflt, Label[] labels) {
             // pass -- table switch instruction
-            
+
         }
 
         public void visitTryCatchBlock(Label start, Label end, Label handler, String type) {
@@ -641,10 +637,10 @@
         }
 
         public void visitVarInsn(int opcode, int var) {
-            // pass -- local variable instruction 
+            // pass -- local variable instruction
         }
 
-        
+
         // ---------------------------------------------------
         // --- SignatureVisitor
         // ---------------------------------------------------
@@ -716,8 +712,8 @@
         public void visitTypeArgument() {
             // pass
         }
-        
-        
+
+
         // ---------------------------------------------------
         // --- AnnotationVisitor
         // ---------------------------------------------------
@@ -746,6 +742,6 @@
             // desc is the class descriptor of the enumeration class.
             considerDesc(desc);
         }
-        
+
     }
 }
diff --git a/tools/layoutlib/create/src/com/android/tools/layoutlib/create/DependencyFinder.java b/tools/layoutlib/create/src/com/android/tools/layoutlib/create/DependencyFinder.java
new file mode 100755
index 0000000..2956958
--- /dev/null
+++ b/tools/layoutlib/create/src/com/android/tools/layoutlib/create/DependencyFinder.java
@@ -0,0 +1,694 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.tools.layoutlib.create;
+
+import com.android.tools.layoutlib.annotations.VisibleForTesting;
+import com.android.tools.layoutlib.annotations.VisibleForTesting.Visibility;
+
+import org.objectweb.asm.AnnotationVisitor;
+import org.objectweb.asm.Attribute;
+import org.objectweb.asm.ClassReader;
+import org.objectweb.asm.ClassVisitor;
+import org.objectweb.asm.FieldVisitor;
+import org.objectweb.asm.Label;
+import org.objectweb.asm.MethodVisitor;
+import org.objectweb.asm.Type;
+import org.objectweb.asm.signature.SignatureReader;
+import org.objectweb.asm.signature.SignatureVisitor;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Enumeration;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.Set;
+import java.util.TreeMap;
+import java.util.TreeSet;
+import java.util.zip.ZipEntry;
+import java.util.zip.ZipFile;
+
+/**
+ * Analyzes the input JAR using the ASM java bytecode manipulation library
+ * to list the classes and their dependencies. A "dependency" is a class
+ * used by another class.
+ */
+public class DependencyFinder {
+
+    // Note: a bunch of stuff has package-level access for unit tests. Consider it private.
+
+    /** Output logger. */
+    private final Log mLog;
+
+    /**
+     * Creates a new analyzer.
+     *
+     * @param log The log output.
+     */
+    public DependencyFinder(Log log) {
+        mLog = log;
+    }
+
+    /**
+     * Starts the analysis using parameters from the constructor.
+     *
+     * @param osJarPath The input source JARs to parse.
+     * @return A pair: [0]: map { class FQCN => set of FQCN class dependencies }.
+     *                 [1]: map { missing class FQCN => set of FQCN class that uses it. }
+     */
+    public List<Map<String, Set<String>>> findDeps(List<String> osJarPath) throws IOException {
+
+        Map<String, ClassReader> zipClasses = parseZip(osJarPath);
+        mLog.info("Found %d classes in input JAR%s.",
+                zipClasses.size(),
+                osJarPath.size() > 1 ? "s" : "");
+
+        Map<String, Set<String>> deps = findClassesDeps(zipClasses);
+
+        Map<String, Set<String>> missing = findMissingClasses(deps, zipClasses.keySet());
+
+        List<Map<String, Set<String>>> result = new ArrayList<Map<String,Set<String>>>(2);
+        result.add(deps);
+        result.add(missing);
+        return result;
+    }
+
+    /**
+     * Prints dependencies to the current logger, found stuff and missing stuff.
+     */
+    public void printAllDeps(List<Map<String, Set<String>>> result) {
+        assert result.size() == 2;
+        Map<String, Set<String>> deps = result.get(0);
+        Map<String, Set<String>> missing = result.get(1);
+
+        // Print all dependences found in the format:
+        // +Found: <FQCN from zip>
+        //     uses: FQCN
+
+        mLog.info("++++++ %d Entries found in source JARs", deps.size());
+        mLog.info("");
+
+        for (Entry<String, Set<String>> entry : deps.entrySet()) {
+            mLog.info(    "+Found  : %s", entry.getKey());
+            for (String dep : entry.getValue()) {
+                mLog.info("    uses: %s", dep);
+            }
+
+            mLog.info("");
+        }
+
+
+        // Now print all missing dependences in the format:
+        // -Missing <FQCN>:
+        //     used by: <FQCN>
+
+        mLog.info("");
+        mLog.info("------ %d Entries missing from source JARs", missing.size());
+        mLog.info("");
+
+        for (Entry<String, Set<String>> entry : missing.entrySet()) {
+            mLog.info(    "-Missing  : %s", entry.getKey());
+            for (String dep : entry.getValue()) {
+                mLog.info("   used by: %s", dep);
+            }
+
+            mLog.info("");
+        }
+    }
+
+    /**
+     * Prints only a summary of the missing dependencies to the current logger.
+     */
+    public void printMissingDeps(List<Map<String, Set<String>>> result) {
+        assert result.size() == 2;
+        @SuppressWarnings("unused") Map<String, Set<String>> deps = result.get(0);
+        Map<String, Set<String>> missing = result.get(1);
+
+        for (String fqcn : missing.keySet()) {
+            mLog.info("%s", fqcn);
+        }
+    }
+
+    // ----------------
+
+    /**
+     * Parses a JAR file and returns a list of all classes founds using a map
+     * class name => ASM ClassReader. Class names are in the form "android.view.View".
+     */
+    Map<String,ClassReader> parseZip(List<String> jarPathList) throws IOException {
+        TreeMap<String, ClassReader> classes = new TreeMap<String, ClassReader>();
+
+        for (String jarPath : jarPathList) {
+            ZipFile zip = new ZipFile(jarPath);
+            Enumeration<? extends ZipEntry> entries = zip.entries();
+            ZipEntry entry;
+            while (entries.hasMoreElements()) {
+                entry = entries.nextElement();
+                if (entry.getName().endsWith(".class")) {
+                    ClassReader cr = new ClassReader(zip.getInputStream(entry));
+                    String className = classReaderToClassName(cr);
+                    classes.put(className, cr);
+                }
+            }
+        }
+
+        return classes;
+    }
+
+    /**
+     * Utility that returns the fully qualified binary class name for a ClassReader.
+     * E.g. it returns something like android.view.View.
+     */
+    static String classReaderToClassName(ClassReader classReader) {
+        if (classReader == null) {
+            return null;
+        } else {
+            return classReader.getClassName().replace('/', '.');
+        }
+    }
+
+    /**
+     * Utility that returns the fully qualified binary class name from a path-like FQCN.
+     * E.g. it returns android.view.View from android/view/View.
+     */
+    static String internalToBinaryClassName(String className) {
+        if (className == null) {
+            return null;
+        } else {
+            return className.replace('/', '.');
+        }
+    }
+
+    /**
+     * Finds all dependencies for all classes in keepClasses which are also
+     * listed in zipClasses. Returns a map of all the dependencies found.
+     */
+    Map<String, Set<String>> findClassesDeps(Map<String, ClassReader> zipClasses) {
+
+        // The dependencies that we'll collect.
+        // It's a map Class name => uses class names.
+        Map<String, Set<String>> dependencyMap = new TreeMap<String, Set<String>>();
+
+        DependencyVisitor visitor = getVisitor();
+
+        int count = 0;
+        try {
+            for (Entry<String, ClassReader> entry : zipClasses.entrySet()) {
+                String name = entry.getKey();
+
+                TreeSet<String> set = new TreeSet<String>();
+                dependencyMap.put(name, set);
+                visitor.setDependencySet(set);
+
+                ClassReader cr = entry.getValue();
+                cr.accept(visitor, 0 /* flags */);
+
+                visitor.setDependencySet(null);
+
+                mLog.debugNoln("Visited %d classes\r", ++count);
+            }
+        } finally {
+            mLog.debugNoln("\n");
+        }
+
+        return dependencyMap;
+    }
+
+    /**
+     * Computes which classes FQCN were found as dependencies that are NOT listed
+     * in the original JAR classes.
+     *
+     * @param deps The map { FQCN => dependencies[] } returned by {@link #findClassesDeps(Map)}.
+     * @param zipClasses The set of all classes FQCN found in the JAR files.
+     * @return A map { FQCN not found in the zipClasses => classes using it }
+     */
+    private Map<String, Set<String>> findMissingClasses(
+            Map<String, Set<String>> deps,
+            Set<String> zipClasses) {
+        Map<String, Set<String>> missing = new TreeMap<String, Set<String>>();
+
+        for (Entry<String, Set<String>> entry : deps.entrySet()) {
+            String name = entry.getKey();
+
+            for (String dep : entry.getValue()) {
+                if (!zipClasses.contains(dep)) {
+                    // This dependency doesn't exist in the zip classes.
+                    Set<String> set = missing.get(dep);
+                    if (set == null) {
+                        set = new TreeSet<String>();
+                        missing.put(dep, set);
+                    }
+                    set.add(name);
+                }
+            }
+
+        }
+
+        return missing;
+    }
+
+
+    // ----------------------------------
+
+    /**
+     * Instantiates a new DependencyVisitor. Useful for unit tests.
+     */
+    @VisibleForTesting(visibility=Visibility.PRIVATE)
+    DependencyVisitor getVisitor() {
+        return new DependencyVisitor();
+    }
+
+    /**
+     * Visitor to collect all the type dependencies from a class.
+     */
+    public class DependencyVisitor
+        implements ClassVisitor, FieldVisitor, MethodVisitor, SignatureVisitor, AnnotationVisitor {
+
+        private Set<String> mCurrentDepSet;
+
+        /**
+         * Creates a new visitor that will find all the dependencies for the visited class.
+         */
+        public DependencyVisitor() {
+        }
+
+        /**
+         * Sets the {@link Set} where to record direct dependencies for this class.
+         * This will change before each {@link ClassReader#accept(ClassVisitor, int)} call.
+         */
+        public void setDependencySet(Set<String> set) {
+            mCurrentDepSet = set;
+        }
+
+        /**
+         * Considers the given class name as a dependency.
+         */
+        public void considerName(String className) {
+            if (className == null) {
+                return;
+            }
+
+            className = internalToBinaryClassName(className);
+
+            try {
+                // exclude classes that are part of the default JRE (the one executing this program)
+                if (getClass().getClassLoader().loadClass(className) != null) {
+                    return;
+                }
+            } catch (ClassNotFoundException e) {
+                // ignore
+            }
+
+            // Add it to the dependency set for the currently visited class, as needed.
+            assert mCurrentDepSet != null;
+            if (mCurrentDepSet != null) {
+                mCurrentDepSet.add(className);
+            }
+        }
+
+        /**
+         * Considers this array of names using considerName().
+         */
+        public void considerNames(String[] classNames) {
+            if (classNames != null) {
+                for (String className : classNames) {
+                    considerName(className);
+                }
+            }
+        }
+
+        /**
+         * Considers this signature or type signature by invoking the {@link SignatureVisitor}
+         * on it.
+         */
+        public void considerSignature(String signature) {
+            if (signature != null) {
+                SignatureReader sr = new SignatureReader(signature);
+                // SignatureReader.accept will call accessType so we don't really have
+                // to differentiate where the signature comes from.
+                sr.accept(this);
+            }
+        }
+
+        /**
+         * Considers this {@link Type}. For arrays, the element type is considered.
+         * If the type is an object, it's internal name is considered.
+         */
+        public void considerType(Type t) {
+            if (t != null) {
+                if (t.getSort() == Type.ARRAY) {
+                    t = t.getElementType();
+                }
+                if (t.getSort() == Type.OBJECT) {
+                    considerName(t.getInternalName());
+                }
+            }
+        }
+
+        /**
+         * Considers a descriptor string. The descriptor is converted to a {@link Type}
+         * and then considerType() is invoked.
+         */
+        public boolean considerDesc(String desc) {
+            if (desc != null) {
+                try {
+                    if (desc.length() > 0 && desc.charAt(0) == '(') {
+                        // This is a method descriptor with arguments and a return type.
+                        Type t = Type.getReturnType(desc);
+                        considerType(t);
+
+                        for (Type arg : Type.getArgumentTypes(desc)) {
+                            considerType(arg);
+                        }
+
+                    } else {
+                        Type t = Type.getType(desc);
+                        considerType(t);
+                    }
+                    return true;
+                } catch (ArrayIndexOutOfBoundsException e) {
+                    // ignore, not a valid type.
+                }
+            }
+            return false;
+        }
+
+
+        // ---------------------------------------------------
+        // --- ClassVisitor, FieldVisitor
+        // ---------------------------------------------------
+
+        // Visits a class header
+        public void visit(int version, int access, String name,
+                String signature, String superName, String[] interfaces) {
+            // signature is the signature of this class. May be null if the class is not a generic
+            // one, and does not extend or implement generic classes or interfaces.
+
+            if (signature != null) {
+                considerSignature(signature);
+            }
+
+            // superName is the internal of name of the super class (see getInternalName).
+            // For interfaces, the super class is Object. May be null but only for the Object class.
+            considerName(superName);
+
+            // interfaces is the internal names of the class's interfaces (see getInternalName).
+            // May be null.
+            considerNames(interfaces);
+        }
+
+        public AnnotationVisitor visitAnnotation(String desc, boolean visible) {
+            // desc is the class descriptor of the annotation class.
+            considerDesc(desc);
+            return this; // return this to visit annotion values
+        }
+
+        public void visitAttribute(Attribute attr) {
+            // pass
+        }
+
+        // Visits the end of a class
+        public void visitEnd() {
+            // pass
+        }
+
+        public FieldVisitor visitField(int access, String name, String desc,
+                String signature, Object value) {
+            // desc is the field's descriptor (see Type).
+            considerDesc(desc);
+
+            // signature is the field's signature. May be null if the field's type does not use
+            // generic types.
+            considerSignature(signature);
+
+            return this; // a visitor to visit field annotations and attributes
+        }
+
+        public void visitInnerClass(String name, String outerName, String innerName, int access) {
+            // name is the internal name of an inner class (see getInternalName).
+            // Note: outerName/innerName seems to be null when we're reading the
+            // _Original_ClassName classes generated by layoutlib_create.
+            if (outerName != null) {
+                considerName(name);
+            }
+        }
+
+        public MethodVisitor visitMethod(int access, String name, String desc,
+                String signature, String[] exceptions) {
+            // desc is the method's descriptor (see Type).
+            considerDesc(desc);
+            // signature is the method's signature. May be null if the method parameters, return
+            // type and exceptions do not use generic types.
+            considerSignature(signature);
+
+            return this; // returns this to visit the method
+        }
+
+        public void visitOuterClass(String owner, String name, String desc) {
+            // pass
+        }
+
+        public void visitSource(String source, String debug) {
+            // pass
+        }
+
+
+        // ---------------------------------------------------
+        // --- MethodVisitor
+        // ---------------------------------------------------
+
+        public AnnotationVisitor visitAnnotationDefault() {
+            return this; // returns this to visit the default value
+        }
+
+
+        public void visitCode() {
+            // pass
+        }
+
+        // field instruction
+        public void visitFieldInsn(int opcode, String owner, String name, String desc) {
+            // name is the field's name, not a type.
+            // desc is the field's descriptor (see Type).
+            considerDesc(desc);
+        }
+
+        public void visitFrame(int type, int local, Object[] local2, int stack, Object[] stack2) {
+            // pass
+        }
+
+        public void visitIincInsn(int var, int increment) {
+            // pass -- an IINC instruction
+        }
+
+        public void visitInsn(int opcode) {
+            // pass -- a zero operand instruction
+        }
+
+        public void visitIntInsn(int opcode, int operand) {
+            // pass -- a single int operand instruction
+        }
+
+        public void visitJumpInsn(int opcode, Label label) {
+            // pass -- a jump instruction
+        }
+
+        public void visitLabel(Label label) {
+            // pass -- a label target
+        }
+
+        // instruction to load a constant from the stack
+        public void visitLdcInsn(Object cst) {
+            if (cst instanceof Type) {
+                considerType((Type) cst);
+            }
+        }
+
+        public void visitLineNumber(int line, Label start) {
+            // pass
+        }
+
+        public void visitLocalVariable(String name, String desc,
+                String signature, Label start, Label end, int index) {
+            // desc is the type descriptor of this local variable.
+            considerDesc(desc);
+            // signature is the type signature of this local variable. May be null if the local
+            // variable type does not use generic types.
+            considerSignature(signature);
+        }
+
+        public void visitLookupSwitchInsn(Label dflt, int[] keys, Label[] labels) {
+            // pass -- a lookup switch instruction
+        }
+
+        public void visitMaxs(int maxStack, int maxLocals) {
+            // pass
+        }
+
+        // instruction that invokes a method
+        public void visitMethodInsn(int opcode, String owner, String name, String desc) {
+
+            // owner is the internal name of the method's owner class
+            if (!considerDesc(owner) && owner.indexOf('/') != -1) {
+                considerName(owner);
+            }
+            // desc is the method's descriptor (see Type).
+            considerDesc(desc);
+        }
+
+        // instruction multianewarray, whatever that is
+        public void visitMultiANewArrayInsn(String desc, int dims) {
+
+            // desc an array type descriptor.
+            considerDesc(desc);
+        }
+
+        public AnnotationVisitor visitParameterAnnotation(int parameter, String desc,
+                boolean visible) {
+            // desc is the class descriptor of the annotation class.
+            considerDesc(desc);
+            return this; // return this to visit annotation values
+        }
+
+        public void visitTableSwitchInsn(int min, int max, Label dflt, Label[] labels) {
+            // pass -- table switch instruction
+
+        }
+
+        public void visitTryCatchBlock(Label start, Label end, Label handler, String type) {
+            // type is the internal name of the type of exceptions handled by the handler,
+            // or null to catch any exceptions (for "finally" blocks).
+            considerName(type);
+        }
+
+        // type instruction
+        public void visitTypeInsn(int opcode, String type) {
+            // type is the operand of the instruction to be visited. This operand must be the
+            // internal name of an object or array class.
+            if (!considerDesc(type) && type.indexOf('/') != -1) {
+                considerName(type);
+            }
+        }
+
+        public void visitVarInsn(int opcode, int var) {
+            // pass -- local variable instruction
+        }
+
+
+        // ---------------------------------------------------
+        // --- SignatureVisitor
+        // ---------------------------------------------------
+
+        private String mCurrentSignatureClass = null;
+
+        // Starts the visit of a signature corresponding to a class or interface type
+        public void visitClassType(String name) {
+            mCurrentSignatureClass = name;
+            considerName(name);
+        }
+
+        // Visits an inner class
+        public void visitInnerClassType(String name) {
+            if (mCurrentSignatureClass != null) {
+                mCurrentSignatureClass += "$" + name;
+                considerName(mCurrentSignatureClass);
+            }
+        }
+
+        public SignatureVisitor visitArrayType() {
+            return this; // returns this to visit the signature of the array element type
+        }
+
+        public void visitBaseType(char descriptor) {
+            // pass -- a primitive type, ignored
+        }
+
+        public SignatureVisitor visitClassBound() {
+            return this; // returns this to visit the signature of the class bound
+        }
+
+        public SignatureVisitor visitExceptionType() {
+            return this; // return this to visit the signature of the exception type.
+        }
+
+        public void visitFormalTypeParameter(String name) {
+            // pass
+        }
+
+        public SignatureVisitor visitInterface() {
+            return this; // returns this to visit the signature of the interface type
+        }
+
+        public SignatureVisitor visitInterfaceBound() {
+            return this; // returns this to visit the signature of the interface bound
+        }
+
+        public SignatureVisitor visitParameterType() {
+            return this; // returns this to visit the signature of the parameter type
+        }
+
+        public SignatureVisitor visitReturnType() {
+            return this; // returns this to visit the signature of the return type
+        }
+
+        public SignatureVisitor visitSuperclass() {
+            return this; // returns this to visit the signature of the super class type
+        }
+
+        public SignatureVisitor visitTypeArgument(char wildcard) {
+            return this; // returns this to visit the signature of the type argument
+        }
+
+        public void visitTypeVariable(String name) {
+            // pass
+        }
+
+        public void visitTypeArgument() {
+            // pass
+        }
+
+
+        // ---------------------------------------------------
+        // --- AnnotationVisitor
+        // ---------------------------------------------------
+
+
+        // Visits a primitive value of an annotation
+        public void visit(String name, Object value) {
+            // value is the actual value, whose type must be Byte, Boolean, Character, Short,
+            // Integer, Long, Float, Double, String or Type
+            if (value instanceof Type) {
+                considerType((Type) value);
+            }
+        }
+
+        public AnnotationVisitor visitAnnotation(String name, String desc) {
+            // desc is the class descriptor of the nested annotation class.
+            considerDesc(desc);
+            return this; // returns this to visit the actual nested annotation value
+        }
+
+        public AnnotationVisitor visitArray(String name) {
+            return this; // returns this to visit the actual array value elements
+        }
+
+        public void visitEnum(String name, String desc, String value) {
+            // desc is the class descriptor of the enumeration class.
+            considerDesc(desc);
+        }
+    }
+}
diff --git a/tools/layoutlib/create/src/com/android/tools/layoutlib/create/Log.java b/tools/layoutlib/create/src/com/android/tools/layoutlib/create/Log.java
index 8efd871..c3ba591 100644
--- a/tools/layoutlib/create/src/com/android/tools/layoutlib/create/Log.java
+++ b/tools/layoutlib/create/src/com/android/tools/layoutlib/create/Log.java
@@ -33,11 +33,19 @@
         }
     }
 
+    /** Similar to debug() but doesn't do a \n automatically. */
+    public void debugNoln(String format, Object... args) {
+        if (mVerbose) {
+            String s = String.format(format, args);
+            System.out.print(s);
+        }
+    }
+
     public void info(String format, Object... args) {
         String s = String.format(format, args);
         outPrintln(s);
     }
-    
+
     public void error(String format, Object... args) {
         String s = String.format(format, args);
         errPrintln(s);
@@ -50,15 +58,15 @@
         pw.flush();
         error(format + "\n" + sw.toString(), args);
     }
-    
+
     /** for unit testing */
     protected void errPrintln(String msg) {
         System.err.println(msg);
     }
-    
+
     /** for unit testing */
     protected void outPrintln(String msg) {
         System.out.println(msg);
     }
-    
+
 }
diff --git a/tools/layoutlib/create/src/com/android/tools/layoutlib/create/Main.java b/tools/layoutlib/create/src/com/android/tools/layoutlib/create/Main.java
index 4b7a348..9cd74db 100644
--- a/tools/layoutlib/create/src/com/android/tools/layoutlib/create/Main.java
+++ b/tools/layoutlib/create/src/com/android/tools/layoutlib/create/Main.java
@@ -18,6 +18,8 @@
 
 import java.io.IOException;
 import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
 import java.util.Set;
 
 
@@ -47,6 +49,8 @@
 
     public static class Options {
         public boolean generatePublicAccess = true;
+        public boolean listAllDeps = false;
+        public boolean listOnlyMissingDeps = false;
     }
 
     public static final Options sOptions = new Options();
@@ -60,16 +64,29 @@
 
         if (!processArgs(log, args, osJarPath, osDestJar)) {
             log.error("Usage: layoutlib_create [-v] [-p] output.jar input.jar ...");
+            log.error("Usage: layoutlib_create [-v] [--list-deps|--missing-deps] input.jar ...");
             System.exit(1);
         }
 
-        log.info("Output: %1$s", osDestJar[0]);
+        if (sOptions.listAllDeps || sOptions.listOnlyMissingDeps) {
+            System.exit(listDeps(osJarPath, log));
+
+        } else {
+            System.exit(createLayoutLib(osDestJar[0], osJarPath, log));
+        }
+
+
+        System.exit(1);
+    }
+
+    private static int createLayoutLib(String osDestJar, ArrayList<String> osJarPath, Log log) {
+        log.info("Output: %1$s", osDestJar);
         for (String path : osJarPath) {
             log.info("Input :      %1$s", path);
         }
 
         try {
-            AsmGenerator agen = new AsmGenerator(log, osDestJar[0], new CreateInfo());
+            AsmGenerator agen = new AsmGenerator(log, osDestJar, new CreateInfo());
 
             AsmAnalyzer aa = new AsmAnalyzer(log, osJarPath, agen,
                     new String[] {                          // derived from
@@ -116,17 +133,33 @@
                 for (String path : osJarPath) {
                     log.info("- Input JAR : %1$s", path);
                 }
-                System.exit(1);
+                return 1;
             }
 
-            System.exit(0);
+            return 0;
         } catch (IOException e) {
             log.exception(e, "Failed to load jar");
         } catch (LogAbortException e) {
             e.error(log);
         }
 
-        System.exit(1);
+        return 1;
+    }
+
+    private static int listDeps(ArrayList<String> osJarPath, Log log) {
+        DependencyFinder df = new DependencyFinder(log);
+        try {
+            List<Map<String, Set<String>>> result = df.findDeps(osJarPath);
+            if (sOptions.listAllDeps) {
+                df.printAllDeps(result);
+            } else if (sOptions.listOnlyMissingDeps) {
+                df.printMissingDeps(result);
+            }
+        } catch (IOException e) {
+            log.exception(e, "Failed to load jar");
+        }
+
+        return 0;
     }
 
     /**
@@ -138,14 +171,21 @@
      */
     private static boolean processArgs(Log log, String[] args,
             ArrayList<String> osJarPath, String[] osDestJar) {
+        boolean needs_dest = true;
         for (int i = 0; i < args.length; i++) {
             String s = args[i];
             if (s.equals("-v")) {
                 log.setVerbose(true);
             } else if (s.equals("-p")) {
                 sOptions.generatePublicAccess = false;
+            } else if (s.equals("--list-deps")) {
+                sOptions.listAllDeps = true;
+                needs_dest = false;
+            } else if (s.equals("--missing-deps")) {
+                sOptions.listOnlyMissingDeps = true;
+                needs_dest = false;
             } else if (!s.startsWith("-")) {
-                if (osDestJar[0] == null) {
+                if (needs_dest && osDestJar[0] == null) {
                     osDestJar[0] = s;
                 } else {
                     osJarPath.add(s);
@@ -160,7 +200,7 @@
             log.error("Missing parameter: path to input jar");
             return false;
         }
-        if (osDestJar[0] == null) {
+        if (needs_dest && osDestJar[0] == null) {
             log.error("Missing parameter: path to output jar");
             return false;
         }