Merge "Add Night display feature" into nyc-mr1-dev
diff --git a/core/java/android/hardware/camera2/CameraManager.java b/core/java/android/hardware/camera2/CameraManager.java
index 3917bfa..145b1d0 100644
--- a/core/java/android/hardware/camera2/CameraManager.java
+++ b/core/java/android/hardware/camera2/CameraManager.java
@@ -267,6 +267,10 @@
      * @param cameraId The unique identifier of the camera device to open
      * @param callback The callback for the camera. Must not be null.
      * @param handler  The handler to invoke the callback on. Must not be null.
+     * @param uid      The UID of the application actually opening the camera.
+     *                 Must be USE_CALLING_UID unless the caller is a service
+     *                 that is trusted to open the device on behalf of an
+     *                 application and to forward the real UID.
      *
      * @throws CameraAccessException if the camera is disabled by device policy,
      * too many camera devices are already open, or the cameraId does not match
@@ -281,7 +285,7 @@
      * @see android.app.admin.DevicePolicyManager#setCameraDisabled
      */
     private CameraDevice openCameraDeviceUserAsync(String cameraId,
-            CameraDevice.StateCallback callback, Handler handler)
+            CameraDevice.StateCallback callback, Handler handler, final int uid)
             throws CameraAccessException {
         CameraCharacteristics characteristics = getCameraCharacteristics(cameraId);
         CameraDevice device = null;
@@ -317,7 +321,7 @@
                             "Camera service is currently unavailable");
                     }
                     cameraUser = cameraService.connectDevice(callbacks, id,
-                            mContext.getOpPackageName(), USE_CALLING_UID);
+                            mContext.getOpPackageName(), uid);
                 } else {
                     // Use legacy camera implementation for HAL1 devices
                     Log.i(TAG, "Using legacy camera HAL.");
@@ -434,6 +438,29 @@
             @NonNull final CameraDevice.StateCallback callback, @Nullable Handler handler)
             throws CameraAccessException {
 
+        openCameraForUid(cameraId, callback, handler, USE_CALLING_UID);
+    }
+
+    /**
+     * Open a connection to a camera with the given ID, on behalf of another application
+     * specified by clientUid.
+     *
+     * <p>The behavior of this method matches that of {@link #openCamera}, except that it allows
+     * the caller to specify the UID to use for permission/etc verification. This can only be
+     * done by services trusted by the camera subsystem to act on behalf of applications and
+     * to forward the real UID.</p>
+     *
+     * @param clientUid
+     *             The UID of the application on whose behalf the camera is being opened.
+     *             Must be USE_CALLING_UID unless the caller is a trusted service.
+     *
+     * @hide
+     */
+    public void openCameraForUid(@NonNull String cameraId,
+            @NonNull final CameraDevice.StateCallback callback, @Nullable Handler handler,
+            int clientUid)
+            throws CameraAccessException {
+
         if (cameraId == null) {
             throw new IllegalArgumentException("cameraId was null");
         } else if (callback == null) {
@@ -447,7 +474,7 @@
             }
         }
 
-        openCameraDeviceUserAsync(cameraId, callback, handler);
+        openCameraDeviceUserAsync(cameraId, callback, handler, clientUid);
     }
 
     /**
diff --git a/core/res/res/layout-watch/preference_material.xml b/core/res/res/layout-watch/preference_material.xml
index 5da64fc..ad217db 100644
--- a/core/res/res/layout-watch/preference_material.xml
+++ b/core/res/res/layout-watch/preference_material.xml
@@ -29,34 +29,42 @@
 
     <LinearLayout
         android:id="@+id/icon_frame"
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        android:layout_marginStart="-4dp"
-        android:minWidth="32dp"
-        android:gravity="start|center_vertical"
+        android:layout_width="40dp"
+        android:layout_height="40dp"
+        android:gravity="center"
         android:orientation="horizontal"
-        android:paddingEnd="8dp"
-        android:paddingTop="4dp"
-        android:paddingBottom="4dp">
+        android:layout_marginEnd="8dp"
+        android:layout_marginTop="8dp"
+        android:layout_marginBottom="8dp">
         <com.android.internal.widget.PreferenceImageView
             android:id="@+id/icon"
             android:layout_width="wrap_content"
             android:layout_height="wrap_content"
-            android:maxWidth="24dp"
-            android:maxHeight="24dp" />
+            android:maxWidth="40dp"
+            android:maxHeight="40dp" />
     </LinearLayout>
 
+    <!-- Preference should place its actual preference widget here. -->
+    <LinearLayout android:id="@+id/widget_frame"
+        android:layout_width="40dp"
+        android:layout_height="40dp"
+        android:gravity="center"
+        android:orientation="horizontal"
+        android:layout_marginEnd="8dp"
+        android:layout_marginTop="8dp"
+        android:layout_marginBottom="8dp" />
+
     <RelativeLayout
         android:layout_width="wrap_content"
         android:layout_height="wrap_content"
         android:layout_weight="1"
-        android:paddingTop="16dp"
-        android:paddingBottom="16dp">
+        android:layout_marginTop="8dp"
+        android:layout_marginBottom="8dp">
 
         <TextView android:id="@+id/title"
             android:layout_width="wrap_content"
             android:layout_height="wrap_content"
-            android:maxLines="2"
+            android:maxLines="3"
             android:textAppearance="?attr/textAppearanceListItem"
             android:ellipsize="end" />
 
@@ -70,13 +78,4 @@
             android:maxLines="10" />
 
     </RelativeLayout>
-
-    <!-- Preference should place its actual preference widget here. -->
-    <LinearLayout android:id="@+id/widget_frame"
-        android:layout_width="wrap_content"
-        android:layout_height="match_parent"
-        android:gravity="end|center_vertical"
-        android:paddingStart="4dp"
-        android:orientation="vertical" />
-
 </LinearLayout>
diff --git a/core/res/res/values-round-watch/dimens_material.xml b/core/res/res/values-round-watch/dimens_material.xml
index a417d19..db1f1f3 100644
--- a/core/res/res/values-round-watch/dimens_material.xml
+++ b/core/res/res/values-round-watch/dimens_material.xml
@@ -14,10 +14,10 @@
      limitations under the License.
 -->
 <resources>
-    <dimen name="dialog_padding_material">32dp</dimen>
-    <dimen name="preference_fragment_padding_vertical_material">22dp</dimen>
+    <dimen name="dialog_padding_material">@dimen/screen_percentage_15</dimen>
+    <dimen name="preference_fragment_padding_vertical_material">@dimen/screen_percentage_15</dimen>
 
-    <dimen name="list_item_padding_horizontal_material">32dp</dimen>
-    <dimen name="list_item_padding_start_material">40dp</dimen>
-    <dimen name="list_item_padding_end_material">24dp</dimen>
+    <dimen name="list_item_padding_horizontal_material">@dimen/screen_percentage_15</dimen>
+    <dimen name="list_item_padding_start_material">@dimen/screen_percentage_15</dimen>
+    <dimen name="list_item_padding_end_material">@dimen/screen_percentage_10</dimen>
 </resources>
diff --git a/core/res/res/values-w194dp/dimens_material.xml b/core/res/res/values-w194dp/dimens_material.xml
new file mode 100644
index 0000000..220c4b0
--- /dev/null
+++ b/core/res/res/values-w194dp/dimens_material.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2016 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.
+-->
+<resources>
+    <dimen name="screen_percentage_05">9.7dp</dimen>
+    <dimen name="screen_percentage_10">19.4dp</dimen>
+    <dimen name="screen_percentage_15">29.1dp</dimen>
+</resources>
diff --git a/core/res/res/values-w205dp/dimens_material.xml b/core/res/res/values-w205dp/dimens_material.xml
new file mode 100644
index 0000000..94907ee
--- /dev/null
+++ b/core/res/res/values-w205dp/dimens_material.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2016 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.
+-->
+<resources>
+    <dimen name="screen_percentage_05">10.25dp</dimen>
+    <dimen name="screen_percentage_10">20.5dp</dimen>
+    <dimen name="screen_percentage_15">30.75dp</dimen>
+</resources>
diff --git a/core/res/res/values-w213dp/dimens_material.xml b/core/res/res/values-w213dp/dimens_material.xml
new file mode 100644
index 0000000..8a4e3a0
--- /dev/null
+++ b/core/res/res/values-w213dp/dimens_material.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2016 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.
+-->
+<resources>
+    <dimen name="screen_percentage_05">10.65dp</dimen>
+    <dimen name="screen_percentage_10">21.3dp</dimen>
+    <dimen name="screen_percentage_15">31.95dp</dimen>
+</resources>
diff --git a/core/res/res/values-w228dp/dimens_material.xml b/core/res/res/values-w228dp/dimens_material.xml
new file mode 100644
index 0000000..a200975
--- /dev/null
+++ b/core/res/res/values-w228dp/dimens_material.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2016 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.
+-->
+<resources>
+    <dimen name="screen_percentage_05">11.4dp</dimen>
+    <dimen name="screen_percentage_10">22.8dp</dimen>
+    <dimen name="screen_percentage_15">34.2dp</dimen>
+</resources>
diff --git a/core/res/res/values-w240dp/dimens_material.xml b/core/res/res/values-w240dp/dimens_material.xml
new file mode 100644
index 0000000..a4b58fa
--- /dev/null
+++ b/core/res/res/values-w240dp/dimens_material.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2016 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.
+-->
+<resources>
+    <dimen name="screen_percentage_05">12dp</dimen>
+    <dimen name="screen_percentage_10">24dp</dimen>
+    <dimen name="screen_percentage_15">36dp</dimen>
+</resources>
diff --git a/media/java/android/media/AudioManager.java b/media/java/android/media/AudioManager.java
index 4bdc70e..f19a262 100644
--- a/media/java/android/media/AudioManager.java
+++ b/media/java/android/media/AudioManager.java
@@ -2744,6 +2744,7 @@
      * to be notified.
      * Use {@link AudioManager#getActiveRecordingConfigurations()} to query the current
      * configuration.
+     * @see AudioRecordingConfiguration
      */
     public static abstract class AudioRecordingCallback {
         /**
@@ -2850,6 +2851,7 @@
      * Returns the current active audio recording configurations of the device.
      * @return a non-null list of recording configurations. An empty list indicates there is
      *     no recording active when queried.
+     * @see AudioRecordingConfiguration
      */
     public @NonNull List<AudioRecordingConfiguration> getActiveRecordingConfigurations() {
         final IAudioService service = getService();
diff --git a/media/java/android/media/AudioRecordingConfiguration.java b/media/java/android/media/AudioRecordingConfiguration.java
index 5935166..354339c 100644
--- a/media/java/android/media/AudioRecordingConfiguration.java
+++ b/media/java/android/media/AudioRecordingConfiguration.java
@@ -28,8 +28,18 @@
 
 /**
  * The AudioRecordingConfiguration class collects the information describing an audio recording
- * session. This information is returned through the
- * {@link AudioManager#getActiveRecordingConfigurations()} method.
+ * session.
+ * <p>Direct polling (see {@link AudioManager#getActiveRecordingConfigurations()}) or callback
+ * (see {@link AudioManager#registerAudioRecordingCallback(android.media.AudioManager.AudioRecordingCallback, android.os.Handler)}
+ * methods are ways to receive information about the current recording configuration of the device.
+ * <p>An audio recording configuration contains information about the recording format as used by
+ * the application ({@link #getClientFormat()}, as well as the recording format actually used by
+ * the device ({@link #getFormat()}). The two recording formats may, for instance, be at different
+ * sampling rates due to hardware limitations (e.g. application recording at 44.1kHz whereas the
+ * device always records at 48kHz, and the Android framework resamples for the application).
+ * <p>The configuration also contains the use case for which audio is recorded
+ * ({@link #getClientAudioSource()}), enabling the ability to distinguish between different
+ * activities such as ongoing voice recognition or camcorder recording.
  *
  */
 public final class AudioRecordingConfiguration implements Parcelable {
@@ -198,4 +208,4 @@
                 && (mClientFormat.equals(that.mClientFormat))
                 && (mDeviceFormat.equals(that.mDeviceFormat)));
     }
-}
\ No newline at end of file
+}
diff --git a/packages/ExternalStorageProvider/src/com/android/externalstorage/ExternalStorageProvider.java b/packages/ExternalStorageProvider/src/com/android/externalstorage/ExternalStorageProvider.java
index 62f33bf..a3070bd 100644
--- a/packages/ExternalStorageProvider/src/com/android/externalstorage/ExternalStorageProvider.java
+++ b/packages/ExternalStorageProvider/src/com/android/externalstorage/ExternalStorageProvider.java
@@ -492,23 +492,26 @@
             throw new IllegalStateException("Failed to delete " + file);
         }
 
-        final ContentResolver resolver = getContext().getContentResolver();
-        final Uri externalUri = MediaStore.Files.getContentUri("external");
+        final File visibleFile = getFileForDocId(docId, true);
+        if (visibleFile != null) {
+            final ContentResolver resolver = getContext().getContentResolver();
+            final Uri externalUri = MediaStore.Files.getContentUri("external");
 
-        // Remove media store entries for any files inside this directory, using
-        // path prefix match. Logic borrowed from MtpDatabase.
-        if (isDirectory) {
-            final String path = file.getAbsolutePath() + "/";
+            // Remove media store entries for any files inside this directory, using
+            // path prefix match. Logic borrowed from MtpDatabase.
+            if (isDirectory) {
+                final String path = visibleFile.getAbsolutePath() + "/";
+                resolver.delete(externalUri,
+                        "_data LIKE ?1 AND lower(substr(_data,1,?2))=lower(?3)",
+                        new String[] { path + "%", Integer.toString(path.length()), path });
+            }
+
+            // Remove media store entry for this exact file.
+            final String path = visibleFile.getAbsolutePath();
             resolver.delete(externalUri,
-                    "_data LIKE ?1 AND lower(substr(_data,1,?2))=lower(?3)",
-                    new String[] { path + "%", Integer.toString(path.length()), path });
+                    "_data LIKE ?1 AND lower(_data)=lower(?2)",
+                    new String[] { path, path });
         }
-
-        // Remove media store entry for this exact file.
-        final String path = file.getAbsolutePath();
-        resolver.delete(externalUri,
-                "_data LIKE ?1 AND lower(_data)=lower(?2)",
-                new String[] { path, path });
     }
 
     @Override