Merge "New JAVA API to support submitting encrypted buffers of input data."
diff --git a/cmds/app_process/Android.mk b/cmds/app_process/Android.mk
index 2391b72..b39c335 100644
--- a/cmds/app_process/Android.mk
+++ b/cmds/app_process/Android.mk
@@ -13,3 +13,29 @@
 LOCAL_MODULE:= app_process
 
 include $(BUILD_EXECUTABLE)
+
+
+# Build a variant of app_process binary linked with ASan runtime.
+# ARM-only at the moment.
+ifeq ($(TARGET_ARCH),arm)
+
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES:= \
+	app_main.cpp
+
+LOCAL_SHARED_LIBRARIES := \
+	libcutils \
+	libutils \
+	libbinder \
+	libandroid_runtime
+
+LOCAL_MODULE := app_process__asan
+LOCAL_MODULE_TAGS := eng
+LOCAL_MODULE_PATH := $(TARGET_OUT_EXECUTABLES)/asan
+LOCAL_MODULE_STEM := app_process
+LOCAL_ADDRESS_SANITIZER := true
+
+include $(BUILD_EXECUTABLE)
+
+endif # ifeq($(TARGET_ARCH),arm)
diff --git a/core/java/android/content/Intent.java b/core/java/android/content/Intent.java
index 2a9f1af..736dd24 100644
--- a/core/java/android/content/Intent.java
+++ b/core/java/android/content/Intent.java
@@ -2034,6 +2034,38 @@
             "android.intent.action.HDMI_AUDIO_PLUG";
 
     /**
+     * Broadcast Action: A USB audio device was plugged in or unplugged.
+     *
+     * <p>The intent will have the following extra values:
+     * <ul>
+     *   <li><em>state</em> - 0 for unplugged, 1 for plugged. </li>
+     *   <li><em>card</em> - ALSA card number (integer) </li>
+     *   <li><em>device</em> - ALSA device number (integer) </li>
+     * </ul>
+     * </ul>
+     * @hide
+     */
+    @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
+    public static final String ACTION_USB_AUDIO_DEVICE_PLUG =
+            "android.intent.action.USB_AUDIO_DEVICE_PLUG";
+
+    /**
+     * Broadcast Action: A USB audio accessory was plugged in or unplugged.
+     *
+     * <p>The intent will have the following extra values:
+     * <ul>
+     *   <li><em>state</em> - 0 for unplugged, 1 for plugged. </li>
+     *   <li><em>card</em> - ALSA card number (integer) </li>
+     *   <li><em>device</em> - ALSA device number (integer) </li>
+     * </ul>
+     * </ul>
+     * @hide
+     */
+    @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
+    public static final String ACTION_USB_AUDIO_ACCESSORY_PLUG =
+            "android.intent.action.USB_AUDIO_ACCESSORY_PLUG";
+
+    /**
      * <p>Broadcast Action: The user has switched on advanced settings in the settings app:</p>
      * <ul>
      *   <li><em>state</em> - A boolean value indicating whether the settings is on or off.</li>
diff --git a/core/java/android/content/pm/PackageParser.java b/core/java/android/content/pm/PackageParser.java
index 15ccda3..7571993 100644
--- a/core/java/android/content/pm/PackageParser.java
+++ b/core/java/android/content/pm/PackageParser.java
@@ -94,10 +94,12 @@
     public static class SplitPermissionInfo {
         public final String rootPerm;
         public final String[] newPerms;
+        public final int targetSdk;
 
-        public SplitPermissionInfo(String rootPerm, String[] newPerms) {
+        public SplitPermissionInfo(String rootPerm, String[] newPerms, int targetSdk) {
             this.rootPerm = rootPerm;
             this.newPerms = newPerms;
+            this.targetSdk = targetSdk;
         }
     }
 
@@ -126,7 +128,14 @@
     public static final PackageParser.SplitPermissionInfo SPLIT_PERMISSIONS[] =
         new PackageParser.SplitPermissionInfo[] {
             new PackageParser.SplitPermissionInfo(android.Manifest.permission.WRITE_EXTERNAL_STORAGE,
-                    new String[] { android.Manifest.permission.READ_EXTERNAL_STORAGE })
+                    new String[] { android.Manifest.permission.READ_EXTERNAL_STORAGE },
+                    android.os.Build.VERSION_CODES.CUR_DEVELOPMENT+1),
+            new PackageParser.SplitPermissionInfo(android.Manifest.permission.READ_CONTACTS,
+                    new String[] { android.Manifest.permission.READ_CALL_LOG },
+                    android.os.Build.VERSION_CODES.JELLY_BEAN),
+            new PackageParser.SplitPermissionInfo(android.Manifest.permission.WRITE_CONTACTS,
+                    new String[] { android.Manifest.permission.WRITE_CALL_LOG },
+                    android.os.Build.VERSION_CODES.JELLY_BEAN)
     };
 
     private String mArchiveSourcePath;
@@ -1293,8 +1302,9 @@
         for (int is=0; is<NS; is++) {
             final PackageParser.SplitPermissionInfo spi
                     = PackageParser.SPLIT_PERMISSIONS[is];
-            if (!pkg.requestedPermissions.contains(spi.rootPerm)) {
-                break;
+            if (pkg.applicationInfo.targetSdkVersion >= spi.targetSdk
+                    || !pkg.requestedPermissions.contains(spi.rootPerm)) {
+                continue;
             }
             for (int in=0; in<spi.newPerms.length; in++) {
                 final String perm = spi.newPerms[in];
diff --git a/core/java/android/hardware/usb/UsbManager.java b/core/java/android/hardware/usb/UsbManager.java
index 93f93c7..c40504a7 100644
--- a/core/java/android/hardware/usb/UsbManager.java
+++ b/core/java/android/hardware/usb/UsbManager.java
@@ -66,6 +66,8 @@
      * PTP function is enabled
      * <li> {@link #USB_FUNCTION_PTP} boolean extra indicating whether the
      * accessory function is enabled
+     * <li> {@link #USB_FUNCTION_AUDIO_SOURCE} boolean extra indicating whether the
+     * audio source function is enabled
      * </ul>
      *
      * {@hide}
@@ -178,6 +180,14 @@
     public static final String USB_FUNCTION_PTP = "ptp";
 
     /**
+     * Name of the audio source USB function.
+     * Used in extras for the {@link #ACTION_USB_STATE} broadcast
+     *
+     * {@hide}
+     */
+    public static final String USB_FUNCTION_AUDIO_SOURCE = "audio_source";
+
+    /**
      * Name of the Accessory USB function.
      * Used in extras for the {@link #ACTION_USB_STATE} broadcast
      *
diff --git a/core/java/android/view/HardwareRenderer.java b/core/java/android/view/HardwareRenderer.java
index d1af397..b0399fd 100644
--- a/core/java/android/view/HardwareRenderer.java
+++ b/core/java/android/view/HardwareRenderer.java
@@ -526,7 +526,7 @@
         static final int SURFACE_STATE_SUCCESS = 1;
         static final int SURFACE_STATE_UPDATED = 2;
 
-        static final int FUNCTOR_PROCESS_DELAY = 2;
+        static final int FUNCTOR_PROCESS_DELAY = 4;
 
         static EGL10 sEgl;
         static EGLDisplay sEglDisplay;
diff --git a/libs/hwui/OpenGLRenderer.cpp b/libs/hwui/OpenGLRenderer.cpp
index 39d2e39..2a908ab 100644
--- a/libs/hwui/OpenGLRenderer.cpp
+++ b/libs/hwui/OpenGLRenderer.cpp
@@ -260,7 +260,7 @@
             Rect localDirty(info.dirtyLeft, info.dirtyTop, info.dirtyRight, info.dirtyBottom);
             dirty.unionWith(localDirty);
 
-            if (result == DrawGlInfo::kStatusInvoke) {
+            if (result & DrawGlInfo::kStatusInvoke) {
                 mFunctors.push(f);
             }
         }
@@ -300,7 +300,7 @@
         Rect localDirty(info.dirtyLeft, info.dirtyTop, info.dirtyRight, info.dirtyBottom);
         dirty.unionWith(localDirty);
 
-        if (result == DrawGlInfo::kStatusInvoke) {
+        if (result & DrawGlInfo::kStatusInvoke) {
             mFunctors.push(functor);
         }
     }
diff --git a/services/java/com/android/server/usb/UsbDeviceManager.java b/services/java/com/android/server/usb/UsbDeviceManager.java
index 4bea5e4..1bd15f6 100644
--- a/services/java/com/android/server/usb/UsbDeviceManager.java
+++ b/services/java/com/android/server/usb/UsbDeviceManager.java
@@ -60,6 +60,7 @@
 import java.util.List;
 import java.util.HashMap;
 import java.util.Map;
+import java.util.Scanner;
 
 /**
  * UsbDeviceManager manages USB state in device mode.
@@ -81,6 +82,8 @@
             "/sys/class/android_usb/android0/f_mass_storage/lun/file";
     private static final String RNDIS_ETH_ADDR_PATH =
             "/sys/class/android_usb/android0/f_rndis/ethaddr";
+    private static final String AUDIO_SOURCE_PCM_PATH =
+            "/sys/class/android_usb/android0/f_audio_source/pcm";
 
     private static final int MSG_UPDATE_STATE = 0;
     private static final int MSG_ENABLE_ADB = 1;
@@ -105,6 +108,7 @@
     private final boolean mHasUsbAccessory;
     private boolean mUseUsbNotification;
     private boolean mAdbEnabled;
+    private boolean mAudioSourceEnabled;
     private Map<String, List<Pair<String, String>>> mOemModeMap;
 
     private class AdbSettingsObserver extends ContentObserver {
@@ -291,6 +295,8 @@
                 String state = FileUtils.readTextFile(new File(STATE_PATH), 0, null).trim();
                 updateState(state);
                 mAdbEnabled = containsFunction(mCurrentFunctions, UsbManager.USB_FUNCTION_ADB);
+                mAudioSourceEnabled = containsFunction(mCurrentFunctions,
+                        UsbManager.USB_FUNCTION_AUDIO_SOURCE);
 
                 // Upgrade step for previous versions that used persist.service.adb.enable
                 String value = SystemProperties.get("persist.service.adb.enable", "");
@@ -504,6 +510,28 @@
             mContext.sendStickyBroadcast(intent);
         }
 
+        private void updateAudioSourceFunction(boolean enabled) {
+            // send a sticky broadcast containing current USB state
+            Intent intent = new Intent(Intent.ACTION_USB_AUDIO_ACCESSORY_PLUG);
+            intent.addFlags(Intent.FLAG_RECEIVER_REPLACE_PENDING);
+            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
+            intent.putExtra("state", (enabled ? 1 : 0));
+            if (enabled) {
+                try {
+                    Scanner scanner = new Scanner(new File(AUDIO_SOURCE_PCM_PATH));
+                    int card = scanner.nextInt();
+                    int device = scanner.nextInt();
+                    intent.putExtra("card", card);
+                    intent.putExtra("device", device);
+                } catch (FileNotFoundException e) {
+                    Slog.e(TAG, "could not open audio source PCM file", e);
+                }
+            }
+
+            mContext.sendStickyBroadcast(intent);
+            mAudioSourceEnabled = enabled;
+        }
+
         @Override
         public void handleMessage(Message msg) {
             switch (msg.what) {
@@ -523,6 +551,11 @@
                     }
                     if (mBootCompleted) {
                         updateUsbState();
+                        boolean audioSourceEnabled = containsFunction(mCurrentFunctions,
+                                UsbManager.USB_FUNCTION_AUDIO_SOURCE);
+                        if (audioSourceEnabled != mAudioSourceEnabled) {
+                            updateAudioSourceFunction(audioSourceEnabled);
+                        }
                     }
                     break;
                 case MSG_ENABLE_ADB:
@@ -543,6 +576,7 @@
                     if (mCurrentAccessory != null) {
                         mSettingsManager.accessoryAttached(mCurrentAccessory);
                     }
+                    updateAudioSourceFunction(mAudioSourceEnabled);
                     break;
             }
         }
diff --git a/tools/aapt/Command.cpp b/tools/aapt/Command.cpp
index 198fce4..689aa8e 100644
--- a/tools/aapt/Command.cpp
+++ b/tools/aapt/Command.cpp
@@ -639,6 +639,12 @@
             // If an app requests write storage, they will also get read storage.
             bool hasReadExternalStoragePermission = false;
 
+            // Implement transition to read and write call log.
+            bool hasReadContactsPermission = false;
+            bool hasWriteContactsPermission = false;
+            bool hasReadCallLogPermission = false;
+            bool hasWriteCallLogPermission = false;
+
             // This next group of variables is used to implement a group of
             // backward-compatibility heuristics necessitated by the addition of
             // some new uses-feature constants in 2.1 and 2.2. In most cases, the
@@ -1006,6 +1012,14 @@
                                 hasReadExternalStoragePermission = true;
                             } else if (name == "android.permission.READ_PHONE_STATE") {
                                 hasReadPhoneStatePermission = true;
+                            } else if (name == "android.permission.READ_CONTACTS") {
+                                hasReadContactsPermission = true;
+                            } else if (name == "android.permission.WRITE_CONTACTS") {
+                                hasWriteContactsPermission = true;
+                            } else if (name == "android.permission.READ_CALL_LOG") {
+                                hasReadCallLogPermission = true;
+                            } else if (name == "android.permission.WRITE_CALL_LOG") {
+                                hasWriteCallLogPermission = true;
                             }
                             printf("uses-permission:'%s'\n", name.string());
                         } else {
@@ -1181,6 +1195,16 @@
                 printf("uses-permission:'android.permission.READ_EXTERNAL_STORAGE'\n");
             }
 
+            // Pre-JellyBean call log permission compatibility.
+            if (targetSdk < 16) {
+                if (!hasReadCallLogPermission && hasReadContactsPermission) {
+                    printf("uses-permission:'android.permission.READ_CALL_LOG'\n");
+                }
+                if (!hasWriteCallLogPermission && hasWriteContactsPermission) {
+                    printf("uses-permission:'android.permission.WRITE_CALL_LOG'\n");
+                }
+            }
+
             /* The following blocks handle printing "inferred" uses-features, based
              * on whether related features or permissions are used by the app.
              * Note that the various spec*Feature variables denote whether the