Merge "MediaController: Keep the controller when touch exploration is enabled" into mnc-dev
diff --git a/api/current.txt b/api/current.txt
index aec29fd..0878e7e 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -4000,6 +4000,7 @@
     ctor public AssistContent();
     method public android.content.ClipData getClipData();
     method public android.net.Uri getWebUri();
+    method public boolean isAppProvidedIntent();
     method public void setClipData(android.content.ClipData);
     method public void setIntent(android.content.Intent);
     method public void setWebUri(android.net.Uri);
diff --git a/api/system-current.txt b/api/system-current.txt
index bcb8784..7b5417b 100644
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -4096,6 +4096,7 @@
     ctor public AssistContent();
     method public android.content.ClipData getClipData();
     method public android.net.Uri getWebUri();
+    method public boolean isAppProvidedIntent();
     method public void setClipData(android.content.ClipData);
     method public void setIntent(android.content.Intent);
     method public void setWebUri(android.net.Uri);
diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java
index 10d76f7..3d26ccd 100644
--- a/core/java/android/app/ActivityThread.java
+++ b/core/java/android/app/ActivityThread.java
@@ -2584,9 +2584,9 @@
                     intent.setFlags(intent.getFlags() & ~(Intent.FLAG_GRANT_WRITE_URI_PERMISSION
                             | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION));
                     intent.removeUnsafeExtras();
-                    content.setIntent(intent);
+                    content.setDefaultIntent(intent);
                 } else {
-                    content.setIntent(new Intent());
+                    content.setDefaultIntent(new Intent());
                 }
                 r.activity.onProvideAssistContent(content);
             }
diff --git a/core/java/android/app/AssistContent.java b/core/java/android/app/AssistContent.java
index 4cb89a8..d23e73d 100644
--- a/core/java/android/app/AssistContent.java
+++ b/core/java/android/app/AssistContent.java
@@ -31,6 +31,7 @@
  */
 @Deprecated
 public class AssistContent {
+    private boolean mIsAppProvidedIntent = false;
     private Intent mIntent;
     private ClipData mClipData;
     private Uri mUri;
@@ -55,12 +56,14 @@
     }
 
     /**
-     * Sets the Intent associated with the content, describing the current top-level context of
-     * the activity.  If this contains a reference to a piece of data related to the activity,
-     * be sure to set {@link Intent#FLAG_GRANT_READ_URI_PERMISSION} so the accessibility
-     * service can access it.
+     * @hide
+     * Called by {@link android.app.ActivityThread} to set the default Intent based on
+     * {@link android.app.Activity#getIntent Activity.getIntent}.
+     *
+     * <p>Automatically populates {@link #mUri} if that Intent is an {@link Intent#ACTION_VIEW}
+     * of a web (http or https scheme) URI.</p>
      */
-    public void setIntent(Intent intent) {
+    public void setDefaultIntent(Intent intent) {
         mIntent = intent;
         setWebUri(null);
         if (intent != null && Intent.ACTION_VIEW.equals(intent.getAction())) {
@@ -72,7 +75,19 @@
     }
 
     /**
-     * Return the current {@link #setIntent}, which you can modify in-place.
+     * Sets the Intent associated with the content, describing the current top-level context of
+     * the activity.  If this contains a reference to a piece of data related to the activity,
+     * be sure to set {@link Intent#FLAG_GRANT_READ_URI_PERMISSION} so the accessibility
+     * service can access it.
+     */
+    public void setIntent(Intent intent) {
+        mIsAppProvidedIntent = true;
+        mIntent = intent;
+    }
+
+    /**
+     * Returns the current {@link #setIntent} if one is set, else the default Intent obtained from
+     * {@link android.app.Activity#getIntent Activity.getIntent}. Can be modified in-place.
      * @hide
      */
     public Intent getIntent() {
@@ -80,6 +95,16 @@
     }
 
     /**
+     * Returns whether or not the current Intent was explicitly provided in
+     * {@link android.app.Activity#onProvideAssistContent Activity.onProvideAssistContent}. If not,
+     * the Intent was automatically set based on
+     * {@link android.app.Activity#getIntent Activity.getIntent}.
+     */
+    public boolean isAppProvidedIntent() {
+        return mIsAppProvidedIntent;
+    }
+
+    /**
      * Optional additional content items that are involved with
      * the current UI.  Access to this content will be granted to the assistant as if you
      * are sending it through an Intent with {@link Intent#FLAG_GRANT_READ_URI_PERMISSION}.
@@ -103,9 +128,6 @@
      * off the device into other environments to acesss the same data as is currently
      * being shown in the app; if the app does not have such a representation, it should
      * leave the null and only report the local intent and clip data.
-     *
-     * <p>This will be automatically populated for you from {@link #setIntent} if that Intent
-     * is an {@link Intent#ACTION_VIEW} of a web (http or https scheme) URI.</p>
      */
     public void setWebUri(Uri uri) {
         mUri = uri;
@@ -130,6 +152,7 @@
         if (in.readInt() != 0) {
             mUri = Uri.CREATOR.createFromParcel(in);
         }
+        mIsAppProvidedIntent = in.readInt() == 1;
     }
 
     /** @hide */
@@ -152,5 +175,6 @@
         } else {
             dest.writeInt(0);
         }
+        dest.writeInt(mIsAppProvidedIntent ? 1 : 0);
     }
 }
diff --git a/core/java/android/hardware/camera2/legacy/CameraDeviceUserShim.java b/core/java/android/hardware/camera2/legacy/CameraDeviceUserShim.java
index e963a0d..f5314da 100644
--- a/core/java/android/hardware/camera2/legacy/CameraDeviceUserShim.java
+++ b/core/java/android/hardware/camera2/legacy/CameraDeviceUserShim.java
@@ -88,15 +88,6 @@
         mSurfaceIdCounter = 0;
     }
 
-    private static int translateErrorsFromCamera1(int errorCode) {
-        switch (errorCode) {
-            case CameraBinderDecorator.EACCES:
-                return CameraBinderDecorator.PERMISSION_DENIED;
-            default:
-                return errorCode;
-        }
-    }
-
     /**
      * Create a separate looper/thread for the camera to run on; open the camera.
      *
@@ -140,7 +131,7 @@
             // Save the looper so that we can terminate this thread
             // after we are done with it.
             mLooper = Looper.myLooper();
-            mInitErrors = translateErrorsFromCamera1(mCamera.cameraInitUnspecified(mCameraId));
+            mInitErrors = mCamera.cameraInitUnspecified(mCameraId);
             mStartDone.open();
             Looper.loop();  // Blocks forever until #close is called.
         }
diff --git a/core/jni/android/graphics/Bitmap.cpp b/core/jni/android/graphics/Bitmap.cpp
index 832f92f..0d80a7f 100755
--- a/core/jni/android/graphics/Bitmap.cpp
+++ b/core/jni/android/graphics/Bitmap.cpp
@@ -27,6 +27,8 @@
 #include <sys/mman.h>
 #include <cutils/ashmem.h>
 
+#define DEBUG_PARCEL 0
+
 namespace android {
 
 class WrappedPixelRef : public SkPixelRef {
@@ -959,76 +961,83 @@
         }
     }
 
-    int fd = p->readFileDescriptor();
-    int dupFd = dup(fd);
-    if (dupFd < 0) {
+    // Read the bitmap blob.
+    size_t size = bitmap->getSize();
+    android::Parcel::ReadableBlob blob;
+    android::status_t status = p->readBlob(size, &blob);
+    if (status) {
         SkSafeUnref(ctable);
-        doThrowRE(env, "Could not dup parcel fd.");
+        doThrowRE(env, "Could not read bitmap blob.");
         return NULL;
     }
 
-    bool readOnlyMapping = !isMutable;
-    Bitmap* nativeBitmap = GraphicsJNI::mapAshmemPixelRef(env, bitmap.get(),
-        ctable, dupFd, readOnlyMapping);
-    SkSafeUnref(ctable);
-    if (!nativeBitmap) {
-        close(dupFd);
-        doThrowRE(env, "Could not allocate ashmem pixel ref.");
-        return NULL;
+    // Map the bitmap in place from the ashmem region if possible otherwise copy.
+    Bitmap* nativeBitmap;
+    if (blob.fd() >= 0 && (blob.isMutable() || !isMutable)) {
+#if DEBUG_PARCEL
+        ALOGD("Bitmap.createFromParcel: mapped contents of %s bitmap from %s blob "
+                "(fds %s)",
+                isMutable ? "mutable" : "immutable",
+                blob.isMutable() ? "mutable" : "immutable",
+                p->allowFds() ? "allowed" : "forbidden");
+#endif
+        // Dup the file descriptor so we can keep a reference to it after the Parcel
+        // is disposed.
+        int dupFd = dup(blob.fd());
+        if (dupFd < 0) {
+            blob.release();
+            SkSafeUnref(ctable);
+            doThrowRE(env, "Could not allocate dup blob fd.");
+            return NULL;
+        }
+
+        // Map the pixels in place and take ownership of the ashmem region.
+        nativeBitmap = GraphicsJNI::mapAshmemPixelRef(env, bitmap.get(),
+                ctable, dupFd, const_cast<void*>(blob.data()), !isMutable);
+        SkSafeUnref(ctable);
+        if (!nativeBitmap) {
+            close(dupFd);
+            blob.release();
+            doThrowRE(env, "Could not allocate ashmem pixel ref.");
+            return NULL;
+        }
+
+        // Clear the blob handle, don't release it.
+        blob.clear();
+    } else {
+#if DEBUG_PARCEL
+        if (blob.fd() >= 0) {
+            ALOGD("Bitmap.createFromParcel: copied contents of mutable bitmap "
+                    "from immutable blob (fds %s)",
+                    p->allowFds() ? "allowed" : "forbidden");
+        } else {
+            ALOGD("Bitmap.createFromParcel: copied contents from %s blob "
+                    "(fds %s)",
+                    blob.isMutable() ? "mutable" : "immutable",
+                    p->allowFds() ? "allowed" : "forbidden");
+        }
+#endif
+
+        // Copy the pixels into a new buffer.
+        nativeBitmap = GraphicsJNI::allocateJavaPixelRef(env, bitmap.get(), ctable);
+        SkSafeUnref(ctable);
+        if (!nativeBitmap) {
+            blob.release();
+            doThrowRE(env, "Could not allocate java pixel ref.");
+            return NULL;
+        }
+        bitmap->lockPixels();
+        memcpy(bitmap->getPixels(), blob.data(), size);
+        bitmap->unlockPixels();
+
+        // Release the blob handle.
+        blob.release();
     }
-    bitmap->pixelRef()->setImmutable();
 
     return GraphicsJNI::createBitmap(env, nativeBitmap,
             getPremulBitmapCreateFlags(isMutable), NULL, NULL, density);
 }
 
-class Ashmem {
-public:
-    Ashmem(size_t sz, bool removeWritePerm) : mSize(sz) {
-        int fd = -1;
-        void *addr = nullptr;
-
-        // Create new ashmem region with read/write priv
-        fd = ashmem_create_region("bitmap", sz);
-        if (fd < 0) {
-            goto error;
-        }
-        addr = mmap(nullptr, sz, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
-        if (addr == MAP_FAILED) {
-            goto error;
-        }
-        // If requested, remove the ability to make additional writeable to
-        // this memory.
-        if (removeWritePerm) {
-            if (ashmem_set_prot_region(fd, PROT_READ) < 0) {
-                goto error;
-            }
-        }
-        mFd = fd;
-        mPtr = addr;
-        return;
-error:
-        if (fd >= 0) {
-            close(fd);
-        }
-        if (addr) {
-            munmap(addr, sz);
-        }
-    }
-    ~Ashmem() {
-        if (mPtr) {
-            close(mFd);
-            munmap(mPtr, mSize);
-        }
-    }
-    void *getPtr() const { return mPtr; }
-    int getFd() const { return mFd; }
-private:
-    int mFd = -1;
-    int mSize;
-    void* mPtr = nullptr;
-};
-
 static jboolean Bitmap_writeToParcel(JNIEnv* env, jobject,
                                      jlong bitmapHandle,
                                      jboolean isMutable, jint density,
@@ -1064,26 +1073,51 @@
         }
     }
 
-    bool ashmemSrc = androidBitmap->getAshmemFd() >= 0;
-    if (ashmemSrc && !isMutable) {
-        p->writeDupFileDescriptor(androidBitmap->getAshmemFd());
-    } else {
-        Ashmem dstAshmem(bitmap.getSize(), !isMutable);
-        if (!dstAshmem.getPtr()) {
-            doThrowRE(env, "Could not allocate ashmem for new bitmap.");
+    // Transfer the underlying ashmem region if we have one and it's immutable.
+    android::status_t status;
+    int fd = androidBitmap->getAshmemFd();
+    if (fd >= 0 && !isMutable && p->allowFds()) {
+#if DEBUG_PARCEL
+        ALOGD("Bitmap.writeToParcel: transferring immutable bitmap's ashmem fd as "
+                "immutable blob (fds %s)",
+                p->allowFds() ? "allowed" : "forbidden");
+#endif
+
+        status = p->writeDupImmutableBlobFileDescriptor(fd);
+        if (status) {
+            doThrowRE(env, "Could not write bitmap blob file descriptor.");
             return JNI_FALSE;
         }
-
-        bitmap.lockPixels();
-        const void* pSrc = bitmap.getPixels();
-        if (pSrc == NULL) {
-            memset(dstAshmem.getPtr(), 0, bitmap.getSize());
-        } else {
-            memcpy(dstAshmem.getPtr(), pSrc, bitmap.getSize());
-        }
-        bitmap.unlockPixels();
-        p->writeDupFileDescriptor(dstAshmem.getFd());
+        return JNI_TRUE;
     }
+
+    // Copy the bitmap to a new blob.
+    bool mutableCopy = isMutable;
+#if DEBUG_PARCEL
+    ALOGD("Bitmap.writeToParcel: copying %s bitmap into new %s blob (fds %s)",
+            isMutable ? "mutable" : "immutable",
+            mutableCopy ? "mutable" : "immutable",
+            p->allowFds() ? "allowed" : "forbidden");
+#endif
+
+    size_t size = bitmap.getSize();
+    android::Parcel::WritableBlob blob;
+    status = p->writeBlob(size, mutableCopy, &blob);
+    if (status) {
+        doThrowRE(env, "Could not copy bitmap to parcel blob.");
+        return JNI_FALSE;
+    }
+
+    bitmap.lockPixels();
+    const void* pSrc =  bitmap.getPixels();
+    if (pSrc == NULL) {
+        memset(blob.data(), 0, size);
+    } else {
+        memcpy(blob.data(), pSrc, size);
+    }
+    bitmap.unlockPixels();
+
+    blob.release();
     return JNI_TRUE;
 }
 
diff --git a/core/jni/android/graphics/Graphics.cpp b/core/jni/android/graphics/Graphics.cpp
index ff22ef3..93259e7 100644
--- a/core/jni/android/graphics/Graphics.cpp
+++ b/core/jni/android/graphics/Graphics.cpp
@@ -623,20 +623,20 @@
 }
 
 android::Bitmap* GraphicsJNI::mapAshmemPixelRef(JNIEnv* env, SkBitmap* bitmap,
-                                                SkColorTable* ctable, int fd, bool readOnly) {
-    int flags;
-
+        SkColorTable* ctable, int fd, void* addr, bool readOnly) {
     const SkImageInfo& info = bitmap->info();
     if (info.fColorType == kUnknown_SkColorType) {
         doThrowIAE(env, "unknown bitmap configuration");
         return nullptr;
     }
 
-    // Create new ashmem region with read/write priv
-    flags = readOnly ? (PROT_READ) : (PROT_READ | PROT_WRITE);
-    void* addr = mmap(NULL, ashmem_get_size_region(fd), flags, MAP_SHARED, fd, 0);
-    if (addr == MAP_FAILED) {
-        return nullptr;
+    if (!addr) {
+        // Map existing ashmem region if not already mapped.
+        int flags = readOnly ? (PROT_READ) : (PROT_READ | PROT_WRITE);
+        addr = mmap(NULL, ashmem_get_size_region(fd), flags, MAP_SHARED, fd, 0);
+        if (addr == MAP_FAILED) {
+            return nullptr;
+        }
     }
 
     // we must respect the rowBytes value already set on the bitmap instead of
@@ -645,6 +645,9 @@
 
     android::Bitmap* wrapper = new android::Bitmap(addr, fd, info, rowBytes, ctable);
     wrapper->getSkBitmap(bitmap);
+    if (readOnly) {
+        bitmap->pixelRef()->setImmutable();
+    }
     // since we're already allocated, we lockPixels right away
     // HeapAllocator behaves this way too
     bitmap->lockPixels();
diff --git a/core/jni/android/graphics/GraphicsJNI.h b/core/jni/android/graphics/GraphicsJNI.h
index 1938e85..bcd834b 100644
--- a/core/jni/android/graphics/GraphicsJNI.h
+++ b/core/jni/android/graphics/GraphicsJNI.h
@@ -99,7 +99,7 @@
             SkColorTable* ctable);
 
     static android::Bitmap* mapAshmemPixelRef(JNIEnv* env, SkBitmap* bitmap,
-            SkColorTable* ctable, int fd, bool readOnly);
+            SkColorTable* ctable, int fd, void* addr, bool readOnly);
 
     /**
      * Given a bitmap we natively allocate a memory block to store the contents
diff --git a/core/jni/android_os_Parcel.cpp b/core/jni/android_os_Parcel.cpp
index a3a0551..2ee9283 100644
--- a/core/jni/android_os_Parcel.cpp
+++ b/core/jni/android_os_Parcel.cpp
@@ -211,7 +211,7 @@
     }
 
     android::Parcel::WritableBlob blob;
-    android::status_t err2 = parcel->writeBlob(length, &blob);
+    android::status_t err2 = parcel->writeBlob(length, false, &blob);
     if (err2 != NO_ERROR) {
         signalExceptionForError(env, clazz, err2);
         return;
diff --git a/docs/html/training/wearables/apps/always-on.jd b/docs/html/training/wearables/apps/always-on.jd
index 5bb6064..d384974 100644
--- a/docs/html/training/wearables/apps/always-on.jd
+++ b/docs/html/training/wearables/apps/always-on.jd
@@ -30,6 +30,11 @@
 so you should carefully consider that impact when adding this feature to your app.
 </p>
 
+<div class="video-wrapper-left">
+<iframe src="https://www.youtube.com/embed/7m6Z9d0fDaM" frameborder="0"
+allowfullscreen></iframe>
+</div>
+
 <p>Android Wear devices running Android version 5.1 or higher allow apps to remain in the
 foreground while saving battery power. Android Wear apps can control what’s displayed on the
 wearable device screen while the device is in a low-power ambient mode. Wear apps that run in both
diff --git a/graphics/java/android/graphics/drawable/VectorDrawable.java b/graphics/java/android/graphics/drawable/VectorDrawable.java
index b9f3f2a..5e205bd 100644
--- a/graphics/java/android/graphics/drawable/VectorDrawable.java
+++ b/graphics/java/android/graphics/drawable/VectorDrawable.java
@@ -311,6 +311,11 @@
     }
 
     @Override
+    public ColorFilter getColorFilter() {
+        return mColorFilter;
+    }
+
+    @Override
     public void setTintList(ColorStateList tint) {
         final VectorDrawableState state = mVectorState;
         if (state.mTint != tint) {
diff --git a/wifi/java/android/net/wifi/RttManager.java b/wifi/java/android/net/wifi/RttManager.java
index 7ced126..503e4a2 100644
--- a/wifi/java/android/net/wifi/RttManager.java
+++ b/wifi/java/android/net/wifi/RttManager.java
@@ -829,7 +829,8 @@
             Log.e(TAG, "Request " + index + ": two side RTT is not supported");
             return false;
         }  else if(params.bssid == null || params.bssid.isEmpty()) {
-            Log.e(TAG,"No BSSID is input");
+            Log.e(TAG,"No BSSID in params");
+            return false;
         } else if ( params.numberBurst != 0 ) {
             Log.e(TAG, "Request " + index + ": Illegal number of burst: " + params.numberBurst);
             return false;