Merge "MediaSync: fix message delay based on play time for pending audio frames."
diff --git a/api/current.txt b/api/current.txt
index d29bd78..61e9186 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -14924,6 +14924,7 @@
 
   public class AudioRecord {
     ctor public AudioRecord(int, int, int, int, int) throws java.lang.IllegalArgumentException;
+    method public void addOnAudioRecordRoutingListener(android.media.OnAudioRecordRoutingListener, android.os.Handler);
     method public int getAudioFormat();
     method public int getAudioSessionId();
     method public int getAudioSource();
@@ -14933,7 +14934,9 @@
     method public int getNativeFrameCount() throws java.lang.IllegalStateException;
     method public int getNotificationMarkerPosition();
     method public int getPositionNotificationPeriod();
+    method public android.media.AudioDeviceInfo getPreferredInputDevice();
     method public int getRecordingState();
+    method public android.media.AudioDeviceInfo getRoutedDevice();
     method public int getSampleRate();
     method public int getState();
     method public int read(byte[], int, int);
@@ -14944,8 +14947,10 @@
     method public int read(java.nio.ByteBuffer, int);
     method public int read(java.nio.ByteBuffer, int, int);
     method public void release();
+    method public void removeOnAudioRecordRoutingListener(android.media.OnAudioRecordRoutingListener);
     method public int setNotificationMarkerPosition(int);
     method public int setPositionNotificationPeriod(int);
+    method public boolean setPreferredInputDevice(android.media.AudioDeviceInfo);
     method public void setRecordPositionUpdateListener(android.media.AudioRecord.OnRecordPositionUpdateListener);
     method public void setRecordPositionUpdateListener(android.media.AudioRecord.OnRecordPositionUpdateListener, android.os.Handler);
     method public void startRecording() throws java.lang.IllegalStateException;
@@ -14986,6 +14991,7 @@
     ctor public AudioTrack(int, int, int, int, int, int) throws java.lang.IllegalArgumentException;
     ctor public AudioTrack(int, int, int, int, int, int, int) throws java.lang.IllegalArgumentException;
     ctor public AudioTrack(android.media.AudioAttributes, android.media.AudioFormat, int, int, int) throws java.lang.IllegalArgumentException;
+    method public void addOnAudioTrackRoutingListener(android.media.OnAudioTrackRoutingListener, android.os.Handler);
     method public int attachAuxEffect(int);
     method public void flush();
     method public int getAudioFormat();
@@ -15004,6 +15010,7 @@
     method public android.media.PlaybackSettings getPlaybackSettings();
     method public int getPositionNotificationPeriod();
     method public android.media.AudioDeviceInfo getPreferredOutputDevice();
+    method public android.media.AudioDeviceInfo getRoutedDevice();
     method public int getSampleRate();
     method public int getState();
     method public int getStreamType();
@@ -15012,6 +15019,7 @@
     method public void play() throws java.lang.IllegalStateException;
     method public void release();
     method public int reloadStaticData();
+    method public void removeOnAudioTrackRoutingListener(android.media.OnAudioTrackRoutingListener);
     method public int setAuxEffectSendLevel(float);
     method public int setLoopPoints(int, int, int);
     method public int setNotificationMarkerPosition(int);
@@ -16425,6 +16433,14 @@
     field public static final int AUDIO_STRETCH_MODE_VOICE = 1; // 0x1
   }
 
+  public abstract interface OnAudioRecordRoutingListener {
+    method public abstract void onAudioRecordRouting(android.media.AudioRecord);
+  }
+
+  public abstract interface OnAudioTrackRoutingListener {
+    method public abstract void onAudioTrackRouting(android.media.AudioTrack);
+  }
+
   public final class Rating implements android.os.Parcelable {
     method public int describeContents();
     method public float getPercentRating();
@@ -30102,8 +30118,8 @@
     field public static final int STATE_DISCONNECTING = 10; // 0xa
     field public static final int STATE_HOLDING = 3; // 0x3
     field public static final int STATE_NEW = 0; // 0x0
-    field public static final int STATE_PRE_DIAL_WAIT = 8; // 0x8
     field public static final int STATE_RINGING = 2; // 0x2
+    field public static final int STATE_SELECT_PHONE_ACCOUNT = 8; // 0x8
   }
 
   public static abstract class Call.Callback {
@@ -30163,20 +30179,6 @@
     field public static final int CONFERENCE = 1; // 0x1
   }
 
-  public final class CallState {
-    method public static java.lang.String toString(int);
-    field public static final int ABORTED = 8; // 0x8
-    field public static final int ACTIVE = 5; // 0x5
-    field public static final int CONNECTING = 1; // 0x1
-    field public static final int DIALING = 3; // 0x3
-    field public static final int DISCONNECTED = 7; // 0x7
-    field public static final int DISCONNECTING = 9; // 0x9
-    field public static final int NEW = 0; // 0x0
-    field public static final int ON_HOLD = 6; // 0x6
-    field public static final int PRE_DIAL_WAIT = 2; // 0x2
-    field public static final int RINGING = 4; // 0x4
-  }
-
   public final class CameraCapabilities implements android.os.Parcelable {
     ctor public CameraCapabilities(int, int);
     method public int describeContents();
@@ -30593,6 +30595,7 @@
     method public boolean handleMmi(java.lang.String, android.telecom.PhoneAccountHandle);
     method public boolean isInCall();
     method public boolean isVoiceMailNumber(android.telecom.PhoneAccountHandle, java.lang.String);
+    method public void placeCall(android.net.Uri, android.os.Bundle);
     method public void registerPhoneAccount(android.telecom.PhoneAccount);
     method public void showInCallScreen(boolean);
     method public void silenceRinger();
@@ -30657,6 +30660,7 @@
     method public android.os.Bundle getConfigForSubId(int);
     method public void reloadCarrierConfigForSubId(int);
     field public static final java.lang.String ACTION_CARRIER_CONFIG_CHANGED = "android.telephony.action.CARRIER_CONFIG_CHANGED";
+    field public static final java.lang.String BOOL_APN_EXPAND = "bool_apn_expand";
     field public static final java.lang.String BOOL_CARRIER_VOLTE_AVAILABLE = "bool_carrier_volte_available";
     field public static final java.lang.String BOOL_CARRIER_VOLTE_PROVISIONED = "bool_carrier_volte_provisioned";
     field public static final java.lang.String BOOL_CARRIER_VOLTE_TTY_SUPPORTED = "bool_carrier_volte_tty_supported";
diff --git a/api/system-current.txt b/api/system-current.txt
index d6242ae..e9f2f9a 100644
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -16135,6 +16135,7 @@
   public class AudioRecord {
     ctor public AudioRecord(int, int, int, int, int) throws java.lang.IllegalArgumentException;
     ctor public AudioRecord(android.media.AudioAttributes, android.media.AudioFormat, int, int) throws java.lang.IllegalArgumentException;
+    method public void addOnAudioRecordRoutingListener(android.media.OnAudioRecordRoutingListener, android.os.Handler);
     method public int getAudioFormat();
     method public int getAudioSessionId();
     method public int getAudioSource();
@@ -16144,7 +16145,9 @@
     method public int getNativeFrameCount() throws java.lang.IllegalStateException;
     method public int getNotificationMarkerPosition();
     method public int getPositionNotificationPeriod();
+    method public android.media.AudioDeviceInfo getPreferredInputDevice();
     method public int getRecordingState();
+    method public android.media.AudioDeviceInfo getRoutedDevice();
     method public int getSampleRate();
     method public int getState();
     method public int read(byte[], int, int);
@@ -16155,8 +16158,10 @@
     method public int read(java.nio.ByteBuffer, int);
     method public int read(java.nio.ByteBuffer, int, int);
     method public void release();
+    method public void removeOnAudioRecordRoutingListener(android.media.OnAudioRecordRoutingListener);
     method public int setNotificationMarkerPosition(int);
     method public int setPositionNotificationPeriod(int);
+    method public boolean setPreferredInputDevice(android.media.AudioDeviceInfo);
     method public void setRecordPositionUpdateListener(android.media.AudioRecord.OnRecordPositionUpdateListener);
     method public void setRecordPositionUpdateListener(android.media.AudioRecord.OnRecordPositionUpdateListener, android.os.Handler);
     method public void startRecording() throws java.lang.IllegalStateException;
@@ -16199,6 +16204,7 @@
     ctor public AudioTrack(int, int, int, int, int, int) throws java.lang.IllegalArgumentException;
     ctor public AudioTrack(int, int, int, int, int, int, int) throws java.lang.IllegalArgumentException;
     ctor public AudioTrack(android.media.AudioAttributes, android.media.AudioFormat, int, int, int) throws java.lang.IllegalArgumentException;
+    method public void addOnAudioTrackRoutingListener(android.media.OnAudioTrackRoutingListener, android.os.Handler);
     method public int attachAuxEffect(int);
     method public void flush();
     method public int getAudioFormat();
@@ -16217,6 +16223,7 @@
     method public android.media.PlaybackSettings getPlaybackSettings();
     method public int getPositionNotificationPeriod();
     method public android.media.AudioDeviceInfo getPreferredOutputDevice();
+    method public android.media.AudioDeviceInfo getRoutedDevice();
     method public int getSampleRate();
     method public int getState();
     method public int getStreamType();
@@ -16225,6 +16232,7 @@
     method public void play() throws java.lang.IllegalStateException;
     method public void release();
     method public int reloadStaticData();
+    method public void removeOnAudioTrackRoutingListener(android.media.OnAudioTrackRoutingListener);
     method public int setAuxEffectSendLevel(float);
     method public int setLoopPoints(int, int, int);
     method public int setNotificationMarkerPosition(int);
@@ -17641,6 +17649,14 @@
     field public static final int AUDIO_STRETCH_MODE_VOICE = 1; // 0x1
   }
 
+  public abstract interface OnAudioRecordRoutingListener {
+    method public abstract void onAudioRecordRouting(android.media.AudioRecord);
+  }
+
+  public abstract interface OnAudioTrackRoutingListener {
+    method public abstract void onAudioTrackRouting(android.media.AudioTrack);
+  }
+
   public final class Rating implements android.os.Parcelable {
     method public int describeContents();
     method public float getPercentRating();
@@ -32208,8 +32224,9 @@
     field public static final int STATE_DISCONNECTING = 10; // 0xa
     field public static final int STATE_HOLDING = 3; // 0x3
     field public static final int STATE_NEW = 0; // 0x0
-    field public static final int STATE_PRE_DIAL_WAIT = 8; // 0x8
+    field public static final deprecated int STATE_PRE_DIAL_WAIT = 8; // 0x8
     field public static final int STATE_RINGING = 2; // 0x2
+    field public static final int STATE_SELECT_PHONE_ACCOUNT = 8; // 0x8
   }
 
   public static abstract class Call.Callback {
@@ -32273,20 +32290,6 @@
     field public static final int CONFERENCE = 1; // 0x1
   }
 
-  public final class CallState {
-    method public static java.lang.String toString(int);
-    field public static final int ABORTED = 8; // 0x8
-    field public static final int ACTIVE = 5; // 0x5
-    field public static final int CONNECTING = 1; // 0x1
-    field public static final int DIALING = 3; // 0x3
-    field public static final int DISCONNECTED = 7; // 0x7
-    field public static final int DISCONNECTING = 9; // 0x9
-    field public static final int NEW = 0; // 0x0
-    field public static final int ON_HOLD = 6; // 0x6
-    field public static final int PRE_DIAL_WAIT = 2; // 0x2
-    field public static final int RINGING = 4; // 0x4
-  }
-
   public final class CameraCapabilities implements android.os.Parcelable {
     ctor public CameraCapabilities(int, int);
     method public int describeContents();
@@ -32742,6 +32745,7 @@
     method public boolean isRinging();
     method public boolean isTtySupported();
     method public boolean isVoiceMailNumber(android.telecom.PhoneAccountHandle, java.lang.String);
+    method public void placeCall(android.net.Uri, android.os.Bundle);
     method public void registerPhoneAccount(android.telecom.PhoneAccount);
     method public void showInCallScreen(boolean);
     method public void silenceRinger();
@@ -32811,6 +32815,7 @@
     method public void reloadCarrierConfigForSubId(int);
     method public void updateConfigForPhoneId(int, java.lang.String);
     field public static final java.lang.String ACTION_CARRIER_CONFIG_CHANGED = "android.telephony.action.CARRIER_CONFIG_CHANGED";
+    field public static final java.lang.String BOOL_APN_EXPAND = "bool_apn_expand";
     field public static final java.lang.String BOOL_CARRIER_VOLTE_AVAILABLE = "bool_carrier_volte_available";
     field public static final java.lang.String BOOL_CARRIER_VOLTE_PROVISIONED = "bool_carrier_volte_provisioned";
     field public static final java.lang.String BOOL_CARRIER_VOLTE_TTY_SUPPORTED = "bool_carrier_volte_tty_supported";
diff --git a/core/java/android/annotation/RequiresPermission.java b/core/java/android/annotation/RequiresPermission.java
new file mode 100644
index 0000000..4aed5c1
--- /dev/null
+++ b/core/java/android/annotation/RequiresPermission.java
@@ -0,0 +1,104 @@
+/*
+ * Copyright (C) 2015 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 android.annotation;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.Target;
+
+import static java.lang.annotation.ElementType.ANNOTATION_TYPE;
+import static java.lang.annotation.ElementType.CONSTRUCTOR;
+import static java.lang.annotation.ElementType.FIELD;
+import static java.lang.annotation.ElementType.METHOD;
+import static java.lang.annotation.RetentionPolicy.SOURCE;
+
+/**
+ * Denotes that the annotated element requires (or may require) one or more permissions.
+ * <p/>
+ * Example of requiring a single permission:
+ * <pre>{@code
+ *   &#64;RequiresPermission(Manifest.permission.SET_WALLPAPER)
+ *   public abstract void setWallpaper(Bitmap bitmap) throws IOException;
+ *
+ *   &#64;RequiresPermission(ACCESS_COARSE_LOCATION)
+ *   public abstract Location getLastKnownLocation(String provider);
+ * }</pre>
+ * Example of requiring at least one permission from a set:
+ * <pre>{@code
+ *   &#64;RequiresPermission(anyOf = {ACCESS_COARSE_LOCATION, ACCESS_FINE_LOCATION})
+ *   public abstract Location getLastKnownLocation(String provider);
+ * }</pre>
+ * Example of requiring multiple permissions:
+ * <pre>{@code
+ *   &#64;RequiresPermission(allOf = {ACCESS_COARSE_LOCATION, ACCESS_FINE_LOCATION})
+ *   public abstract Location getLastKnownLocation(String provider);
+ * }</pre>
+ * Example of requiring separate read and write permissions for a content provider:
+ * <pre>{@code
+ *   &#64;RequiresPermission.Read(&#64;RequiresPermission(READ_HISTORY_BOOKMARKS))
+ *   &#64;RequiresPermission.Write(&#64;RequiresPermission(WRITE_HISTORY_BOOKMARKS))
+ *   public static final Uri BOOKMARKS_URI = Uri.parse("content://browser/bookmarks");
+ * }</pre>
+ *
+ * @hide
+ */
+@Retention(SOURCE)
+@Target({ANNOTATION_TYPE,METHOD,CONSTRUCTOR,FIELD})
+public @interface RequiresPermission {
+    /**
+     * The name of the permission that is required, if precisely one permission
+     * is required. If more than one permission is required, specify either
+     * {@link #allOf()} or {@link #anyOf()} instead.
+     * <p>
+     * If specified, {@link #anyOf()} and {@link #allOf()} must both be null.
+     */
+    String value() default "";
+
+    /**
+     * Specifies a list of permission names that are all required.
+     * <p>
+     * If specified, {@link #anyOf()} and {@link #value()} must both be null.
+     */
+    String[] allOf() default {};
+
+    /**
+     * Specifies a list of permission names where at least one is required
+     * <p>
+     * If specified, {@link #allOf()} and {@link #value()} must both be null.
+     */
+    String[] anyOf() default {};
+
+    /**
+     * If true, the permission may not be required in all cases (e.g. it may only be
+     * enforced on certain platforms, or for certain call parameters, etc.
+     */
+    boolean conditional() default false;
+
+    /**
+     * Specifies that the given permission is required for read operations
+     */
+    @Target(FIELD)
+    @interface Read {
+        RequiresPermission value();
+    }
+
+    /**
+     * Specifies that the given permission is required for write operations
+     */
+    @Target(FIELD)
+    @interface Write {
+        RequiresPermission value();
+    }
+}
diff --git a/core/java/android/app/ActivityManagerNative.java b/core/java/android/app/ActivityManagerNative.java
index 7f062d9..b11c509 100644
--- a/core/java/android/app/ActivityManagerNative.java
+++ b/core/java/android/app/ActivityManagerNative.java
@@ -2513,6 +2513,14 @@
             return true;
         }
 
+        case UPDATE_DEVICE_OWNER_TRANSACTION: {
+            data.enforceInterface(IActivityManager.descriptor);
+            String packageName = data.readString();
+            updateDeviceOwner(packageName);
+            reply.writeNoException();
+            return true;
+        }
+
         case GET_PACKAGE_PROCESS_STATE_TRANSACTION: {
             data.enforceInterface(IActivityManager.descriptor);
             String pkg = data.readString();
@@ -5801,6 +5809,18 @@
     }
 
     @Override
+    public void updateDeviceOwner(String packageName) throws RemoteException {
+        Parcel data = Parcel.obtain();
+        Parcel reply = Parcel.obtain();
+        data.writeInterfaceToken(IActivityManager.descriptor);
+        data.writeString(packageName);
+        mRemote.transact(UPDATE_DEVICE_OWNER_TRANSACTION, data, reply, 0);
+        reply.readException();
+        data.recycle();
+        reply.recycle();
+    }
+
+    @Override
     public int getPackageProcessState(String packageName) throws RemoteException {
         Parcel data = Parcel.obtain();
         Parcel reply = Parcel.obtain();
diff --git a/core/java/android/app/IActivityManager.java b/core/java/android/app/IActivityManager.java
index 7e03faa..00558fe 100644
--- a/core/java/android/app/IActivityManager.java
+++ b/core/java/android/app/IActivityManager.java
@@ -495,6 +495,7 @@
     public void setVoiceKeepAwake(IVoiceInteractionSession session, boolean keepAwake)
             throws RemoteException;
     public void updateLockTaskPackages(int userId, String[] packages) throws RemoteException;
+    public void updateDeviceOwner(String packageName) throws RemoteException;
 
     public int getPackageProcessState(String packageName) throws RemoteException;
 
@@ -837,4 +838,5 @@
     int NOTE_ALARM_FINISH_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+292;
     int GET_PACKAGE_PROCESS_STATE_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+293;
     int SHOW_LOCK_TASK_ESCAPE_MESSAGE_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+294;
+    int UPDATE_DEVICE_OWNER_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+295;
 }
diff --git a/core/java/android/bluetooth/BluetoothAdapter.java b/core/java/android/bluetooth/BluetoothAdapter.java
index 2418e82..79e560f 100644
--- a/core/java/android/bluetooth/BluetoothAdapter.java
+++ b/core/java/android/bluetooth/BluetoothAdapter.java
@@ -792,7 +792,6 @@
                 //          mService is null, handle that case
             }
         } catch (RemoteException e) {Log.e(TAG, "", e);}
-        if (DBG) Log.d(TAG, "" + hashCode() + ": getState() :  mService = null. Returning STATE_OFF");
         return STATE_OFF;
     }
 
diff --git a/core/java/android/content/ContentProvider.java b/core/java/android/content/ContentProvider.java
index 393cf8e..fd65d56 100644
--- a/core/java/android/content/ContentProvider.java
+++ b/core/java/android/content/ContentProvider.java
@@ -26,6 +26,7 @@
 import android.content.res.AssetFileDescriptor;
 import android.content.res.Configuration;
 import android.database.Cursor;
+import android.database.MatrixCursor;
 import android.database.SQLException;
 import android.net.Uri;
 import android.os.AsyncTask;
@@ -204,8 +205,13 @@
             validateIncomingUri(uri);
             uri = getUriWithoutUserId(uri);
             if (enforceReadPermission(callingPkg, uri, null) != AppOpsManager.MODE_ALLOWED) {
-                return rejectQuery(uri, projection, selection, selectionArgs, sortOrder,
-                        CancellationSignal.fromTransport(cancellationSignal));
+                // The caller has no access to the data, so return an empty cursor with
+                // the columns in the requested order. The caller may ask for an invalid
+                // column and we would not catch that but this is not a problem in practice.
+                // We do not call ContentProvider#query with a modified where clause since
+                // the implementation is not guaranteed to be backed by a SQL database, hence
+                // it may not handle properly the tautology where clause we would have created.
+                return new MatrixCursor(projection, 0);
             }
             final String original = setCallingPackage(callingPkg);
             try {
@@ -817,31 +823,6 @@
     }
 
     /**
-     * @hide
-     * Implementation when a caller has performed a query on the content
-     * provider, but that call has been rejected for the operation given
-     * to {@link #setAppOps(int, int)}.  The default implementation
-     * rewrites the <var>selection</var> argument to include a condition
-     * that is never true (so will always result in an empty cursor)
-     * and calls through to {@link #query(android.net.Uri, String[], String, String[],
-     * String, android.os.CancellationSignal)} with that.
-     */
-    public Cursor rejectQuery(Uri uri, String[] projection,
-            String selection, String[] selectionArgs, String sortOrder,
-            CancellationSignal cancellationSignal) {
-        // The read is not allowed...  to fake it out, we replace the given
-        // selection statement with a dummy one that will always be false.
-        // This way we will get a cursor back that has the correct structure
-        // but contains no rows.
-        if (selection == null || selection.isEmpty()) {
-            selection = "'A' = 'B'";
-        } else {
-            selection = "'A' = 'B' AND (" + selection + ")";
-        }
-        return query(uri, projection, selection, selectionArgs, sortOrder, cancellationSignal);
-    }
-
-    /**
      * Implement this to handle query requests from clients.
      * This method can be called from multiple threads, as described in
      * <a href="{@docRoot}guide/topics/fundamentals/processes-and-threads.html#Threads">Processes
diff --git a/core/java/android/os/FileUtils.java b/core/java/android/os/FileUtils.java
index b302f95..931cd3e 100644
--- a/core/java/android/os/FileUtils.java
+++ b/core/java/android/os/FileUtils.java
@@ -16,11 +16,13 @@
 
 package android.os;
 
+import android.provider.DocumentsContract.Document;
 import android.system.ErrnoException;
 import android.system.Os;
 import android.text.TextUtils;
 import android.util.Log;
 import android.util.Slog;
+import android.webkit.MimeTypeMap;
 
 import java.io.BufferedInputStream;
 import java.io.ByteArrayOutputStream;
@@ -34,6 +36,7 @@
 import java.io.InputStream;
 import java.util.Arrays;
 import java.util.Comparator;
+import java.util.Objects;
 import java.util.regex.Pattern;
 import java.util.zip.CRC32;
 import java.util.zip.CheckedInputStream;
@@ -533,4 +536,76 @@
         }
         return null;
     }
+
+    /**
+     * Generates a unique file name under the given parent directory. If the display name doesn't
+     * have an extension that matches the requested MIME type, the default extension for that MIME
+     * type is appended. If a file already exists, the name is appended with a numerical value to
+     * make it unique.
+     *
+     * For example, the display name 'example' with 'text/plain' MIME might produce
+     * 'example.txt' or 'example (1).txt', etc.
+     *
+     * @throws FileNotFoundException
+     */
+    public static File buildUniqueFile(File parent, String mimeType, String displayName)
+            throws FileNotFoundException {
+        String name;
+        String ext;
+
+        if (Document.MIME_TYPE_DIR.equals(mimeType)) {
+            name = displayName;
+            ext = null;
+        } else {
+            String mimeTypeFromExt;
+
+            // Extract requested extension from display name
+            final int lastDot = displayName.lastIndexOf('.');
+            if (lastDot >= 0) {
+                name = displayName.substring(0, lastDot);
+                ext = displayName.substring(lastDot + 1);
+                mimeTypeFromExt = MimeTypeMap.getSingleton().getMimeTypeFromExtension(
+                        ext.toLowerCase());
+            } else {
+                name = displayName;
+                ext = null;
+                mimeTypeFromExt = null;
+            }
+
+            if (mimeTypeFromExt == null) {
+                mimeTypeFromExt = "application/octet-stream";
+            }
+
+            final String extFromMimeType = MimeTypeMap.getSingleton().getExtensionFromMimeType(
+                    mimeType);
+            if (Objects.equals(mimeType, mimeTypeFromExt) || Objects.equals(ext, extFromMimeType)) {
+                // Extension maps back to requested MIME type; allow it
+            } else {
+                // No match; insist that create file matches requested MIME
+                name = displayName;
+                ext = extFromMimeType;
+            }
+        }
+
+        File file = buildFile(parent, name, ext);
+
+        // If conflicting file, try adding counter suffix
+        int n = 0;
+        while (file.exists()) {
+            if (n++ >= 32) {
+                throw new FileNotFoundException("Failed to create unique file");
+            }
+            file = buildFile(parent, name + " (" + n + ")", ext);
+        }
+
+        return file;
+    }
+
+    private static File buildFile(File parent, String name, String ext) {
+        if (TextUtils.isEmpty(ext)) {
+            return new File(parent, name);
+        } else {
+            return new File(parent, name + "." + ext);
+        }
+    }
 }
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index 8dc27dc..00c851b 100644
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -5391,6 +5391,12 @@
         public static final String SMS_DEFAULT_APPLICATION = "sms_default_application";
 
         /**
+         * Specifies the package name currently configured to be the default dialer application
+         * @hide
+         */
+        public static final String DIALER_DEFAULT_APPLICATION = "dialer_default_application";
+
+        /**
          * Specifies the package name currently configured to be the emergency assistance application
          *
          * @see android.telephony.TelephonyManager#ACTION_EMERGENCY_ASSISTANCE
diff --git a/core/java/android/service/chooser/ChooserTarget.java b/core/java/android/service/chooser/ChooserTarget.java
index d21cc3c..f0ca276 100644
--- a/core/java/android/service/chooser/ChooserTarget.java
+++ b/core/java/android/service/chooser/ChooserTarget.java
@@ -78,7 +78,8 @@
      * <p>The creator of a target may supply a ranking score. This score is assumed to be relative
      * to the other targets supplied by the same
      * {@link ChooserTargetService#onGetChooserTargets(ComponentName, IntentFilter) query}.
-     * Scores should be in the range from 0.0f (unlikely match) to 1.0f (very relevant match).</p>
+     * Scores should be in the range from 0.0f (unlikely match) to 1.0f (very relevant match).
+     * Scores for a set of targets do not need to sum to 1.</p>
      *
      * <p>Before being sent, the PendingIntent supplied will be
      * {@link Intent#fillIn(Intent, int) filled in} by the Intent originally supplied
@@ -113,7 +114,8 @@
      * <p>The creator of a target may supply a ranking score. This score is assumed to be relative
      * to the other targets supplied by the same
      * {@link ChooserTargetService#onGetChooserTargets(ComponentName, IntentFilter) query}.
-     * Scores should be in the range from 0.0f (unlikely match) to 1.0f (very relevant match).</p>
+     * Scores should be in the range from 0.0f (unlikely match) to 1.0f (very relevant match).
+     * Scores for a set of targets do not need to sum to 1.</p>
      *
      * <p>Before being sent, the IntentSender supplied will be
      * {@link Intent#fillIn(Intent, int) filled in} by the Intent originally supplied
@@ -144,6 +146,32 @@
         mIntentSender = intentSender;
     }
 
+    /**
+     * Construct a deep link target for presentation by a chooser UI.
+     *
+     * <p>A target is composed of a title and an icon for presentation to the user.
+     * The UI presenting this target may truncate the title if it is too long to be presented
+     * in the available space, as well as crop, resize or overlay the supplied icon.</p>
+     *
+     * <p>The creator of a target may supply a ranking score. This score is assumed to be relative
+     * to the other targets supplied by the same
+     * {@link ChooserTargetService#onGetChooserTargets(ComponentName, IntentFilter) query}.
+     * Scores should be in the range from 0.0f (unlikely match) to 1.0f (very relevant match).
+     * Scores for a set of targets do not need to sum to 1.</p>
+     *
+     * <p>Before being sent, the Intent supplied will be
+     * {@link Intent#fillIn(Intent, int) filled in} by the Intent originally supplied
+     * to the chooser.</p>
+     *
+     * <p>Take care not to place custom {@link android.os.Parcelable} types into
+     * the Intent as extras, as the system will not be able to unparcel it to merge
+     * additional extras.</p>
+     *
+     * @param title title of this target that will be shown to a user
+     * @param icon icon to represent this target
+     * @param score ranking score for this target between 0.0f and 1.0f, inclusive
+     * @param intent Intent to fill in and send if the user chooses this target
+     */
     public ChooserTarget(CharSequence title, Bitmap icon, float score, Intent intent) {
         mTitle = title;
         mIcon = icon;
@@ -358,6 +386,10 @@
         }
         dest.writeFloat(mScore);
         IntentSender.writeIntentSenderOrNullToParcel(mIntentSender, dest);
+        dest.writeInt(mIntent != null ? 1 : 0);
+        if (mIntent != null) {
+            mIntent.writeToParcel(dest, 0);
+        }
     }
 
     public static final Creator<ChooserTarget> CREATOR
diff --git a/core/java/android/webkit/WebSettings.java b/core/java/android/webkit/WebSettings.java
index 943beb0..453e4f5 100644
--- a/core/java/android/webkit/WebSettings.java
+++ b/core/java/android/webkit/WebSettings.java
@@ -900,7 +900,9 @@
      * and therefore secure policy, this setting should be disabled.
      * Note that this setting affects only JavaScript access to file scheme
      * resources. Other access to such resources, for example, from image HTML
-     * elements, is unaffected.
+     * elements, is unaffected. To prevent possible violation of same domain policy
+     * on {@link android.os.Build.VERSION_CODES#ICE_CREAM_SANDWICH} and earlier
+     * devices, you should explicitly set this value to {@code false}.
      * <p>
      * The default value is true for API level
      * {@link android.os.Build.VERSION_CODES#ICE_CREAM_SANDWICH_MR1} and below,
@@ -920,7 +922,9 @@
      * the value of {@link #getAllowUniversalAccessFromFileURLs} is true.
      * Note too, that this setting affects only JavaScript access to file scheme
      * resources. Other access to such resources, for example, from image HTML
-     * elements, is unaffected.
+     * elements, is unaffected. To prevent possible violation of same domain policy
+     * on {@link android.os.Build.VERSION_CODES#ICE_CREAM_SANDWICH} and earlier
+     * devices, you should explicitly set this value to {@code false}.
      * <p>
      * The default value is true for API level
      * {@link android.os.Build.VERSION_CODES#ICE_CREAM_SANDWICH_MR1} and below,
diff --git a/core/java/com/android/internal/app/ChooserActivity.java b/core/java/com/android/internal/app/ChooserActivity.java
index 8403e77..a6c39e6 100644
--- a/core/java/com/android/internal/app/ChooserActivity.java
+++ b/core/java/com/android/internal/app/ChooserActivity.java
@@ -401,6 +401,11 @@
         }
 
         @Override
+        public boolean shouldGetResolvedFilter() {
+            return true;
+        }
+
+        @Override
         public int getCount() {
             int count = super.getCount();
             if (mServiceTargets != null) {
diff --git a/core/java/com/android/internal/app/ResolverActivity.java b/core/java/com/android/internal/app/ResolverActivity.java
index 3cd69a1..7f51d92 100644
--- a/core/java/com/android/internal/app/ResolverActivity.java
+++ b/core/java/com/android/internal/app/ResolverActivity.java
@@ -1062,7 +1062,7 @@
             } else {
                 currentResolveList = mOrigResolveList = mPm.queryIntentActivities(mIntent,
                         PackageManager.MATCH_DEFAULT_ONLY
-                        | (mFilterLastUsed ? PackageManager.GET_RESOLVED_FILTER : 0)
+                        | (shouldGetResolvedFilter() ? PackageManager.GET_RESOLVED_FILTER : 0)
                         | (shouldGetActivityMetadata() ? PackageManager.GET_META_DATA : 0)
                 );
                 // Filter out any activities that the launched uid does not
@@ -1188,6 +1188,10 @@
             // This space for rent
         }
 
+        public boolean shouldGetResolvedFilter() {
+            return mFilterLastUsed;
+        }
+
         private void processGroup(List<ResolveInfo> rList, int start, int end, ResolveInfo ro,
                 CharSequence roLabel) {
             // Process labels from start to i
diff --git a/core/java/com/android/internal/widget/FloatingToolbar.java b/core/java/com/android/internal/widget/FloatingToolbar.java
index 579cad4..3a1e0ca 100644
--- a/core/java/com/android/internal/widget/FloatingToolbar.java
+++ b/core/java/com/android/internal/widget/FloatingToolbar.java
@@ -433,15 +433,13 @@
 
             mHidden = false;
             mDismissed = false;
-            cancelAllAnimations();
+            cancelDismissAndHideAnimations();
+            cancelOverflowAnimations();
             // Make sure a panel is set as the content.
             if (mContentContainer.getChildCount() == 0) {
                 setMainPanelAsContent();
             }
             preparePopupContent();
-            // If we're yet to show the popup, set the container visibility to zero.
-            // The "show" animation will make this visible.
-            mContentContainer.setAlpha(0);
             mPopupWindow.showAtLocation(mParent, Gravity.NO_GRAVITY, x, y);
             setTouchableSurfaceInsetsComputer();
             runShowAnimation();
@@ -451,12 +449,13 @@
          * Gets rid of this popup. If the popup isn't currently showing, this will be a no-op.
          */
         public void dismiss() {
-            if (!isShowing()) {
+            if (mDismissed) {
                 return;
             }
 
             mHidden = false;
             mDismissed = true;
+            mHideAnimation.cancel();
             runDismissAnimation();
             setZeroTouchableSurface();
         }
@@ -499,7 +498,7 @@
                 return;
             }
 
-            cancelAllAnimations();
+            cancelOverflowAnimations();
             preparePopupContent();
             mPopupWindow.update(x, y, getWidth(), getHeight());
         }
@@ -563,10 +562,12 @@
             mHideAnimation.start();
         }
 
-        private void cancelAllAnimations() {
-            mShowAnimation.cancel();
+        private void cancelDismissAndHideAnimations() {
             mDismissAnimation.cancel();
             mHideAnimation.cancel();
+        }
+
+        private void cancelOverflowAnimations() {
             mOpenOverflowAnimation.cancel();
             mCloseOverflowAnimation.cancel();
         }
diff --git a/core/jni/android_media_AudioRecord.cpp b/core/jni/android_media_AudioRecord.cpp
index 23b0d50..d86f71a 100644
--- a/core/jni/android_media_AudioRecord.cpp
+++ b/core/jni/android_media_AudioRecord.cpp
@@ -584,6 +584,13 @@
     return frameCount * channelCount * audio_bytes_per_sample(format);
 }
 
+static jboolean android_media_AudioRecord_setInputDevice(
+        JNIEnv *env,  jobject thiz, jint device_id) {
+
+//    sp<AudioRecord> lpRecorder = getAudioRecord(env, thiz);
+//    return lpRecorder->setInputDevice(device_id) == NO_ERROR;
+    return false;
+}
 
 // ----------------------------------------------------------------------------
 // ----------------------------------------------------------------------------
@@ -616,6 +623,7 @@
                              "()I",    (void *)android_media_AudioRecord_get_pos_update_period},
     {"native_get_min_buff_size",
                              "(III)I",   (void *)android_media_AudioRecord_get_min_buff_size},
+    {"native_setInputDevice", "(I)Z", (void *)android_media_AudioRecord_setInputDevice},
 };
 
 // field names found in android/media/AudioRecord.java
diff --git a/core/tests/coretests/src/android/os/FileUtilsTest.java b/core/tests/coretests/src/android/os/FileUtilsTest.java
index 5c9e813..ee9e2e4 100644
--- a/core/tests/coretests/src/android/os/FileUtilsTest.java
+++ b/core/tests/coretests/src/android/os/FileUtilsTest.java
@@ -21,6 +21,7 @@
 import static android.text.format.DateUtils.WEEK_IN_MILLIS;
 
 import android.content.Context;
+import android.provider.DocumentsContract.Document;
 import android.test.AndroidTestCase;
 import android.test.suitebuilder.annotation.MediumTest;
 
@@ -43,6 +44,8 @@
     private File mDir;
     private File mTestFile;
     private File mCopyFile;
+    private File mTarget;
+
 
     @Override
     protected void setUp() throws Exception {
@@ -50,11 +53,15 @@
         mDir = getContext().getDir("testing", Context.MODE_PRIVATE);
         mTestFile = new File(mDir, "test.file");
         mCopyFile = new File(mDir, "copy.file");
+
+        mTarget = getContext().getFilesDir();
+        FileUtils.deleteContents(mTarget);
     }
 
     @Override
     protected void tearDown() throws Exception {
         IoUtils.deleteContents(mDir);
+        FileUtils.deleteContents(mTarget);
     }
 
     // TODO: test setPermissions(), getPermissions()
@@ -225,6 +232,63 @@
         assertEquals("foo_bar__baz", FileUtils.buildValidFatFilename("foo?bar**baz"));
     }
 
+    public void testBuildUniqueFile_normal() throws Exception {
+        assertNameEquals("test.jpg", FileUtils.buildUniqueFile(mTarget, "image/jpeg", "test"));
+        assertNameEquals("test.jpg", FileUtils.buildUniqueFile(mTarget, "image/jpeg", "test.jpg"));
+        assertNameEquals("test.jpeg", FileUtils.buildUniqueFile(mTarget, "image/jpeg", "test.jpeg"));
+        assertNameEquals("TEst.JPeg", FileUtils.buildUniqueFile(mTarget, "image/jpeg", "TEst.JPeg"));
+        assertNameEquals("test.png.jpg",
+                FileUtils.buildUniqueFile(mTarget, "image/jpeg", "test.png.jpg"));
+        assertNameEquals("test.png.jpg",
+                FileUtils.buildUniqueFile(mTarget, "image/jpeg", "test.png"));
+
+        assertNameEquals("test.flac", FileUtils.buildUniqueFile(mTarget, "audio/flac", "test"));
+        assertNameEquals("test.flac", FileUtils.buildUniqueFile(mTarget, "audio/flac", "test.flac"));
+        assertNameEquals("test.flac",
+                FileUtils.buildUniqueFile(mTarget, "application/x-flac", "test"));
+        assertNameEquals("test.flac",
+                FileUtils.buildUniqueFile(mTarget, "application/x-flac", "test.flac"));
+    }
+
+    public void testBuildUniqueFile_unknown() throws Exception {
+        assertNameEquals("test",
+                FileUtils.buildUniqueFile(mTarget, "application/octet-stream", "test"));
+        assertNameEquals("test.jpg",
+                FileUtils.buildUniqueFile(mTarget, "application/octet-stream", "test.jpg"));
+        assertNameEquals(".test",
+                FileUtils.buildUniqueFile(mTarget, "application/octet-stream", ".test"));
+
+        assertNameEquals("test", FileUtils.buildUniqueFile(mTarget, "lolz/lolz", "test"));
+        assertNameEquals("test.lolz", FileUtils.buildUniqueFile(mTarget, "lolz/lolz", "test.lolz"));
+    }
+
+    public void testBuildUniqueFile_dir() throws Exception {
+        assertNameEquals("test", FileUtils.buildUniqueFile(mTarget, Document.MIME_TYPE_DIR, "test"));
+        new File(mTarget, "test").mkdir();
+        assertNameEquals("test (1)",
+                FileUtils.buildUniqueFile(mTarget, Document.MIME_TYPE_DIR, "test"));
+
+        assertNameEquals("test.jpg",
+                FileUtils.buildUniqueFile(mTarget, Document.MIME_TYPE_DIR, "test.jpg"));
+        new File(mTarget, "test.jpg").mkdir();
+        assertNameEquals("test.jpg (1)",
+                FileUtils.buildUniqueFile(mTarget, Document.MIME_TYPE_DIR, "test.jpg"));
+    }
+
+    public void testBuildUniqueFile_increment() throws Exception {
+        assertNameEquals("test.jpg", FileUtils.buildUniqueFile(mTarget, "image/jpeg", "test.jpg"));
+        new File(mTarget, "test.jpg").createNewFile();
+        assertNameEquals("test (1).jpg",
+                FileUtils.buildUniqueFile(mTarget, "image/jpeg", "test.jpg"));
+        new File(mTarget, "test (1).jpg").createNewFile();
+        assertNameEquals("test (2).jpg",
+                FileUtils.buildUniqueFile(mTarget, "image/jpeg", "test.jpg"));
+    }
+
+    private static void assertNameEquals(String expected, File actual) {
+        assertEquals(expected, actual.getName());
+    }
+
     private void touch(String name, long age) throws Exception {
         final File file = new File(mDir, name);
         file.createNewFile();
diff --git a/docs/html/google/play-services/index.jd b/docs/html/google/play-services/index.jd
index e31290a..d674f7f 100644
--- a/docs/html/google/play-services/index.jd
+++ b/docs/html/google/play-services/index.jd
@@ -88,7 +88,7 @@
       <li><a href="https://developers.google.com/maps/documentation/android/wear"
         class="external-link">Google Maps on Android Wear developer guide</a>
       </li>
-      <li><a href="https://github.com/googlemaps/android-samples"
+      <li><a href="https://github.com/googlemaps/android-samples/tree/master/BasicWearMap"
         class="external-link">Google Maps on Android Wear sample</a>
       </li>
       <li><a href="https://developers.google.com/maps/documentation/android/releases"
diff --git a/docs/html/guide/topics/resources/string-resource.jd b/docs/html/guide/topics/resources/string-resource.jd
index cbfa82e..743e692 100644
--- a/docs/html/guide/topics/resources/string-resource.jd
+++ b/docs/html/guide/topics/resources/string-resource.jd
@@ -401,19 +401,35 @@
 format and style your string resources.</p>
 
 
-<h3>Escaping apostrophes and quotes</h3>
+<h3 id="escaping_quotes">Escaping apostrophes and quotes</h3>
 
-<p>If you have an apostrophe or a quote in your string, you must either escape it or enclose the
-whole string in the other type of enclosing quotes. For example, here are some stings that
-do and don't work:</p>
+<p>
+  If you have an apostrophe (<code>'</code>) in your string, you must either
+  escape it with a backslash (<code>\'</code>) or enclose the string in
+  double-quotes (<code>""</code>). For example, here are some strings that do
+  and don't work:
+</p>
 
 <pre>
-&lt;string name="good_example">"This'll work"&lt;/string>
-&lt;string name="good_example_2">This\'ll also work&lt;/string>
+&lt;string name="good_example">This\'ll work&lt;/string>
+&lt;string name="good_example_2">"This'll also work"&lt;/string>
 &lt;string name="bad_example">This doesn't work&lt;/string>
-&lt;string name="bad_example_2">XML encodings don&amp;apos;t work&lt;/string>
+    &lt;!-- Causes a compile error -->
 </pre>
 
+<p>
+  If you have a double-quote in your string, you must escape it
+  (<code>\"</code>). Surrounding the string with single-quotes does
+  <em>not</em> work.
+</p>
+
+<pre>
+&lt;string name="good_example">This is a \"good string\".&lt;/string>
+&lt;string name="bad_example">This is a "bad string".&lt;/string>
+    &lt;!-- Quotes are stripped; displays as: This is a bad string. -->
+&lt;string name="bad_example_2">'This is another "bad string".'&lt;/string>
+    &lt;!-- Causes a compile error -->
+</pre>
 
 <h3>Formatting strings</h3>
 
diff --git a/docs/html/reference/com/google/android/gms/fitness/data/Field.html b/docs/html/reference/com/google/android/gms/fitness/data/Field.html
index 91bf861..0f97e7e 100644
--- a/docs/html/reference/com/google/android/gms/fitness/data/Field.html
+++ b/docs/html/reference/com/google/android/gms/fitness/data/Field.html
@@ -151,7 +151,7 @@
 
 <a name="top"></a>
 
-<!-- dialog to prompt lang pref change when loaded from hardcoded URL 
+<!-- dialog to prompt lang pref change when loaded from hardcoded URL
 <div id="langMessage" style="display:none">
   <div>
     <div class="lang en">
@@ -201,7 +201,7 @@
   <div id="header-wrapper">
     <div id="header">
 
-    
+
 
 
       <div class="wrap" id="header-wrap">
@@ -245,8 +245,8 @@
         </ul>
 
 
-        
-        
+
+
 <div class="menu-container">
   <div class="moremenu">
     <div id="more-btn"></div>
@@ -267,8 +267,8 @@
         <li><a href="http://source.android.com">Android Open Source Project</a></li>
       </ul>
 
-      
-      
+
+
         <div class="header">Language</div>
           <div id="language" class="locales">
             <select name="language" onChange="changeLangPref(this.value, true)">
@@ -286,8 +286,8 @@
           loadLangPref();
             //-->
         </script>
-      
-      
+
+
       <br class="clearfix" />
     </div><!-- end 'mid' -->
     <div class="bottom"></div>
@@ -401,10 +401,10 @@
                 </li>
                 <li><a href="/google/index.html">Google Services</a>
                 </li>
-                
+
                   <li><a href="/samples/index.html">Samples</a>
                   </li>
-                
+
               </ul>
             </li>
             <li class="distribute last">
@@ -424,14 +424,14 @@
       </div><!-- end header-wrap.wrap -->
     </div><!-- end header -->
 
-  
+
     <!-- Secondary x-nav -->
     <div id="nav-x">
         <div class="wrap" style="position:relative;z-index:1">
 
-        
-        
-        
+
+
+
 
             <ul class="nav-x col-9 develop" style="width:100%">
                 <li class="training"><a href="/training/index.html"
@@ -469,17 +469,17 @@
                 <li class="google"><a href="/google/index.html"
                   >Google Services</a>
                 </li>
-                
+
                   <li class="samples"><a href="/samples/index.html"
                     >Samples</a>
                   </li>
-                
+
             </ul>
         </div>
     </div>
     <!-- /Sendondary x-nav DEVELOP -->
 
-  
+
 
     <div id="searchResults" class="wrap" style="display:none;">
       <h2 id="searchTitle">Results</h2>
@@ -492,7 +492,7 @@
       <a class="logo" href="#top"></a>
       <a class="top" href="#top"></a>
       <ul class="breadcrumb">
-        
+
         <li class="current">Field</li>
       </ul>
     </div>
@@ -502,7 +502,7 @@
 
 
 
-  
+
   <div class="wrap clearfix" id="body-content">
     <div class="col-4" id="side-nav" itemscope itemtype="http://schema.org/SiteNavigationElement">
       <div id="devdoc-nav" class="scroll-pane">
@@ -759,12 +759,12 @@
 </script>
 
 
-        
+
 
       </div>
       <script type="text/javascript">
        showGoogleRefTree();
-    
+
       </script>
     </div> <!-- end side-nav -->
     <script>
@@ -774,7 +774,7 @@
     </script>
 
 
-     
+
 
 
 
@@ -784,21 +784,21 @@
 
 
 
-  
-   
-  
-  
-  
-  
 
-  
-   
-  
-  
-   
-  
-  
-  
+
+
+
+
+
+
+
+
+
+
+
+
+
+
 
 
 <div class="sum-details-links">
@@ -810,22 +810,22 @@
 
 
   <a href="#constants">Constants</a>
-  
+
 
 
   &#124; <a href="#inhconstants">Inherited Constants</a>
-  
+
 
 
   &#124; <a href="#lfields">Fields</a>
-  
+
 
 
 
 
 
   &#124; <a href="#pubmethods">Methods</a>
-  
+
 
 
 
@@ -835,9 +835,9 @@
 
 </div><!-- end sum-details-links -->
 <div class="api-level">
-  
-  
-  
+
+
+
 
 </div>
 </div><!-- end api-info-block -->
@@ -847,31 +847,31 @@
 
 <div id="jd-header">
     public
-     
-    final 
-    
+
+    final
+
     class
 <h1 itemprop="name">Field</h1>
 
 
 
-  
+
     extends Object<br/>
-  
-  
-  
-
-  
-  
-      implements 
-      
-        Parcelable 
-      
-  
-  
 
 
-    
+
+
+
+
+      implements
+
+        Parcelable
+
+
+
+
+
+
 
 
 </div><!-- end header -->
@@ -883,18 +883,18 @@
 
 
     <tr>
-         	
+
         <td colspan="2" class="jd-inheritance-class-cell">java.lang.Object</td>
     </tr>
-    
+
 
     <tr>
-        
+
             <td class="jd-inheritance-space">&nbsp;&nbsp;&nbsp;&#x21b3;</td>
-         	
+
         <td colspan="1" class="jd-inheritance-class-cell">com.google.android.gms.fitness.data.Field</td>
     </tr>
-    
+
 
 </table>
 
@@ -962,31 +962,31 @@
 <table id="constants" class="jd-sumtable"><tr><th colspan="12">Constants</th></tr>
 
 
-    
+
     <tr class="alt-color api apilevel-" >
         <td class="jd-typecol">int</td>
         <td class="jd-linkcol"><a href="/reference/com/google/android/gms/fitness/data/Field.html#FORMAT_FLOAT">FORMAT_FLOAT</a></td>
         <td class="jd-descrcol" width="100%">
           Format constant indicating the field holds float values.
-          
-    
+
+
 
         </td>
     </tr>
-    
-    
+
+
     <tr class=" api apilevel-" >
         <td class="jd-typecol">int</td>
         <td class="jd-linkcol"><a href="/reference/com/google/android/gms/fitness/data/Field.html#FORMAT_INT32">FORMAT_INT32</a></td>
         <td class="jd-descrcol" width="100%">
           Format constant indicating the field holds integer values.
-          
-    
+
+
 
         </td>
     </tr>
-    
-    
+
+
     <tr class="alt-color api apilevel-" >
         <td class="jd-typecol">int</td>
         <td class="jd-linkcol"><a href="/reference/com/google/android/gms/fitness/data/Field.html#FORMAT_MAP">FORMAT_MAP</a></td>
@@ -1305,33 +1305,33 @@
   </div>
   <div id="inherited-constants-android.os.Parcelable-summary" style="display: none;">
     <table class="jd-sumtable-expando">
-    
 
-    
+
+
     <tr class="alt-color api apilevel-" >
         <td class="jd-typecol">int</td>
         <td class="jd-linkcol">CONTENTS_FILE_DESCRIPTOR</td>
         <td class="jd-descrcol" width="100%">
-          
-          
-    
+
+
+
 
         </td>
     </tr>
-    
-    
+
+
     <tr class=" api apilevel-" >
         <td class="jd-typecol">int</td>
         <td class="jd-linkcol">PARCELABLE_WRITE_RETURN_VALUE</td>
         <td class="jd-descrcol" width="100%">
-          
-          
-    
+
+
+
 
         </td>
     </tr>
-    
-    
+
+
 </table>
   </div>
 </div>
@@ -1347,7 +1347,7 @@
 <table id="lfields" class="jd-sumtable"><tr><th colspan="12">Fields</th></tr>
 
 
-    
+
       <tr class="alt-color api apilevel-" >
           <td class="jd-typecol"><nobr>
           public
@@ -1357,13 +1357,13 @@
           <td class="jd-linkcol"><a href="/reference/com/google/android/gms/fitness/data/Field.html#FIELD_ACCURACY">FIELD_ACCURACY</a></td>
           <td class="jd-descrcol" width="100%">
             The accuracy of an accompanied value (such as location).
-            
-    
+
+
 
           </td>
       </tr>
-      
-    
+
+
       <tr class=" api apilevel-" >
           <td class="jd-typecol"><nobr>
           public
@@ -1373,13 +1373,13 @@
           <td class="jd-linkcol"><a href="/reference/com/google/android/gms/fitness/data/Field.html#FIELD_ACTIVITY">FIELD_ACTIVITY</a></td>
           <td class="jd-descrcol" width="100%">
             An activity type of <code><a href="/reference/com/google/android/gms/fitness/FitnessActivities.html">FitnessActivities</a></code>, encoded as an integer for efficiency.
-            
-    
+
+
 
           </td>
       </tr>
-      
-    
+
+
       <tr class="alt-color api apilevel-" >
           <td class="jd-typecol"><nobr>
           public
@@ -1389,13 +1389,13 @@
           <td class="jd-linkcol"><a href="/reference/com/google/android/gms/fitness/data/Field.html#FIELD_ALTITUDE">FIELD_ALTITUDE</a></td>
           <td class="jd-descrcol" width="100%">
             An altitude of a location represented as a float, in meters above sea level.
-            
-    
+
+
 
           </td>
       </tr>
-      
-    
+
+
       <tr class=" api apilevel-" >
           <td class="jd-typecol"><nobr>
           public
@@ -1405,13 +1405,13 @@
           <td class="jd-linkcol"><a href="/reference/com/google/android/gms/fitness/data/Field.html#FIELD_AVERAGE">FIELD_AVERAGE</a></td>
           <td class="jd-descrcol" width="100%">
             An average value.
-            
-    
+
+
 
           </td>
       </tr>
-      
-    
+
+
       <tr class="alt-color api apilevel-" >
           <td class="jd-typecol"><nobr>
           public
@@ -1421,13 +1421,13 @@
           <td class="jd-linkcol"><a href="/reference/com/google/android/gms/fitness/data/Field.html#FIELD_BPM">FIELD_BPM</a></td>
           <td class="jd-descrcol" width="100%">
             A heart rate in beats per minute.
-            
-    
+
+
 
           </td>
       </tr>
-      
-    
+
+
       <tr class=" api apilevel-" >
           <td class="jd-typecol"><nobr>
           public
@@ -1437,13 +1437,13 @@
           <td class="jd-linkcol"><a href="/reference/com/google/android/gms/fitness/data/Field.html#FIELD_CALORIES">FIELD_CALORIES</a></td>
           <td class="jd-descrcol" width="100%">
             Calories in kcal.
-            
-    
+
+
 
           </td>
       </tr>
-      
-    
+
+
       <tr class="alt-color api apilevel-" >
           <td class="jd-typecol"><nobr>
           public
@@ -1469,13 +1469,13 @@
           <td class="jd-linkcol"><a href="/reference/com/google/android/gms/fitness/data/Field.html#FIELD_CONFIDENCE">FIELD_CONFIDENCE</a></td>
           <td class="jd-descrcol" width="100%">
             The confidence of an accompanied value, specified as a value between 0.0 and 100.0.
-            
-    
+
+
 
           </td>
       </tr>
-      
-    
+
+
       <tr class="alt-color api apilevel-" >
           <td class="jd-typecol"><nobr>
           public
@@ -1485,13 +1485,13 @@
           <td class="jd-linkcol"><a href="/reference/com/google/android/gms/fitness/data/Field.html#FIELD_DISTANCE">FIELD_DISTANCE</a></td>
           <td class="jd-descrcol" width="100%">
             A distance in meters.
-            
-    
+
+
 
           </td>
       </tr>
-      
-    
+
+
       <tr class=" api apilevel-" >
           <td class="jd-typecol"><nobr>
           public
@@ -1501,13 +1501,13 @@
           <td class="jd-linkcol"><a href="/reference/com/google/android/gms/fitness/data/Field.html#FIELD_DURATION">FIELD_DURATION</a></td>
           <td class="jd-descrcol" width="100%">
             A duration in milliseconds.
-            
-    
+
+
 
           </td>
       </tr>
-      
-    
+
+
       <tr class="alt-color api apilevel-" >
           <td class="jd-typecol"><nobr>
           public
@@ -1533,13 +1533,13 @@
           <td class="jd-linkcol"><a href="/reference/com/google/android/gms/fitness/data/Field.html#FIELD_HEIGHT">FIELD_HEIGHT</a></td>
           <td class="jd-descrcol" width="100%">
             A height in meters.
-            
-    
+
+
 
           </td>
       </tr>
-      
-    
+
+
       <tr class="alt-color api apilevel-" >
           <td class="jd-typecol"><nobr>
           public
@@ -1549,13 +1549,13 @@
           <td class="jd-linkcol"><a href="/reference/com/google/android/gms/fitness/data/Field.html#FIELD_HIGH_LATITUDE">FIELD_HIGH_LATITUDE</a></td>
           <td class="jd-descrcol" width="100%">
             A high latitude of a location bounding box represented as a float, in degrees.
-            
-    
+
+
 
           </td>
       </tr>
-      
-    
+
+
       <tr class=" api apilevel-" >
           <td class="jd-typecol"><nobr>
           public
@@ -1565,13 +1565,13 @@
           <td class="jd-linkcol"><a href="/reference/com/google/android/gms/fitness/data/Field.html#FIELD_HIGH_LONGITUDE">FIELD_HIGH_LONGITUDE</a></td>
           <td class="jd-descrcol" width="100%">
             A high longitude of a location bounding box represented as a float, in degrees.
-            
-    
+
+
 
           </td>
       </tr>
-      
-    
+
+
       <tr class="alt-color api apilevel-" >
           <td class="jd-typecol"><nobr>
           public
@@ -1581,13 +1581,13 @@
           <td class="jd-linkcol"><a href="/reference/com/google/android/gms/fitness/data/Field.html#FIELD_LATITUDE">FIELD_LATITUDE</a></td>
           <td class="jd-descrcol" width="100%">
             A latitude of a location represented as a float, in degrees.
-            
-    
+
+
 
           </td>
       </tr>
-      
-    
+
+
       <tr class=" api apilevel-" >
           <td class="jd-typecol"><nobr>
           public
@@ -1597,13 +1597,13 @@
           <td class="jd-linkcol"><a href="/reference/com/google/android/gms/fitness/data/Field.html#FIELD_LONGITUDE">FIELD_LONGITUDE</a></td>
           <td class="jd-descrcol" width="100%">
             A longitude of a location represented as a float, in degrees.
-            
-    
+
+
 
           </td>
       </tr>
-      
-    
+
+
       <tr class="alt-color api apilevel-" >
           <td class="jd-typecol"><nobr>
           public
@@ -1613,13 +1613,13 @@
           <td class="jd-linkcol"><a href="/reference/com/google/android/gms/fitness/data/Field.html#FIELD_LOW_LATITUDE">FIELD_LOW_LATITUDE</a></td>
           <td class="jd-descrcol" width="100%">
             A low latitude of a location bounding box represented as a float, in degrees.
-            
-    
+
+
 
           </td>
       </tr>
-      
-    
+
+
       <tr class=" api apilevel-" >
           <td class="jd-typecol"><nobr>
           public
@@ -1629,13 +1629,13 @@
           <td class="jd-linkcol"><a href="/reference/com/google/android/gms/fitness/data/Field.html#FIELD_LOW_LONGITUDE">FIELD_LOW_LONGITUDE</a></td>
           <td class="jd-descrcol" width="100%">
             A low longitude of a location bounding box represented as a float, in degrees.
-            
-    
+
+
 
           </td>
       </tr>
-      
-    
+
+
       <tr class="alt-color api apilevel-" >
           <td class="jd-typecol"><nobr>
           public
@@ -1645,13 +1645,13 @@
           <td class="jd-linkcol"><a href="/reference/com/google/android/gms/fitness/data/Field.html#FIELD_MAX">FIELD_MAX</a></td>
           <td class="jd-descrcol" width="100%">
             A maximum value.
-            
-    
+
+
 
           </td>
       </tr>
-      
-    
+
+
       <tr class=" api apilevel-" >
           <td class="jd-typecol"><nobr>
           public
@@ -1677,13 +1677,13 @@
           <td class="jd-linkcol"><a href="/reference/com/google/android/gms/fitness/data/Field.html#FIELD_MIN">FIELD_MIN</a></td>
           <td class="jd-descrcol" width="100%">
             A minimum value.
-            
-    
+
+
 
           </td>
       </tr>
-      
-    
+
+
       <tr class=" api apilevel-" >
           <td class="jd-typecol"><nobr>
           public
@@ -1725,13 +1725,13 @@
           <td class="jd-linkcol"><a href="/reference/com/google/android/gms/fitness/data/Field.html#FIELD_PERCENTAGE">FIELD_PERCENTAGE</a></td>
           <td class="jd-descrcol" width="100%">
             A percentage value, between 0 and 100.
-            
-    
+
+
 
           </td>
       </tr>
-      
-    
+
+
       <tr class="alt-color api apilevel-" >
           <td class="jd-typecol"><nobr>
           public
@@ -1741,13 +1741,13 @@
           <td class="jd-linkcol"><a href="/reference/com/google/android/gms/fitness/data/Field.html#FIELD_REVOLUTIONS">FIELD_REVOLUTIONS</a></td>
           <td class="jd-descrcol" width="100%">
             A count of revolutions.
-            
-    
+
+
 
           </td>
       </tr>
-      
-    
+
+
       <tr class=" api apilevel-" >
           <td class="jd-typecol"><nobr>
           public
@@ -1757,13 +1757,13 @@
           <td class="jd-linkcol"><a href="/reference/com/google/android/gms/fitness/data/Field.html#FIELD_RPM">FIELD_RPM</a></td>
           <td class="jd-descrcol" width="100%">
             Revolutions per minute or rate per minute.
-            
-    
+
+
 
           </td>
       </tr>
-      
-    
+
+
       <tr class="alt-color api apilevel-" >
           <td class="jd-typecol"><nobr>
           public
@@ -1773,13 +1773,13 @@
           <td class="jd-linkcol"><a href="/reference/com/google/android/gms/fitness/data/Field.html#FIELD_SPEED">FIELD_SPEED</a></td>
           <td class="jd-descrcol" width="100%">
             A speed in meter/sec.
-            
-    
+
+
 
           </td>
       </tr>
-      
-    
+
+
       <tr class=" api apilevel-" >
           <td class="jd-typecol"><nobr>
           public
@@ -1789,13 +1789,13 @@
           <td class="jd-linkcol"><a href="/reference/com/google/android/gms/fitness/data/Field.html#FIELD_STEPS">FIELD_STEPS</a></td>
           <td class="jd-descrcol" width="100%">
             A count of steps.
-            
-    
+
+
 
           </td>
       </tr>
-      
-    
+
+
       <tr class="alt-color api apilevel-" >
           <td class="jd-typecol"><nobr>
           public
@@ -1805,13 +1805,13 @@
           <td class="jd-linkcol"><a href="/reference/com/google/android/gms/fitness/data/Field.html#FIELD_WATTS">FIELD_WATTS</a></td>
           <td class="jd-descrcol" width="100%">
             Power in watts.
-            
-    
+
+
 
           </td>
       </tr>
-      
-    
+
+
       <tr class=" api apilevel-" >
           <td class="jd-typecol"><nobr>
           public
@@ -1821,13 +1821,13 @@
           <td class="jd-linkcol"><a href="/reference/com/google/android/gms/fitness/data/Field.html#FIELD_WEIGHT">FIELD_WEIGHT</a></td>
           <td class="jd-descrcol" width="100%">
             A weight in kilograms.
-            
-    
+
+
 
           </td>
       </tr>
-      
-    
+
+
 
 </table>
 
@@ -1846,129 +1846,129 @@
 
 
 
-	 
+
     <tr class="alt-color api apilevel-" >
         <td class="jd-typecol"><nobr>
-            
-            
-            
-            
-            
+
+
+
+
+
             int</nobr>
         </td>
         <td class="jd-linkcol" width="100%"><nobr>
         <span class="sympad"><a href="/reference/com/google/android/gms/fitness/data/Field.html#describeContents()">describeContents</a></span>()</nobr>
-        
+
   </td></tr>
 
 
-	 
+
     <tr class=" api apilevel-" >
         <td class="jd-typecol"><nobr>
-            
-            
-            
-            
-            
+
+
+
+
+
             boolean</nobr>
         </td>
         <td class="jd-linkcol" width="100%"><nobr>
         <span class="sympad"><a href="/reference/com/google/android/gms/fitness/data/Field.html#equals(java.lang.Object)">equals</a></span>(Object that)</nobr>
-        
+
   </td></tr>
 
 
-	 
+
     <tr class="alt-color api apilevel-" >
         <td class="jd-typecol"><nobr>
-            
-            
-            
-            
-            
+
+
+
+
+
             int</nobr>
         </td>
         <td class="jd-linkcol" width="100%"><nobr>
         <span class="sympad"><a href="/reference/com/google/android/gms/fitness/data/Field.html#getFormat()">getFormat</a></span>()</nobr>
-        
+
         <div class="jd-descrdiv">
           Returns the format of the field, as one of the format constant values.
-          
-    
+
+
 
         </div>
-  
+
   </td></tr>
 
 
-	 
+
     <tr class=" api apilevel-" >
         <td class="jd-typecol"><nobr>
-            
-            
-            
-            
-            
+
+
+
+
+
             String</nobr>
         </td>
         <td class="jd-linkcol" width="100%"><nobr>
         <span class="sympad"><a href="/reference/com/google/android/gms/fitness/data/Field.html#getName()">getName</a></span>()</nobr>
-        
+
         <div class="jd-descrdiv">
           Returns the name of the field.
-          
-    
+
+
 
         </div>
-  
+
   </td></tr>
 
 
-	 
+
     <tr class="alt-color api apilevel-" >
         <td class="jd-typecol"><nobr>
-            
-            
-            
-            
-            
+
+
+
+
+
             int</nobr>
         </td>
         <td class="jd-linkcol" width="100%"><nobr>
         <span class="sympad"><a href="/reference/com/google/android/gms/fitness/data/Field.html#hashCode()">hashCode</a></span>()</nobr>
-        
+
   </td></tr>
 
 
-	 
+
     <tr class=" api apilevel-" >
         <td class="jd-typecol"><nobr>
-            
-            
-            
-            
-            
+
+
+
+
+
             String</nobr>
         </td>
         <td class="jd-linkcol" width="100%"><nobr>
         <span class="sympad"><a href="/reference/com/google/android/gms/fitness/data/Field.html#toString()">toString</a></span>()</nobr>
-        
+
   </td></tr>
 
 
-	 
+
     <tr class="alt-color api apilevel-" >
         <td class="jd-typecol"><nobr>
-            
-            
-            
-            
-            
+
+
+
+
+
             void</nobr>
         </td>
         <td class="jd-linkcol" width="100%"><nobr>
         <span class="sympad"><a href="/reference/com/google/android/gms/fitness/data/Field.html#writeToParcel(android.os.Parcel, int)">writeToParcel</a></span>(Parcel dest, int flags)</nobr>
-        
+
   </td></tr>
 
 
@@ -2003,182 +2003,182 @@
   </div>
   <div id="inherited-methods-java.lang.Object-summary" style="display: none;">
     <table class="jd-sumtable-expando">
-    
 
 
-	 
+
+
     <tr class="alt-color api apilevel-" >
         <td class="jd-typecol"><nobr>
-            
-            
-            
-            
-            
+
+
+
+
+
             Object</nobr>
         </td>
         <td class="jd-linkcol" width="100%"><nobr>
         <span class="sympad">clone</span>()</nobr>
-        
+
   </td></tr>
 
 
-	 
+
     <tr class=" api apilevel-" >
         <td class="jd-typecol"><nobr>
-            
-            
-            
-            
-            
+
+
+
+
+
             boolean</nobr>
         </td>
         <td class="jd-linkcol" width="100%"><nobr>
         <span class="sympad">equals</span>(Object arg0)</nobr>
-        
+
   </td></tr>
 
 
-	 
+
     <tr class="alt-color api apilevel-" >
         <td class="jd-typecol"><nobr>
-            
-            
-            
-            
-            
+
+
+
+
+
             void</nobr>
         </td>
         <td class="jd-linkcol" width="100%"><nobr>
         <span class="sympad">finalize</span>()</nobr>
-        
+
   </td></tr>
 
 
-	 
+
     <tr class=" api apilevel-" >
         <td class="jd-typecol"><nobr>
-            
-            
+
+
             final
-            
-            
+
+
             Class&lt;?&gt;</nobr>
         </td>
         <td class="jd-linkcol" width="100%"><nobr>
         <span class="sympad">getClass</span>()</nobr>
-        
+
   </td></tr>
 
 
-	 
+
     <tr class="alt-color api apilevel-" >
         <td class="jd-typecol"><nobr>
-            
-            
-            
-            
-            
+
+
+
+
+
             int</nobr>
         </td>
         <td class="jd-linkcol" width="100%"><nobr>
         <span class="sympad">hashCode</span>()</nobr>
-        
+
   </td></tr>
 
 
-	 
+
     <tr class=" api apilevel-" >
         <td class="jd-typecol"><nobr>
-            
-            
+
+
             final
-            
-            
+
+
             void</nobr>
         </td>
         <td class="jd-linkcol" width="100%"><nobr>
         <span class="sympad">notify</span>()</nobr>
-        
+
   </td></tr>
 
 
-	 
+
     <tr class="alt-color api apilevel-" >
         <td class="jd-typecol"><nobr>
-            
-            
+
+
             final
-            
-            
+
+
             void</nobr>
         </td>
         <td class="jd-linkcol" width="100%"><nobr>
         <span class="sympad">notifyAll</span>()</nobr>
-        
+
   </td></tr>
 
 
-	 
+
     <tr class=" api apilevel-" >
         <td class="jd-typecol"><nobr>
-            
-            
-            
-            
-            
+
+
+
+
+
             String</nobr>
         </td>
         <td class="jd-linkcol" width="100%"><nobr>
         <span class="sympad">toString</span>()</nobr>
-        
+
   </td></tr>
 
 
-	 
+
     <tr class="alt-color api apilevel-" >
         <td class="jd-typecol"><nobr>
-            
-            
+
+
             final
-            
-            
+
+
             void</nobr>
         </td>
         <td class="jd-linkcol" width="100%"><nobr>
         <span class="sympad">wait</span>()</nobr>
-        
+
   </td></tr>
 
 
-	 
+
     <tr class=" api apilevel-" >
         <td class="jd-typecol"><nobr>
-            
-            
+
+
             final
-            
-            
+
+
             void</nobr>
         </td>
         <td class="jd-linkcol" width="100%"><nobr>
         <span class="sympad">wait</span>(long arg0, int arg1)</nobr>
-        
+
   </td></tr>
 
 
-	 
+
     <tr class="alt-color api apilevel-" >
         <td class="jd-typecol"><nobr>
-            
-            
+
+
             final
-            
-            
+
+
             void</nobr>
         </td>
         <td class="jd-linkcol" width="100%"><nobr>
         <span class="sympad">wait</span>(long arg0)</nobr>
-        
+
   </td></tr>
 
 
@@ -2205,7 +2205,7 @@
   </div>
   <div id="inherited-methods-android.os.Parcelable-summary" style="display: none;">
     <table class="jd-sumtable-expando">
-    
+
 
 
 
@@ -2232,6 +2232,7 @@
 
 
 
+
             void</nobr>
         </td>
         <td class="jd-linkcol" width="100%"><nobr>
@@ -3196,40 +3197,40 @@
 
 <A NAME="NUTRIENT_TOTAL_FAT"></A>
 
-<div class="jd-details api apilevel-"> 
+<div class="jd-details api apilevel-">
     <h4 class="jd-details-title">
       <span class="normal">
-        public 
-        static 
-        final 
+        public
+        static
+        final
         String
       </span>
         NUTRIENT_TOTAL_FAT
     </h4>
       <div class="api-level">
-        
-        
-  
+
+
+
 
       </div>
     <div class="jd-details-descr">
-      
-    
 
-      
+
+
+
   <div class="jd-tagdata jd-tagdescr"><p>Total fat in grams.
 </p></div>
 
-    
+
         <div class="jd-tagdata">
         <span class="jd-tagtitle">Constant Value: </span>
         <span>
-            
+
                 "fat.total"
-            
+
         </span>
         </div>
-    
+
     </div>
 </div>
 
@@ -3237,40 +3238,40 @@
 
 <A NAME="NUTRIENT_TRANS_FAT"></A>
 
-<div class="jd-details api apilevel-"> 
+<div class="jd-details api apilevel-">
     <h4 class="jd-details-title">
       <span class="normal">
-        public 
-        static 
-        final 
+        public
+        static
+        final
         String
       </span>
         NUTRIENT_TRANS_FAT
     </h4>
       <div class="api-level">
-        
-        
-  
+
+
+
 
       </div>
     <div class="jd-details-descr">
-      
-    
 
-      
+
+
+
   <div class="jd-tagdata jd-tagdescr"><p>Trans fat in grams.
 </p></div>
 
-    
+
         <div class="jd-tagdata">
         <span class="jd-tagtitle">Constant Value: </span>
         <span>
-            
+
                 "fat.trans"
-            
+
         </span>
         </div>
-    
+
     </div>
 </div>
 
@@ -3321,31 +3322,31 @@
 
 <A NAME="NUTRIENT_VITAMIN_C"></A>
 
-<div class="jd-details api apilevel-"> 
+<div class="jd-details api apilevel-">
     <h4 class="jd-details-title">
       <span class="normal">
-        public 
-        static 
-        final 
+        public
+        static
+        final
         String
       </span>
         NUTRIENT_VITAMIN_C
     </h4>
       <div class="api-level">
-        
-        
-  
+
+
+
 
       </div>
     <div class="jd-details-descr">
-      
-    
 
-      
+
+
+
   <div class="jd-tagdata jd-tagdescr"><p>Vitamin C amount in milligrams.
 </p></div>
 
-    
+
         <div class="jd-tagdata">
         <span class="jd-tagtitle">Constant Value: </span>
         <span>
@@ -3372,31 +3373,31 @@
 
 <A NAME="FIELD_ACCURACY"></A>
 
-<div class="jd-details api apilevel-"> 
+<div class="jd-details api apilevel-">
     <h4 class="jd-details-title">
       <span class="normal">
-        public 
-        static 
-        final 
+        public
+        static
+        final
         <a href="/reference/com/google/android/gms/fitness/data/Field.html">Field</a>
       </span>
         FIELD_ACCURACY
     </h4>
       <div class="api-level">
-        
-        
-  
+
+
+
 
       </div>
     <div class="jd-details-descr">
-      
-    
 
-      
+
+
+
   <div class="jd-tagdata jd-tagdescr"><p>The accuracy of an accompanied value (such as location).
 </p></div>
 
-    
+
     </div>
 </div>
 
@@ -3404,33 +3405,33 @@
 
 <A NAME="FIELD_ACTIVITY"></A>
 
-<div class="jd-details api apilevel-"> 
+<div class="jd-details api apilevel-">
     <h4 class="jd-details-title">
       <span class="normal">
-        public 
-        static 
-        final 
+        public
+        static
+        final
         <a href="/reference/com/google/android/gms/fitness/data/Field.html">Field</a>
       </span>
         FIELD_ACTIVITY
     </h4>
       <div class="api-level">
-        
-        
-  
+
+
+
 
       </div>
     <div class="jd-details-descr">
-      
-    
 
-      
+
+
+
   <div class="jd-tagdata jd-tagdescr"><p>An activity type of <code><a href="/reference/com/google/android/gms/fitness/FitnessActivities.html">FitnessActivities</a></code>, encoded as an integer for efficiency.  The
  activity value should be stored using <code><a href="/reference/com/google/android/gms/fitness/data/Value.html#setActivity(java.lang.String)">setActivity(String)</a></code>,
  and read using <code><a href="/reference/com/google/android/gms/fitness/data/Value.html#asActivity()">asActivity()</a></code>
 </p></div>
 
-    
+
     </div>
 </div>
 
@@ -3438,32 +3439,32 @@
 
 <A NAME="FIELD_ALTITUDE"></A>
 
-<div class="jd-details api apilevel-"> 
+<div class="jd-details api apilevel-">
     <h4 class="jd-details-title">
       <span class="normal">
-        public 
-        static 
-        final 
+        public
+        static
+        final
         <a href="/reference/com/google/android/gms/fitness/data/Field.html">Field</a>
       </span>
         FIELD_ALTITUDE
     </h4>
       <div class="api-level">
-        
-        
-  
+
+
+
 
       </div>
     <div class="jd-details-descr">
-      
-    
 
-      
+
+
+
   <div class="jd-tagdata jd-tagdescr"><p>An altitude of a location represented as a float, in meters above sea level.
  Some location samples don't have an altitude value so this field might not be set.
 </p></div>
 
-    
+
     </div>
 </div>
 
@@ -3471,31 +3472,31 @@
 
 <A NAME="FIELD_AVERAGE"></A>
 
-<div class="jd-details api apilevel-"> 
+<div class="jd-details api apilevel-">
     <h4 class="jd-details-title">
       <span class="normal">
-        public 
-        static 
-        final 
+        public
+        static
+        final
         <a href="/reference/com/google/android/gms/fitness/data/Field.html">Field</a>
       </span>
         FIELD_AVERAGE
     </h4>
       <div class="api-level">
-        
-        
-  
+
+
+
 
       </div>
     <div class="jd-details-descr">
-      
-    
 
-      
+
+
+
   <div class="jd-tagdata jd-tagdescr"><p>An average value.
 </p></div>
 
-    
+
     </div>
 </div>
 
@@ -3503,31 +3504,31 @@
 
 <A NAME="FIELD_BPM"></A>
 
-<div class="jd-details api apilevel-"> 
+<div class="jd-details api apilevel-">
     <h4 class="jd-details-title">
       <span class="normal">
-        public 
-        static 
-        final 
+        public
+        static
+        final
         <a href="/reference/com/google/android/gms/fitness/data/Field.html">Field</a>
       </span>
         FIELD_BPM
     </h4>
       <div class="api-level">
-        
-        
-  
+
+
+
 
       </div>
     <div class="jd-details-descr">
-      
-    
 
-      
+
+
+
   <div class="jd-tagdata jd-tagdescr"><p>A heart rate in beats per minute.
 </p></div>
 
-    
+
     </div>
 </div>
 
@@ -3535,31 +3536,31 @@
 
 <A NAME="FIELD_CALORIES"></A>
 
-<div class="jd-details api apilevel-"> 
+<div class="jd-details api apilevel-">
     <h4 class="jd-details-title">
       <span class="normal">
-        public 
-        static 
-        final 
+        public
+        static
+        final
         <a href="/reference/com/google/android/gms/fitness/data/Field.html">Field</a>
       </span>
         FIELD_CALORIES
     </h4>
       <div class="api-level">
-        
-        
-  
+
+
+
 
       </div>
     <div class="jd-details-descr">
-      
-    
 
-      
+
+
+
   <div class="jd-tagdata jd-tagdescr"><p>Calories in kcal.
 </p></div>
 
-    
+
     </div>
 </div>
 
@@ -3599,31 +3600,31 @@
 
 <A NAME="FIELD_CONFIDENCE"></A>
 
-<div class="jd-details api apilevel-"> 
+<div class="jd-details api apilevel-">
     <h4 class="jd-details-title">
       <span class="normal">
-        public 
-        static 
-        final 
+        public
+        static
+        final
         <a href="/reference/com/google/android/gms/fitness/data/Field.html">Field</a>
       </span>
         FIELD_CONFIDENCE
     </h4>
       <div class="api-level">
-        
-        
-  
+
+
+
 
       </div>
     <div class="jd-details-descr">
-      
-    
 
-      
+
+
+
   <div class="jd-tagdata jd-tagdescr"><p>The confidence of an accompanied value, specified as a value between 0.0 and 100.0.
 </p></div>
 
-    
+
     </div>
 </div>
 
@@ -3631,31 +3632,31 @@
 
 <A NAME="FIELD_DISTANCE"></A>
 
-<div class="jd-details api apilevel-"> 
+<div class="jd-details api apilevel-">
     <h4 class="jd-details-title">
       <span class="normal">
-        public 
-        static 
-        final 
+        public
+        static
+        final
         <a href="/reference/com/google/android/gms/fitness/data/Field.html">Field</a>
       </span>
         FIELD_DISTANCE
     </h4>
       <div class="api-level">
-        
-        
-  
+
+
+
 
       </div>
     <div class="jd-details-descr">
-      
-    
 
-      
+
+
+
   <div class="jd-tagdata jd-tagdescr"><p>A distance in meters.
 </p></div>
 
-    
+
     </div>
 </div>
 
@@ -3663,31 +3664,31 @@
 
 <A NAME="FIELD_DURATION"></A>
 
-<div class="jd-details api apilevel-"> 
+<div class="jd-details api apilevel-">
     <h4 class="jd-details-title">
       <span class="normal">
-        public 
-        static 
-        final 
+        public
+        static
+        final
         <a href="/reference/com/google/android/gms/fitness/data/Field.html">Field</a>
       </span>
         FIELD_DURATION
     </h4>
       <div class="api-level">
-        
-        
-  
+
+
+
 
       </div>
     <div class="jd-details-descr">
-      
-    
 
-      
+
+
+
   <div class="jd-tagdata jd-tagdescr"><p>A duration in milliseconds.
 </p></div>
 
-    
+
     </div>
 </div>
 
@@ -3727,31 +3728,31 @@
 
 <A NAME="FIELD_HEIGHT"></A>
 
-<div class="jd-details api apilevel-"> 
+<div class="jd-details api apilevel-">
     <h4 class="jd-details-title">
       <span class="normal">
-        public 
-        static 
-        final 
+        public
+        static
+        final
         <a href="/reference/com/google/android/gms/fitness/data/Field.html">Field</a>
       </span>
         FIELD_HEIGHT
     </h4>
       <div class="api-level">
-        
-        
-  
+
+
+
 
       </div>
     <div class="jd-details-descr">
-      
-    
 
-      
+
+
+
   <div class="jd-tagdata jd-tagdescr"><p>A height in meters.
 </p></div>
 
-    
+
     </div>
 </div>
 
@@ -3759,31 +3760,31 @@
 
 <A NAME="FIELD_HIGH_LATITUDE"></A>
 
-<div class="jd-details api apilevel-"> 
+<div class="jd-details api apilevel-">
     <h4 class="jd-details-title">
       <span class="normal">
-        public 
-        static 
-        final 
+        public
+        static
+        final
         <a href="/reference/com/google/android/gms/fitness/data/Field.html">Field</a>
       </span>
         FIELD_HIGH_LATITUDE
     </h4>
       <div class="api-level">
-        
-        
-  
+
+
+
 
       </div>
     <div class="jd-details-descr">
-      
-    
 
-      
+
+
+
   <div class="jd-tagdata jd-tagdescr"><p>A high latitude of a location bounding box represented as a float, in degrees.
 </p></div>
 
-    
+
     </div>
 </div>
 
@@ -3791,31 +3792,31 @@
 
 <A NAME="FIELD_HIGH_LONGITUDE"></A>
 
-<div class="jd-details api apilevel-"> 
+<div class="jd-details api apilevel-">
     <h4 class="jd-details-title">
       <span class="normal">
-        public 
-        static 
-        final 
+        public
+        static
+        final
         <a href="/reference/com/google/android/gms/fitness/data/Field.html">Field</a>
       </span>
         FIELD_HIGH_LONGITUDE
     </h4>
       <div class="api-level">
-        
-        
-  
+
+
+
 
       </div>
     <div class="jd-details-descr">
-      
-    
 
-      
+
+
+
   <div class="jd-tagdata jd-tagdescr"><p>A high longitude of a location bounding box represented as a float, in degrees.
 </p></div>
 
-    
+
     </div>
 </div>
 
@@ -3823,31 +3824,31 @@
 
 <A NAME="FIELD_LATITUDE"></A>
 
-<div class="jd-details api apilevel-"> 
+<div class="jd-details api apilevel-">
     <h4 class="jd-details-title">
       <span class="normal">
-        public 
-        static 
-        final 
+        public
+        static
+        final
         <a href="/reference/com/google/android/gms/fitness/data/Field.html">Field</a>
       </span>
         FIELD_LATITUDE
     </h4>
       <div class="api-level">
-        
-        
-  
+
+
+
 
       </div>
     <div class="jd-details-descr">
-      
-    
 
-      
+
+
+
   <div class="jd-tagdata jd-tagdescr"><p>A latitude of a location represented as a float, in degrees.
 </p></div>
 
-    
+
     </div>
 </div>
 
@@ -3855,31 +3856,31 @@
 
 <A NAME="FIELD_LONGITUDE"></A>
 
-<div class="jd-details api apilevel-"> 
+<div class="jd-details api apilevel-">
     <h4 class="jd-details-title">
       <span class="normal">
-        public 
-        static 
-        final 
+        public
+        static
+        final
         <a href="/reference/com/google/android/gms/fitness/data/Field.html">Field</a>
       </span>
         FIELD_LONGITUDE
     </h4>
       <div class="api-level">
-        
-        
-  
+
+
+
 
       </div>
     <div class="jd-details-descr">
-      
-    
 
-      
+
+
+
   <div class="jd-tagdata jd-tagdescr"><p>A longitude of a location represented as a float, in degrees.
 </p></div>
 
-    
+
     </div>
 </div>
 
@@ -3887,31 +3888,31 @@
 
 <A NAME="FIELD_LOW_LATITUDE"></A>
 
-<div class="jd-details api apilevel-"> 
+<div class="jd-details api apilevel-">
     <h4 class="jd-details-title">
       <span class="normal">
-        public 
-        static 
-        final 
+        public
+        static
+        final
         <a href="/reference/com/google/android/gms/fitness/data/Field.html">Field</a>
       </span>
         FIELD_LOW_LATITUDE
     </h4>
       <div class="api-level">
-        
-        
-  
+
+
+
 
       </div>
     <div class="jd-details-descr">
-      
-    
 
-      
+
+
+
   <div class="jd-tagdata jd-tagdescr"><p>A low latitude of a location bounding box represented as a float, in degrees.
 </p></div>
 
-    
+
     </div>
 </div>
 
@@ -3919,31 +3920,31 @@
 
 <A NAME="FIELD_LOW_LONGITUDE"></A>
 
-<div class="jd-details api apilevel-"> 
+<div class="jd-details api apilevel-">
     <h4 class="jd-details-title">
       <span class="normal">
-        public 
-        static 
-        final 
+        public
+        static
+        final
         <a href="/reference/com/google/android/gms/fitness/data/Field.html">Field</a>
       </span>
         FIELD_LOW_LONGITUDE
     </h4>
       <div class="api-level">
-        
-        
-  
+
+
+
 
       </div>
     <div class="jd-details-descr">
-      
-    
 
-      
+
+
+
   <div class="jd-tagdata jd-tagdescr"><p>A low longitude of a location bounding box represented as a float, in degrees.
 </p></div>
 
-    
+
     </div>
 </div>
 
@@ -3951,31 +3952,31 @@
 
 <A NAME="FIELD_MAX"></A>
 
-<div class="jd-details api apilevel-"> 
+<div class="jd-details api apilevel-">
     <h4 class="jd-details-title">
       <span class="normal">
-        public 
-        static 
-        final 
+        public
+        static
+        final
         <a href="/reference/com/google/android/gms/fitness/data/Field.html">Field</a>
       </span>
         FIELD_MAX
     </h4>
       <div class="api-level">
-        
-        
-  
+
+
+
 
       </div>
     <div class="jd-details-descr">
-      
-    
 
-      
+
+
+
   <div class="jd-tagdata jd-tagdescr"><p>A maximum value.
 </p></div>
 
-    
+
     </div>
 </div>
 
@@ -4015,31 +4016,31 @@
 
 <A NAME="FIELD_MIN"></A>
 
-<div class="jd-details api apilevel-"> 
+<div class="jd-details api apilevel-">
     <h4 class="jd-details-title">
       <span class="normal">
-        public 
-        static 
-        final 
+        public
+        static
+        final
         <a href="/reference/com/google/android/gms/fitness/data/Field.html">Field</a>
       </span>
         FIELD_MIN
     </h4>
       <div class="api-level">
-        
-        
-  
+
+
+
 
       </div>
     <div class="jd-details-descr">
-      
-    
 
-      
+
+
+
   <div class="jd-tagdata jd-tagdescr"><p>A minimum value.
 </p></div>
 
-    
+
     </div>
 </div>
 
@@ -4113,31 +4114,31 @@
 
 <A NAME="FIELD_PERCENTAGE"></A>
 
-<div class="jd-details api apilevel-"> 
+<div class="jd-details api apilevel-">
     <h4 class="jd-details-title">
       <span class="normal">
-        public 
-        static 
-        final 
+        public
+        static
+        final
         <a href="/reference/com/google/android/gms/fitness/data/Field.html">Field</a>
       </span>
         FIELD_PERCENTAGE
     </h4>
       <div class="api-level">
-        
-        
-  
+
+
+
 
       </div>
     <div class="jd-details-descr">
-      
-    
 
-      
+
+
+
   <div class="jd-tagdata jd-tagdescr"><p>A percentage value, between 0 and 100.
 </p></div>
 
-    
+
     </div>
 </div>
 
@@ -4145,31 +4146,31 @@
 
 <A NAME="FIELD_REVOLUTIONS"></A>
 
-<div class="jd-details api apilevel-"> 
+<div class="jd-details api apilevel-">
     <h4 class="jd-details-title">
       <span class="normal">
-        public 
-        static 
-        final 
+        public
+        static
+        final
         <a href="/reference/com/google/android/gms/fitness/data/Field.html">Field</a>
       </span>
         FIELD_REVOLUTIONS
     </h4>
       <div class="api-level">
-        
-        
-  
+
+
+
 
       </div>
     <div class="jd-details-descr">
-      
-    
 
-      
+
+
+
   <div class="jd-tagdata jd-tagdescr"><p>A count of revolutions.
 </p></div>
 
-    
+
     </div>
 </div>
 
@@ -4177,31 +4178,31 @@
 
 <A NAME="FIELD_RPM"></A>
 
-<div class="jd-details api apilevel-"> 
+<div class="jd-details api apilevel-">
     <h4 class="jd-details-title">
       <span class="normal">
-        public 
-        static 
-        final 
+        public
+        static
+        final
         <a href="/reference/com/google/android/gms/fitness/data/Field.html">Field</a>
       </span>
         FIELD_RPM
     </h4>
       <div class="api-level">
-        
-        
-  
+
+
+
 
       </div>
     <div class="jd-details-descr">
-      
-    
 
-      
+
+
+
   <div class="jd-tagdata jd-tagdescr"><p>Revolutions per minute or rate per minute.
 </p></div>
 
-    
+
     </div>
 </div>
 
@@ -4209,31 +4210,31 @@
 
 <A NAME="FIELD_SPEED"></A>
 
-<div class="jd-details api apilevel-"> 
+<div class="jd-details api apilevel-">
     <h4 class="jd-details-title">
       <span class="normal">
-        public 
-        static 
-        final 
+        public
+        static
+        final
         <a href="/reference/com/google/android/gms/fitness/data/Field.html">Field</a>
       </span>
         FIELD_SPEED
     </h4>
       <div class="api-level">
-        
-        
-  
+
+
+
 
       </div>
     <div class="jd-details-descr">
-      
-    
 
-      
+
+
+
   <div class="jd-tagdata jd-tagdescr"><p>A speed in meter/sec.
 </p></div>
 
-    
+
     </div>
 </div>
 
@@ -4241,31 +4242,31 @@
 
 <A NAME="FIELD_STEPS"></A>
 
-<div class="jd-details api apilevel-"> 
+<div class="jd-details api apilevel-">
     <h4 class="jd-details-title">
       <span class="normal">
-        public 
-        static 
-        final 
+        public
+        static
+        final
         <a href="/reference/com/google/android/gms/fitness/data/Field.html">Field</a>
       </span>
         FIELD_STEPS
     </h4>
       <div class="api-level">
-        
-        
-  
+
+
+
 
       </div>
     <div class="jd-details-descr">
-      
-    
 
-      
+
+
+
   <div class="jd-tagdata jd-tagdescr"><p>A count of steps.
 </p></div>
 
-    
+
     </div>
 </div>
 
@@ -4273,31 +4274,31 @@
 
 <A NAME="FIELD_WATTS"></A>
 
-<div class="jd-details api apilevel-"> 
+<div class="jd-details api apilevel-">
     <h4 class="jd-details-title">
       <span class="normal">
-        public 
-        static 
-        final 
+        public
+        static
+        final
         <a href="/reference/com/google/android/gms/fitness/data/Field.html">Field</a>
       </span>
         FIELD_WATTS
     </h4>
       <div class="api-level">
-        
-        
-  
+
+
+
 
       </div>
     <div class="jd-details-descr">
-      
-    
 
-      
+
+
+
   <div class="jd-tagdata jd-tagdescr"><p>Power in watts.
 </p></div>
 
-    
+
     </div>
 </div>
 
@@ -4305,31 +4306,31 @@
 
 <A NAME="FIELD_WEIGHT"></A>
 
-<div class="jd-details api apilevel-"> 
+<div class="jd-details api apilevel-">
     <h4 class="jd-details-title">
       <span class="normal">
-        public 
-        static 
-        final 
+        public
+        static
+        final
         <a href="/reference/com/google/android/gms/fitness/data/Field.html">Field</a>
       </span>
         FIELD_WEIGHT
     </h4>
       <div class="api-level">
-        
-        
-  
+
+
+
 
       </div>
     <div class="jd-details-descr">
-      
-    
 
-      
+
+
+
   <div class="jd-tagdata jd-tagdescr"><p>A weight in kilograms.
 </p></div>
 
-    
+
     </div>
 </div>
 
@@ -4354,14 +4355,14 @@
 
 <A NAME="describeContents()"></A>
 
-<div class="jd-details api apilevel-"> 
+<div class="jd-details api apilevel-">
     <h4 class="jd-details-title">
       <span class="normal">
-        public 
-         
-         
-         
-         
+        public
+
+
+
+
         int
       </span>
       <span class="sympad">describeContents</span>
@@ -4369,15 +4370,15 @@
     </h4>
       <div class="api-level">
         <div></div>
-        
-  
+
+
 
       </div>
     <div class="jd-details-descr">
-      
-    
 
-      
+
+
+
   <div class="jd-tagdata jd-tagdescr"><p></p></div>
 
     </div>
@@ -4386,14 +4387,14 @@
 
 <A NAME="equals(java.lang.Object)"></A>
 
-<div class="jd-details api apilevel-"> 
+<div class="jd-details api apilevel-">
     <h4 class="jd-details-title">
       <span class="normal">
-        public 
-         
-         
-         
-         
+        public
+
+
+
+
         boolean
       </span>
       <span class="sympad">equals</span>
@@ -4401,15 +4402,15 @@
     </h4>
       <div class="api-level">
         <div></div>
-        
-  
+
+
 
       </div>
     <div class="jd-details-descr">
-      
-    
 
-      
+
+
+
   <div class="jd-tagdata jd-tagdescr"><p></p></div>
 
     </div>
@@ -4418,14 +4419,14 @@
 
 <A NAME="getFormat()"></A>
 
-<div class="jd-details api apilevel-"> 
+<div class="jd-details api apilevel-">
     <h4 class="jd-details-title">
       <span class="normal">
-        public 
-         
-         
-         
-         
+        public
+
+
+
+
         int
       </span>
       <span class="sympad">getFormat</span>
@@ -4433,15 +4434,15 @@
     </h4>
       <div class="api-level">
         <div></div>
-        
-  
+
+
 
       </div>
     <div class="jd-details-descr">
-      
-    
 
-      
+
+
+
   <div class="jd-tagdata jd-tagdescr"><p>Returns the format of the field, as one of the format constant values.
 </p></div>
 
@@ -4451,14 +4452,14 @@
 
 <A NAME="getName()"></A>
 
-<div class="jd-details api apilevel-"> 
+<div class="jd-details api apilevel-">
     <h4 class="jd-details-title">
       <span class="normal">
-        public 
-         
-         
-         
-         
+        public
+
+
+
+
         String
       </span>
       <span class="sympad">getName</span>
@@ -4466,15 +4467,15 @@
     </h4>
       <div class="api-level">
         <div></div>
-        
-  
+
+
 
       </div>
     <div class="jd-details-descr">
-      
-    
 
-      
+
+
+
   <div class="jd-tagdata jd-tagdescr"><p>Returns the name of the field.
 </p></div>
 
@@ -4484,14 +4485,14 @@
 
 <A NAME="hashCode()"></A>
 
-<div class="jd-details api apilevel-"> 
+<div class="jd-details api apilevel-">
     <h4 class="jd-details-title">
       <span class="normal">
-        public 
-         
-         
-         
-         
+        public
+
+
+
+
         int
       </span>
       <span class="sympad">hashCode</span>
@@ -4499,15 +4500,15 @@
     </h4>
       <div class="api-level">
         <div></div>
-        
-  
+
+
 
       </div>
     <div class="jd-details-descr">
-      
-    
 
-      
+
+
+
   <div class="jd-tagdata jd-tagdescr"><p></p></div>
 
     </div>
@@ -4516,14 +4517,14 @@
 
 <A NAME="toString()"></A>
 
-<div class="jd-details api apilevel-"> 
+<div class="jd-details api apilevel-">
     <h4 class="jd-details-title">
       <span class="normal">
-        public 
-         
-         
-         
-         
+        public
+
+
+
+
         String
       </span>
       <span class="sympad">toString</span>
@@ -4531,15 +4532,15 @@
     </h4>
       <div class="api-level">
         <div></div>
-        
-  
+
+
 
       </div>
     <div class="jd-details-descr">
-      
-    
 
-      
+
+
+
   <div class="jd-tagdata jd-tagdescr"><p></p></div>
 
     </div>
@@ -4548,14 +4549,14 @@
 
 <A NAME="writeToParcel(android.os.Parcel, int)"></A>
 
-<div class="jd-details api apilevel-"> 
+<div class="jd-details api apilevel-">
     <h4 class="jd-details-title">
       <span class="normal">
-        public 
-         
-         
-         
-         
+        public
+
+
+
+
         void
       </span>
       <span class="sympad">writeToParcel</span>
@@ -4563,15 +4564,15 @@
     </h4>
       <div class="api-level">
         <div></div>
-        
-  
+
+
 
       </div>
     <div class="jd-details-descr">
-      
-    
 
-      
+
+
+
   <div class="jd-tagdata jd-tagdescr"><p></p></div>
 
     </div>
@@ -4589,17 +4590,17 @@
 <A NAME="navbar_top"></A>
 
 <div id="footer" class="wrap" >
-        
+
 
   <div id="copyright">
-    
+
   Except as noted, this content is licensed under <a
-  href="http://www.apache.org/licenses/LICENSE-2.0">Apache 2.0</a>. 
+  href="http://www.apache.org/licenses/LICENSE-2.0">Apache 2.0</a>.
   For details and restrictions, see the <a href="/license.html">
   Content License</a>.
   </div>
   <div id="build_info">
-    
+
 <script src="/timestamp.js" type="text/javascript"></script>
 <script>document.write(BUILD_TIMESTAMP)</script>
 
@@ -4607,7 +4608,7 @@
 
 
   <div id="footerlinks">
-    
+
   <p>
     <a href="/about/index.html">About Android</a>&nbsp;&nbsp;|&nbsp;
     <a href="/legal.html">Legal</a>&nbsp;&nbsp;|&nbsp;
@@ -4620,7 +4621,7 @@
 
 </div><!-- end doc-content -->
 
-</div> <!-- end body-content --> 
+</div> <!-- end body-content -->
 
 
 
diff --git a/docs/html/training/enterprise/app-restrictions.jd b/docs/html/training/enterprise/app-restrictions.jd
index fc5dfcc..dd2c2c0 100644
--- a/docs/html/training/enterprise/app-restrictions.jd
+++ b/docs/html/training/enterprise/app-restrictions.jd
@@ -316,8 +316,18 @@
   {@link android.content.Intent#ACTION_APPLICATION_RESTRICTIONS_CHANGED
   ACTION_APPLICATION_RESTRICTIONS_CHANGED} intent. Your app has to listen for
   this intent so you can change the app's behavior when the restriction settings
-  change. The following code shows how to dynamically register a broadcast
-  receiver for this intent:
+  change.</p>
+
+<p class="note">
+  <strong>Note:</strong> The {@link
+  android.content.Intent#ACTION_APPLICATION_RESTRICTIONS_CHANGED
+  ACTION_APPLICATION_RESTRICTIONS_CHANGED} intent is sent only to listeners
+  that are dynamically registered, <em>not</em> to listeners that are declared
+  in the app manifest.
+</p>
+<p>
+  The following code shows how to dynamically register a broadcast receiver for
+  this intent:
 </p>
 
 <pre>IntentFilter restrictionsFilter =
diff --git a/graphics/java/android/graphics/Paint.java b/graphics/java/android/graphics/Paint.java
index 649d996..6385706 100644
--- a/graphics/java/android/graphics/Paint.java
+++ b/graphics/java/android/graphics/Paint.java
@@ -185,7 +185,9 @@
     public static final int VERTICAL_TEXT_FLAG = 0x1000;
 
     // we use this when we first create a paint
-    static final int DEFAULT_PAINT_FLAGS = DEV_KERN_TEXT_FLAG | EMBEDDED_BITMAP_TEXT_FLAG;
+    private static final int HIDDEN_DEFAULT_PAINT_FLAGS =
+            DEV_KERN_TEXT_FLAG | EMBEDDED_BITMAP_TEXT_FLAG;
+    private static final int DEFAULT_PAINT_FLAGS = ANTI_ALIAS_FLAG;
 
     /**
      * Font hinter option that disables font hinting.
@@ -415,9 +417,11 @@
 
     /**
      * Create a new paint with default settings.
+     *
+     * As of {@link android.os.Build.VERSION_CODES#MNC}, sets {@link #ANTI_ALIAS_FLAG}.
      */
     public Paint() {
-        this(0);
+        this(DEFAULT_PAINT_FLAGS);
     }
 
     /**
@@ -428,7 +432,7 @@
      */
     public Paint(int flags) {
         mNativePaint = native_init();
-        setFlags(flags | DEFAULT_PAINT_FLAGS);
+        setFlags(flags | HIDDEN_DEFAULT_PAINT_FLAGS);
         // TODO: Turning off hinting has undesirable side effects, we need to
         //       revisit hinting once we add support for subpixel positioning
         // setHinting(DisplayMetrics.DENSITY_DEVICE >= DisplayMetrics.DENSITY_TV
@@ -452,7 +456,7 @@
     /** Restores the paint to its default settings. */
     public void reset() {
         native_reset(mNativePaint);
-        setFlags(DEFAULT_PAINT_FLAGS);
+        setFlags(DEFAULT_PAINT_FLAGS | HIDDEN_DEFAULT_PAINT_FLAGS);
 
         // TODO: Turning off hinting has undesirable side effects, we need to
         //       revisit hinting once we add support for subpixel positioning
@@ -1870,7 +1874,7 @@
      * Convenience overload that takes a char array instead of a
      * String.
      *
-     * @see #getTextRunAdvances(String, int, int, int, int, int, float[], int)
+     * @see #getTextRunAdvances(String, int, int, int, int, boolean, float[], int)
      * @hide
      */
     public float getTextRunAdvances(char[] chars, int index, int count,
@@ -1915,7 +1919,7 @@
      * Convenience overload that takes a CharSequence instead of a
      * String.
      *
-     * @see #getTextRunAdvances(String, int, int, int, int, int, float[], int)
+     * @see #getTextRunAdvances(String, int, int, int, int, boolean, float[], int)
      * @hide
      */
     public float getTextRunAdvances(CharSequence text, int start, int end,
diff --git a/media/java/android/media/AudioRecord.java b/media/java/android/media/AudioRecord.java
index 8bbfb51..513e4c8 100644
--- a/media/java/android/media/AudioRecord.java
+++ b/media/java/android/media/AudioRecord.java
@@ -20,6 +20,7 @@
 import java.lang.annotation.RetentionPolicy;
 import java.lang.ref.WeakReference;
 import java.nio.ByteBuffer;
+import java.util.Collection;
 import java.util.Iterator;
 
 import android.annotation.IntDef;
@@ -32,6 +33,7 @@
 import android.os.Message;
 import android.os.RemoteException;
 import android.os.ServiceManager;
+import android.util.ArrayMap;
 import android.util.Log;
 
 /**
@@ -113,6 +115,11 @@
      */
     private static final int NATIVE_EVENT_NEW_POS = 3;
 
+    /**
+     * Event id denotes when the routing changes.
+     */
+    private final static int NATIVE_EVENT_ROUTING_CHANGE = 1000;
+
     private final static String TAG = "android.media.AudioRecord";
 
     /** @hide */
@@ -1127,7 +1134,7 @@
      * Sets the listener the AudioRecord notifies when a previously set marker is reached or
      * for each periodic record head position update.
      * Use this method to receive AudioRecord events in the Handler associated with another
-     * thread than the one in which you created the AudioTrack instance.
+     * thread than the one in which you created the AudioRecord instance.
      * @param listener
      * @param handler the Handler that will receive the event notification messages.
      */
@@ -1168,6 +1175,115 @@
     }
 
 
+    //--------------------------------------------------------------------------
+    // (Re)Routing Info
+    //--------------------
+    /**
+     * Returns an {@link AudioDeviceInfo} identifying the current routing of this AudioRecord.
+     */
+    public AudioDeviceInfo getRoutedDevice() {
+        return null;
+    }
+
+    /**
+     * The message sent to apps when the routing of this AudioRecord changes if they provide
+     * a {#link Handler} object to addOnAudioRecordRoutingListener().
+     */
+    private ArrayMap<OnAudioRecordRoutingListener, NativeRoutingEventHandlerDelegate>
+        mRoutingChangeListeners =
+            new ArrayMap<OnAudioRecordRoutingListener, NativeRoutingEventHandlerDelegate>();
+
+    /**
+     * Adds an {@link OnAudioRecordRoutingListener} to receive notifications of routing changes
+     * on this AudioRecord.
+     */
+    public void addOnAudioRecordRoutingListener(OnAudioRecordRoutingListener listener,
+            android.os.Handler handler) {
+        if (listener != null && !mRoutingChangeListeners.containsKey(listener)) {
+            synchronized (mRoutingChangeListeners) {
+                mRoutingChangeListeners.put(
+                    listener, new NativeRoutingEventHandlerDelegate(this, listener, handler));
+            }
+        }
+    }
+
+    /**
+     * Removes an {@link OnAudioRecordRoutingListener} which has been previously added
+     * to receive notifications of changes to the set of connected audio devices.
+     */
+    public void removeOnAudioRecordRoutingListener(OnAudioRecordRoutingListener listener) {
+        synchronized (mRoutingChangeListeners) {
+            if (mRoutingChangeListeners.containsKey(listener)) {
+                mRoutingChangeListeners.remove(listener);
+            }
+        }
+    }
+
+    /**
+     * Helper class to handle the forwarding of native events to the appropriate listener
+     * (potentially) handled in a different thread
+     */
+    private class NativeRoutingEventHandlerDelegate {
+        private final Handler mHandler;
+
+        NativeRoutingEventHandlerDelegate(final AudioRecord record,
+                                   final OnAudioRecordRoutingListener listener,
+                                   Handler handler) {
+            // find the looper for our new event handler
+            Looper looper;
+            if (handler != null) {
+                looper = handler.getLooper();
+            } else {
+                // no given handler, use the looper the AudioRecord was created in
+                looper = mInitializationLooper;
+            }
+
+            // construct the event handler with this looper
+            if (looper != null) {
+                // implement the event handler delegate
+                mHandler = new Handler(looper) {
+                    @Override
+                    public void handleMessage(Message msg) {
+                        if (record == null) {
+                            return;
+                        }
+                        switch(msg.what) {
+                        case NATIVE_EVENT_ROUTING_CHANGE:
+                            if (listener != null) {
+                                listener.onAudioRecordRouting(record);
+                            }
+                            break;
+                        default:
+                            loge("Unknown native event type: " + msg.what);
+                            break;
+                        }
+                    }
+                };
+            } else {
+                mHandler = null;
+            }
+        }
+
+        Handler getHandler() {
+            return mHandler;
+        }
+    }
+    /**
+     * Sends device list change notification to all listeners.
+     */
+    private void broadcastRoutingChange() {
+        Collection<NativeRoutingEventHandlerDelegate> values;
+        synchronized (mRoutingChangeListeners) {
+            values = mRoutingChangeListeners.values();
+        }
+        for(NativeRoutingEventHandlerDelegate delegate : values) {
+            Handler handler = delegate.getHandler();
+            if (handler != null) {
+                handler.sendEmptyMessage(NATIVE_EVENT_ROUTING_CHANGE);
+            }
+        }
+    }
+
     /**
      * Sets the period at which the listener is called, if set with
      * {@link #setRecordPositionUpdateListener(OnRecordPositionUpdateListener)} or
@@ -1184,6 +1300,39 @@
     }
 
 
+    //--------------------------------------------------------------------------
+    // Explicit Routing
+    //--------------------
+    private AudioDeviceInfo mPreferredDevice = null;
+
+    /**
+     * Specifies an audio device (via an {@link AudioDeviceInfo} object) to route
+     * the input to this AudioRecord.
+     * @param deviceInfo The {@link AudioDeviceInfo} specifying the audio source.
+     *  If deviceInfo is null, default routing is restored.
+     * @return true if successful, false if the specified {@link AudioDeviceInfo} is non-null and
+     * does not correspond to a valid audio input device.
+     */
+    public boolean setPreferredInputDevice(AudioDeviceInfo deviceInfo) {
+        // Do some validation....
+        if (deviceInfo != null && !deviceInfo.isSource()) {
+            return false;
+        }
+
+        mPreferredDevice = deviceInfo;
+        int preferredDeviceId = mPreferredDevice != null ? deviceInfo.getId() : 0;
+
+        return native_setInputDevice(preferredDeviceId);
+    }
+
+    /**
+     * Returns the selected input specified by {@link #setPreferredInputDevice}. Note that this
+     * is not guarenteed to correspond to the actual device being used for recording.
+     */
+    public AudioDeviceInfo getPreferredInputDevice() {
+        return mPreferredDevice;
+    }
+
     //---------------------------------------------------------
     // Interface definitions
     //--------------------
@@ -1314,6 +1463,8 @@
     static private native final int native_get_min_buff_size(
             int sampleRateInHz, int channelCount, int audioFormat);
 
+    private native final boolean native_setInputDevice(int deviceId);
+
 
     //---------------------------------------------------------
     // Utility methods
diff --git a/media/java/android/media/AudioTrack.java b/media/java/android/media/AudioTrack.java
index 093ff26..6785ebc 100644
--- a/media/java/android/media/AudioTrack.java
+++ b/media/java/android/media/AudioTrack.java
@@ -23,6 +23,7 @@
 import java.nio.ByteBuffer;
 import java.nio.ByteOrder;
 import java.nio.NioUtils;
+import java.util.Collection;
 
 import android.annotation.IntDef;
 import android.annotation.NonNull;
@@ -37,6 +38,7 @@
 import android.os.Process;
 import android.os.RemoteException;
 import android.os.ServiceManager;
+import android.util.ArrayMap;
 import android.util.Log;
 
 import com.android.internal.app.IAppOpsService;
@@ -176,6 +178,12 @@
      */
     private static final int NATIVE_EVENT_NEW_POS = 4;
 
+    /**
+     * Event id denotes when the routing changes.
+     */
+    private final static int NATIVE_EVENT_ROUTING_CHANGE = 1000;
+
+
     private final static String TAG = "android.media.AudioTrack";
 
 
@@ -224,7 +232,7 @@
     /**
      * Handler for events coming from the native code.
      */
-    private NativeEventHandlerDelegate mEventHandlerDelegate;
+    private NativePositionEventHandlerDelegate mEventHandlerDelegate;
     /**
      * Looper associated with the thread that creates the AudioTrack instance.
      */
@@ -1243,7 +1251,7 @@
     public void setPlaybackPositionUpdateListener(OnPlaybackPositionUpdateListener listener,
                                                     Handler handler) {
         if (listener != null) {
-            mEventHandlerDelegate = new NativeEventHandlerDelegate(this, listener, handler);
+            mEventHandlerDelegate = new NativePositionEventHandlerDelegate(this, listener, handler);
         } else {
             mEventHandlerDelegate = null;
         }
@@ -2082,33 +2090,93 @@
     private AudioDeviceInfo mPreferredDevice = null;
 
     /**
-     * Specifies an audio device (via and {@link AudioDeviceInfo} object) to route
+     * Specifies an audio device (via an {@link AudioDeviceInfo} object) to route
      * the output from this AudioTrack.
-     * @param deviceSpec The {@link AudioDeviceInfo} specifying the physical audio device.
-     *  If deviceSpec is null, default routing is restored.
+     * @param deviceInfo The {@link AudioDeviceInfo} specifying the audio sink.
+     *  If deviceInfo is null, default routing is restored.
      * @return true if succesful, false if the specified {@link AudioDeviceInfo} is non-null and
      * does not correspond to a valid audio output device.
      */
-    public boolean setPreferredOutputDevice(AudioDeviceInfo deviceSpec) {
+    public boolean setPreferredOutputDevice(AudioDeviceInfo deviceInfo) {
         // Do some validation....
-        if (deviceSpec != null && !deviceSpec.isSink()) {
+        if (deviceInfo != null && !deviceInfo.isSink()) {
             return false;
         }
 
-        mPreferredDevice = deviceSpec;
-        int routingDeviceId = mPreferredDevice != null ? deviceSpec.getId() : 0;
+        mPreferredDevice = deviceInfo;
+        int preferredDeviceId = mPreferredDevice != null ? deviceInfo.getId() : 0;
 
-        return native_setOutputDevice(routingDeviceId);
+        return native_setOutputDevice(preferredDeviceId);
     }
 
     /**
      * Returns the selected output specified by {@link #setPreferredOutputDevice}. Note that this
-     * is not guarenteed to correspond to the actual device being used for playback.
+     * is not guaranteed to correspond to the actual device being used for playback.
      */
     public AudioDeviceInfo getPreferredOutputDevice() {
         return mPreferredDevice;
     }
 
+    //--------------------------------------------------------------------------
+    // (Re)Routing Info
+    //--------------------
+    /**
+     * Returns an {@link AudioDeviceInfo} identifying the current routing of this AudioTrack.
+     */
+    public AudioDeviceInfo getRoutedDevice() {
+        return null;
+    }
+
+    /**
+     * The message sent to apps when the routing of this AudioTrack changes if they provide
+     * a {#link Handler} object to addOnAudioTrackRoutingListener().
+     */
+    private ArrayMap<OnAudioTrackRoutingListener, NativeRoutingEventHandlerDelegate>
+        mRoutingChangeListeners =
+            new ArrayMap<OnAudioTrackRoutingListener, NativeRoutingEventHandlerDelegate>();
+
+    /**
+     * Adds an {@link OnAudioTrackRoutingListener} to receive notifications of routing changes
+     * on this AudioTrack.
+     */
+    public void addOnAudioTrackRoutingListener(OnAudioTrackRoutingListener listener,
+            android.os.Handler handler) {
+        if (listener != null && !mRoutingChangeListeners.containsKey(listener)) {
+            synchronized (mRoutingChangeListeners) {
+                mRoutingChangeListeners.put(
+                    listener, new NativeRoutingEventHandlerDelegate(this, listener, handler));
+            }
+        }
+    }
+
+    /**
+     * Removes an {@link OnAudioTrackRoutingListener} which has been previously added
+     * to receive notifications of changes to the set of connected audio devices.
+     */
+    public void removeOnAudioTrackRoutingListener(OnAudioTrackRoutingListener listener) {
+        synchronized (mRoutingChangeListeners) {
+            if (mRoutingChangeListeners.containsKey(listener)) {
+                mRoutingChangeListeners.remove(listener);
+            }
+        }
+    }
+
+    /**
+     * Sends device list change notification to all listeners.
+     */
+    private void broadcastRoutingChange() {
+        Collection<NativeRoutingEventHandlerDelegate> values;
+        synchronized (mRoutingChangeListeners) {
+            values = mRoutingChangeListeners.values();
+        }
+        for(NativeRoutingEventHandlerDelegate delegate : values) {
+            Handler handler = delegate.getHandler();
+            if (handler != null) {
+                handler.sendEmptyMessage(NATIVE_EVENT_ROUTING_CHANGE);
+            }
+        }
+    }
+
     //---------------------------------------------------------
     // Interface definitions
     //--------------------
@@ -2137,10 +2205,10 @@
      * Helper class to handle the forwarding of native events to the appropriate listener
      * (potentially) handled in a different thread
      */
-    private class NativeEventHandlerDelegate {
+    private class NativePositionEventHandlerDelegate {
         private final Handler mHandler;
 
-        NativeEventHandlerDelegate(final AudioTrack track,
+        NativePositionEventHandlerDelegate(final AudioTrack track,
                                    final OnPlaybackPositionUpdateListener listener,
                                    Handler handler) {
             // find the looper for our new event handler
@@ -2188,6 +2256,55 @@
         }
     }
 
+    /**
+     * Helper class to handle the forwarding of native events to the appropriate listener
+     * (potentially) handled in a different thread
+     */
+    private class NativeRoutingEventHandlerDelegate {
+        private final Handler mHandler;
+
+        NativeRoutingEventHandlerDelegate(final AudioTrack track,
+                                   final OnAudioTrackRoutingListener listener,
+                                   Handler handler) {
+            // find the looper for our new event handler
+            Looper looper;
+            if (handler != null) {
+                looper = handler.getLooper();
+            } else {
+                // no given handler, use the looper the AudioTrack was created in
+                looper = mInitializationLooper;
+            }
+
+            // construct the event handler with this looper
+            if (looper != null) {
+                // implement the event handler delegate
+                mHandler = new Handler(looper) {
+                    @Override
+                    public void handleMessage(Message msg) {
+                        if (track == null) {
+                            return;
+                        }
+                        switch(msg.what) {
+                        case NATIVE_EVENT_ROUTING_CHANGE:
+                            if (listener != null) {
+                                listener.onAudioTrackRouting(track);
+                            }
+                            break;
+                        default:
+                            loge("Unknown native event type: " + msg.what);
+                            break;
+                        }
+                    }
+                };
+            } else {
+                mHandler = null;
+            }
+        }
+
+        Handler getHandler() {
+            return mHandler;
+        }
+    }
 
     //---------------------------------------------------------
     // Java methods called from the native side
@@ -2201,7 +2318,7 @@
             return;
         }
 
-        NativeEventHandlerDelegate delegate = track.mEventHandlerDelegate;
+        NativePositionEventHandlerDelegate delegate = track.mEventHandlerDelegate;
         if (delegate != null) {
             Handler handler = delegate.getHandler();
             if (handler != null) {
diff --git a/media/java/android/media/OnAudioRecordRoutingListener.java b/media/java/android/media/OnAudioRecordRoutingListener.java
new file mode 100644
index 0000000..8ff41c5
--- /dev/null
+++ b/media/java/android/media/OnAudioRecordRoutingListener.java
@@ -0,0 +1,29 @@
+/*
+ * Copyright (C) 2015 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 android.media;
+
+/**
+ * OnAudioDeviceConnectionListener defines the interface for notification listeners in the
+ * {@link AudioDevicesManager}
+ */
+public interface OnAudioRecordRoutingListener {
+    /**
+     * Called when the routing of an AudioRecord changes from either and explicit or
+     * policy rerouting.
+     */
+    public void onAudioRecordRouting(AudioRecord audioRecord);
+}
diff --git a/media/java/android/media/OnAudioTrackRoutingListener.java b/media/java/android/media/OnAudioTrackRoutingListener.java
new file mode 100644
index 0000000..18c72ef
--- /dev/null
+++ b/media/java/android/media/OnAudioTrackRoutingListener.java
@@ -0,0 +1,29 @@
+/*
+ * Copyright (C) 2015 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 android.media;
+
+/**
+ * OnAudioDeviceConnectionListener defines the interface for notification listeners in the
+ * {@link AudioDevicesManager}
+ */
+public interface OnAudioTrackRoutingListener {
+    /**
+     * Called when the routing of an AudioTrack changes from either and explicit or
+     * policy rerouting.
+     */
+    public void onAudioTrackRouting(AudioTrack audioTrack);
+}
diff --git a/packages/DocumentsUI/Android.mk b/packages/DocumentsUI/Android.mk
index 2f97809..67d8ab6 100644
--- a/packages/DocumentsUI/Android.mk
+++ b/packages/DocumentsUI/Android.mk
@@ -11,3 +11,5 @@
 LOCAL_CERTIFICATE := platform
 
 include $(BUILD_PACKAGE)
+
+include $(LOCAL_PATH)/tests/Android.mk
diff --git a/packages/DocumentsUI/res/values/strings.xml b/packages/DocumentsUI/res/values/strings.xml
index 062d433..5281087 100644
--- a/packages/DocumentsUI/res/values/strings.xml
+++ b/packages/DocumentsUI/res/values/strings.xml
@@ -121,22 +121,20 @@
     <string name="copy_remaining"><xliff:g id="duration" example="3 minutes">%s</xliff:g> left</string>
     <!-- Toast shown when a file copy is kicked off -->
     <plurals name="copy_begin">
-      <item quantity="one">Copying <xliff:g id="count" example="1">%1$d</xliff:g> file.</item>
-      <item quantity="other">Copying <xliff:g id="count" example="3">%1$d</xliff:g> files.</item>
+        <item quantity="one">Copying <xliff:g id="count" example="1">%1$d</xliff:g> file.</item>
+        <item quantity="other">Copying <xliff:g id="count" example="3">%1$d</xliff:g> files.</item>
     </plurals>
     <!-- Text shown on the copy notification while DocumentsUI performs setup in preparation for copying files [CHAR LIMIT=32] -->
     <string name="copy_preparing">Preparing for copy\u2026</string>
     <!-- Title of the copy error notification [CHAR LIMIT=48] -->
     <plurals name="copy_error_notification_title">
-      <item quantity="one">Error copying <xliff:g id="count" example="1">%1$d</xliff:g> file.</item>
-      <item quantity="other">Error copying <xliff:g id="count" example="1">%1$d</xliff:g> files.</item>
+        <item quantity="one">Couldn\'t copy <xliff:g id="count" example="1">%1$d</xliff:g> file</item>
+        <item quantity="other">Couldn\'t copy <xliff:g id="count" example="2">%1$d</xliff:g> files</item>
     </plurals>
     <!-- Second line for notifications saying that more information will be shown after touching [CHAR LIMIT=48] -->
     <string name="notification_touch_for_details">Touch to view details</string>
     <!-- Label of a dialog button for retrying a failed operation [CHAR LIMIT=24] -->
     <string name="retry">Retry</string>
-    <!-- Title of the copying failure alert dialog. [CHAR LIMIT=48] -->
-    <string name="copy_failure_alert_title">Error copying files</string>
     <!-- Contents of the copying failure alert dialog. [CHAR LIMIT=48] -->
-    <string name="copy_failure_alert_content">Following files are not copied: <xliff:g id="list">%1$s</xliff:g></string>
+    <string name="copy_failure_alert_content">These files weren\'t copied: <xliff:g id="list">%1$s</xliff:g></string>
 </resources>
diff --git a/packages/DocumentsUI/src/com/android/documentsui/CopyService.java b/packages/DocumentsUI/src/com/android/documentsui/CopyService.java
index a9f03b6..2e0bece 100644
--- a/packages/DocumentsUI/src/com/android/documentsui/CopyService.java
+++ b/packages/DocumentsUI/src/com/android/documentsui/CopyService.java
@@ -26,6 +26,7 @@
 import android.content.ContentProviderClient;
 import android.content.Context;
 import android.content.Intent;
+import android.content.res.Resources;
 import android.database.Cursor;
 import android.net.Uri;
 import android.os.CancellationSignal;
@@ -37,12 +38,14 @@
 import android.provider.DocumentsContract.Document;
 import android.text.format.DateUtils;
 import android.util.Log;
+import android.widget.Toast;
 
 import com.android.documentsui.model.DocumentInfo;
 import com.android.documentsui.model.DocumentStack;
 
 import libcore.io.IoUtils;
 
+import java.io.FileNotFoundException;
 import java.io.IOException;
 import java.io.InputStream;
 import java.io.OutputStream;
@@ -70,7 +73,7 @@
     private volatile boolean mIsCancelled;
     // Parameters of the copy job. Requests to an IntentService are serialized so this code only
     // needs to deal with one job at a time.
-    private final ArrayList<Uri> mFailedFiles;
+    private final ArrayList<DocumentInfo> mFailedFiles;
     private long mBatchSize;
     private long mBytesCopied;
     private long mStartTime;
@@ -88,7 +91,27 @@
     public CopyService() {
         super("CopyService");
 
-        mFailedFiles = new ArrayList<Uri>();
+        mFailedFiles = new ArrayList<DocumentInfo>();
+    }
+
+    /**
+     * Starts the service for a copy operation.
+     *
+     * @param context Context for the intent.
+     * @param srcDocs A list of src files to copy.
+     * @param dstStack The copy destination stack.
+     */
+    public static void start(Context context, List<DocumentInfo> srcDocs, DocumentStack dstStack) {
+        final Resources res = context.getResources();
+        final Intent copyIntent = new Intent(context, CopyService.class);
+        copyIntent.putParcelableArrayListExtra(
+                EXTRA_SRC_LIST, new ArrayList<DocumentInfo>(srcDocs));
+        copyIntent.putExtra(EXTRA_STACK, (Parcelable) dstStack);
+
+        Toast.makeText(context,
+                res.getQuantityString(R.plurals.copy_begin, srcDocs.size(), srcDocs.size()),
+                Toast.LENGTH_SHORT).show();
+        context.startService(copyIntent);
     }
 
     @Override
@@ -360,7 +383,7 @@
         if (dstUri == null) {
             // If this is a directory, the entire subdir will not be copied over.
             Log.e(TAG, "Error while copying " + srcInfo.displayName);
-            mFailedFiles.add(srcInfo.derivedUri);
+            mFailedFiles.add(srcInfo);
             return;
         }
 
@@ -444,7 +467,12 @@
         } catch (IOException e) {
             errorOccurred = true;
             Log.e(TAG, "Error while copying " + srcUri.toString(), e);
-            mFailedFiles.add(srcUri);
+            try {
+                mFailedFiles.add(DocumentInfo.fromUri(getContentResolver(), srcUri));
+            } catch (FileNotFoundException ignore) {
+                Log.w(TAG, "Source file gone: " + srcUri, e);
+              // The source file is gone.
+            }
         } finally {
             // This also ensures the file descriptors are closed.
             IoUtils.closeQuietly(src);
diff --git a/packages/DocumentsUI/src/com/android/documentsui/DirectoryFragment.java b/packages/DocumentsUI/src/com/android/documentsui/DirectoryFragment.java
index 7cf58cc..a789da8 100644
--- a/packages/DocumentsUI/src/com/android/documentsui/DirectoryFragment.java
+++ b/packages/DocumentsUI/src/com/android/documentsui/DirectoryFragment.java
@@ -82,6 +82,7 @@
 import com.android.documentsui.ProviderExecutor.Preemptable;
 import com.android.documentsui.RecentsProvider.StateColumns;
 import com.android.documentsui.model.DocumentInfo;
+import com.android.documentsui.model.DocumentStack;
 import com.android.documentsui.model.RootInfo;
 import com.google.android.collect.Lists;
 
@@ -341,9 +342,6 @@
 
     @Override
     public void onActivityResult(int requestCode, int resultCode, Intent data) {
-        final Context context = getActivity();
-        final Resources res = context.getResources();
-
         // There's only one request code right now. Replace this with a switch statement or
         // something more scalable when more codes are added.
         if (requestCode != REQUEST_COPY_DESTINATION) {
@@ -355,15 +353,8 @@
             return;
         }
 
-        final List<DocumentInfo> docs = getDisplayState(this).selectedDocumentsForCopy;
-        final Intent copyIntent = new Intent(context, CopyService.class);
-        copyIntent.putParcelableArrayListExtra(CopyService.EXTRA_SRC_LIST, new ArrayList<DocumentInfo>(docs));
-        copyIntent.putExtra(CopyService.EXTRA_STACK, data.getParcelableExtra(CopyService.EXTRA_STACK));
-
-        Toast.makeText(context,
-                res.getQuantityString(R.plurals.copy_begin, docs.size(), docs.size()),
-                Toast.LENGTH_SHORT).show();
-        context.startService(copyIntent);
+        CopyService.start(getActivity(), getDisplayState(this).selectedDocumentsForCopy,
+                (DocumentStack) data.getParcelableExtra(CopyService.EXTRA_STACK));
     }
 
     @Override
diff --git a/packages/DocumentsUI/src/com/android/documentsui/FailureDialogFragment.java b/packages/DocumentsUI/src/com/android/documentsui/FailureDialogFragment.java
index 1748c9c..00b0f78 100644
--- a/packages/DocumentsUI/src/com/android/documentsui/FailureDialogFragment.java
+++ b/packages/DocumentsUI/src/com/android/documentsui/FailureDialogFragment.java
@@ -20,6 +20,7 @@
 import android.app.AlertDialog;
 import android.app.Dialog;
 import android.app.DialogFragment;
+import android.app.Fragment;
 import android.app.FragmentManager;
 import android.app.FragmentTransaction;
 import android.content.DialogInterface;
@@ -27,7 +28,9 @@
 import android.os.Bundle;
 import android.text.Html;
 
+import com.android.documentsui.CopyService;
 import com.android.documentsui.model.DocumentInfo;
+import com.android.documentsui.model.DocumentStack;
 
 import java.io.FileNotFoundException;
 import java.util.ArrayList;
@@ -40,9 +43,10 @@
     private static final String TAG = "FailureDialogFragment";
 
     private int mFailure;
-    private ArrayList<Uri> mFailedSrcList;
+    private ArrayList<DocumentInfo> mFailedSrcList;
 
-    public static void show(FragmentManager fm, int failure, ArrayList<Uri> failedSrcList) {
+    public static void show(FragmentManager fm, int failure,
+            ArrayList<DocumentInfo> failedSrcList, DocumentStack dstStack) {
         // TODO: Add support for other failures than copy.
         if (failure != CopyService.FAILURE_COPY) {
             return;
@@ -62,7 +66,11 @@
 
     @Override
     public void onClick(DialogInterface dialog, int whichButton) {
-      // TODO: Pass mFailure and mFailedSrcList to the parent fragment.
+      if (whichButton == DialogInterface.BUTTON_POSITIVE) {
+          CopyService.start(getActivity(), mFailedSrcList,
+                  (DocumentStack) getActivity().getIntent().getParcelableExtra(
+                          CopyService.EXTRA_STACK));
+      }
     }
 
     @Override
@@ -73,27 +81,17 @@
         mFailedSrcList = getArguments().getParcelableArrayList(CopyService.EXTRA_SRC_LIST);
 
         final StringBuilder list = new StringBuilder("<p>");
-        for (Uri documentUri : mFailedSrcList) {
-            try {
-                final DocumentInfo documentInfo = DocumentInfo.fromUri(
-                    getActivity().getContentResolver(), documentUri);
-                list.append(String.format("&#8226; %s<br>", documentInfo.displayName));
-            }
-            catch (FileNotFoundException ignore) {
-                // Source file most probably gone.
-            }
+        for (DocumentInfo documentInfo : mFailedSrcList) {
+            list.append(String.format("&#8226; %s<br>", documentInfo.displayName));
         }
         list.append("</p>");
         final String message = String.format(getString(R.string.copy_failure_alert_content),
                 list.toString());
 
         return new AlertDialog.Builder(getActivity())
-            .setTitle(getString(R.string.copy_failure_alert_title))
             .setMessage(Html.fromHtml(message))
-            // TODO: Implement retrying the copy operation.
             .setPositiveButton(R.string.retry, this)
             .setNegativeButton(android.R.string.cancel, this)
-            .setIcon(android.R.drawable.ic_dialog_alert)
             .create();
     }
 }
diff --git a/packages/DocumentsUI/src/com/android/documentsui/StandaloneActivity.java b/packages/DocumentsUI/src/com/android/documentsui/StandaloneActivity.java
index 1d021cb..cad277d 100644
--- a/packages/DocumentsUI/src/com/android/documentsui/StandaloneActivity.java
+++ b/packages/DocumentsUI/src/com/android/documentsui/StandaloneActivity.java
@@ -106,12 +106,15 @@
         RootsFragment.show(getFragmentManager(), null);
         if (!mState.restored) {
             new RestoreStackTask().execute();
+
+            // Show a failure dialog if there was a failed operation.
             final Intent intent = getIntent();
+            final DocumentStack dstStack = intent.getParcelableExtra(CopyService.EXTRA_STACK);
             final int failure = intent.getIntExtra(CopyService.EXTRA_FAILURE, 0);
             if (failure != 0) {
-                final ArrayList<Uri> failedSrcList = intent.getParcelableArrayListExtra(
-                        CopyService.EXTRA_SRC_LIST);
-                FailureDialogFragment.show(getFragmentManager(), failure, failedSrcList);
+                final ArrayList<DocumentInfo> failedSrcList =
+                        intent.getParcelableArrayListExtra(CopyService.EXTRA_SRC_LIST);
+                FailureDialogFragment.show(getFragmentManager(), failure, failedSrcList, dstStack);
             }
         } else {
             onCurrentDirectoryChanged(ANIM_NONE);
diff --git a/packages/ExternalStorageProvider/src/com/android/externalstorage/ExternalStorageProvider.java b/packages/ExternalStorageProvider/src/com/android/externalstorage/ExternalStorageProvider.java
index aff57bf..73a723d 100644
--- a/packages/ExternalStorageProvider/src/com/android/externalstorage/ExternalStorageProvider.java
+++ b/packages/ExternalStorageProvider/src/com/android/externalstorage/ExternalStorageProvider.java
@@ -45,7 +45,6 @@
 import android.webkit.MimeTypeMap;
 
 import com.android.internal.annotations.GuardedBy;
-import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.util.IndentingPrintWriter;
 
 import java.io.File;
@@ -55,7 +54,6 @@
 import java.io.PrintWriter;
 import java.util.LinkedList;
 import java.util.List;
-import java.util.Objects;
 
 public class ExternalStorageProvider extends DocumentsProvider {
     private static final String TAG = "ExternalStorage";
@@ -327,7 +325,7 @@
             throw new IllegalArgumentException("Parent document isn't a directory");
         }
 
-        final File file = buildUniqueFile(parent, mimeType, displayName);
+        final File file = FileUtils.buildUniqueFile(parent, mimeType, displayName);
         if (Document.MIME_TYPE_DIR.equals(mimeType)) {
             if (!file.mkdir()) {
                 throw new IllegalStateException("Failed to mkdir " + file);
@@ -345,68 +343,6 @@
         return getDocIdForFile(file);
     }
 
-    private static File buildFile(File parent, String name, String ext) {
-        if (TextUtils.isEmpty(ext)) {
-            return new File(parent, name);
-        } else {
-            return new File(parent, name + "." + ext);
-        }
-    }
-
-    @VisibleForTesting
-    public static File buildUniqueFile(File parent, String mimeType, String displayName)
-            throws FileNotFoundException {
-        String name;
-        String ext;
-
-        if (Document.MIME_TYPE_DIR.equals(mimeType)) {
-            name = displayName;
-            ext = null;
-        } else {
-            String mimeTypeFromExt;
-
-            // Extract requested extension from display name
-            final int lastDot = displayName.lastIndexOf('.');
-            if (lastDot >= 0) {
-                name = displayName.substring(0, lastDot);
-                ext = displayName.substring(lastDot + 1);
-                mimeTypeFromExt = MimeTypeMap.getSingleton().getMimeTypeFromExtension(
-                        ext.toLowerCase());
-            } else {
-                name = displayName;
-                ext = null;
-                mimeTypeFromExt = null;
-            }
-
-            if (mimeTypeFromExt == null) {
-                mimeTypeFromExt = "application/octet-stream";
-            }
-
-            final String extFromMimeType = MimeTypeMap.getSingleton().getExtensionFromMimeType(
-                    mimeType);
-            if (Objects.equals(mimeType, mimeTypeFromExt) || Objects.equals(ext, extFromMimeType)) {
-                // Extension maps back to requested MIME type; allow it
-            } else {
-                // No match; insist that create file matches requested MIME
-                name = displayName;
-                ext = extFromMimeType;
-            }
-        }
-
-        File file = buildFile(parent, name, ext);
-
-        // If conflicting file, try adding counter suffix
-        int n = 0;
-        while (file.exists()) {
-            if (n++ >= 32) {
-                throw new FileNotFoundException("Failed to create unique file");
-            }
-            file = buildFile(parent, name + " (" + n + ")", ext);
-        }
-
-        return file;
-    }
-
     @Override
     public String renameDocument(String docId, String displayName) throws FileNotFoundException {
         // Since this provider treats renames as generating a completely new
diff --git a/packages/ExternalStorageProvider/tests/Android.mk b/packages/ExternalStorageProvider/tests/Android.mk
deleted file mode 100644
index 830731a..0000000
--- a/packages/ExternalStorageProvider/tests/Android.mk
+++ /dev/null
@@ -1,16 +0,0 @@
-
-LOCAL_PATH := $(call my-dir)
-include $(CLEAR_VARS)
-
-LOCAL_MODULE_TAGS := tests
-
-LOCAL_SRC_FILES := $(call all-java-files-under, src)
-
-LOCAL_JAVA_LIBRARIES := android.test.runner
-
-LOCAL_PACKAGE_NAME := ExternalStorageProviderTests
-LOCAL_INSTRUMENTATION_FOR := ExternalStorageProvider
-
-LOCAL_CERTIFICATE := platform
-
-include $(BUILD_PACKAGE)
diff --git a/packages/ExternalStorageProvider/tests/AndroidManifest.xml b/packages/ExternalStorageProvider/tests/AndroidManifest.xml
deleted file mode 100644
index ffcd499..0000000
--- a/packages/ExternalStorageProvider/tests/AndroidManifest.xml
+++ /dev/null
@@ -1,13 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<manifest xmlns:android="http://schemas.android.com/apk/res/android"
-    package="com.android.externalstorage.tests">
-
-    <application>
-        <uses-library android:name="android.test.runner" />
-    </application>
-
-    <instrumentation android:name="android.test.InstrumentationTestRunner"
-        android:targetPackage="com.android.externalstorage"
-        android:label="Tests for ExternalStorageProvider" />
-
-</manifest>
diff --git a/packages/ExternalStorageProvider/tests/src/com/android/externalstorage/ExternalStorageProviderTest.java b/packages/ExternalStorageProvider/tests/src/com/android/externalstorage/ExternalStorageProviderTest.java
deleted file mode 100644
index f980b60..0000000
--- a/packages/ExternalStorageProvider/tests/src/com/android/externalstorage/ExternalStorageProviderTest.java
+++ /dev/null
@@ -1,90 +0,0 @@
-/*
- * Copyright (C) 2013 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.externalstorage;
-
-import static com.android.externalstorage.ExternalStorageProvider.buildUniqueFile;
-
-import android.os.FileUtils;
-import android.provider.DocumentsContract.Document;
-import android.test.AndroidTestCase;
-import android.test.suitebuilder.annotation.MediumTest;
-
-import java.io.File;
-
-@MediumTest
-public class ExternalStorageProviderTest extends AndroidTestCase {
-
-    private File mTarget;
-
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-        mTarget = getContext().getFilesDir();
-        FileUtils.deleteContents(mTarget);
-    }
-
-    @Override
-    protected void tearDown() throws Exception {
-        super.tearDown();
-        FileUtils.deleteContents(mTarget);
-    }
-
-    public void testBuildUniqueFile_normal() throws Exception {
-        assertNameEquals("test.jpg", buildUniqueFile(mTarget, "image/jpeg", "test"));
-        assertNameEquals("test.jpg", buildUniqueFile(mTarget, "image/jpeg", "test.jpg"));
-        assertNameEquals("test.jpeg", buildUniqueFile(mTarget, "image/jpeg", "test.jpeg"));
-        assertNameEquals("TEst.JPeg", buildUniqueFile(mTarget, "image/jpeg", "TEst.JPeg"));
-        assertNameEquals("test.png.jpg", buildUniqueFile(mTarget, "image/jpeg", "test.png.jpg"));
-        assertNameEquals("test.png.jpg", buildUniqueFile(mTarget, "image/jpeg", "test.png"));
-
-        assertNameEquals("test.flac", buildUniqueFile(mTarget, "audio/flac", "test"));
-        assertNameEquals("test.flac", buildUniqueFile(mTarget, "audio/flac", "test.flac"));
-        assertNameEquals("test.flac", buildUniqueFile(mTarget, "application/x-flac", "test"));
-        assertNameEquals("test.flac", buildUniqueFile(mTarget, "application/x-flac", "test.flac"));
-    }
-
-    public void testBuildUniqueFile_unknown() throws Exception {
-        assertNameEquals("test", buildUniqueFile(mTarget, "application/octet-stream", "test"));
-        assertNameEquals("test.jpg", buildUniqueFile(mTarget, "application/octet-stream", "test.jpg"));
-        assertNameEquals(".test", buildUniqueFile(mTarget, "application/octet-stream", ".test"));
-
-        assertNameEquals("test", buildUniqueFile(mTarget, "lolz/lolz", "test"));
-        assertNameEquals("test.lolz", buildUniqueFile(mTarget, "lolz/lolz", "test.lolz"));
-    }
-
-    public void testBuildUniqueFile_dir() throws Exception {
-        assertNameEquals("test", buildUniqueFile(mTarget, Document.MIME_TYPE_DIR, "test"));
-        new File(mTarget, "test").mkdir();
-        assertNameEquals("test (1)", buildUniqueFile(mTarget, Document.MIME_TYPE_DIR, "test"));
-
-        assertNameEquals("test.jpg", buildUniqueFile(mTarget, Document.MIME_TYPE_DIR, "test.jpg"));
-        new File(mTarget, "test.jpg").mkdir();
-        assertNameEquals("test.jpg (1)", buildUniqueFile(mTarget, Document.MIME_TYPE_DIR, "test.jpg"));
-    }
-
-    public void testBuildUniqueFile_increment() throws Exception {
-        assertNameEquals("test.jpg", buildUniqueFile(mTarget, "image/jpeg", "test.jpg"));
-        new File(mTarget, "test.jpg").createNewFile();
-        assertNameEquals("test (1).jpg", buildUniqueFile(mTarget, "image/jpeg", "test.jpg"));
-        new File(mTarget, "test (1).jpg").createNewFile();
-        assertNameEquals("test (2).jpg", buildUniqueFile(mTarget, "image/jpeg", "test.jpg"));
-    }
-
-    private static void assertNameEquals(String expected, File actual) {
-        assertEquals(expected, actual.getName());
-    }
-}
diff --git a/packages/Keyguard/src/com/android/keyguard/CarrierText.java b/packages/Keyguard/src/com/android/keyguard/CarrierText.java
index 4fbcc1e..e083c9c 100644
--- a/packages/Keyguard/src/com/android/keyguard/CarrierText.java
+++ b/packages/Keyguard/src/com/android/keyguard/CarrierText.java
@@ -18,6 +18,7 @@
 
 import java.util.List;
 import java.util.Locale;
+import java.util.Objects;
 
 import android.content.Context;
 import android.content.Intent;
@@ -141,7 +142,11 @@
                         plmn = i.getStringExtra(TelephonyIntents.EXTRA_PLMN);
                     }
                     if (DEBUG) Log.d(TAG, "Getting plmn/spn sticky brdcst " + plmn + "/" + spn);
-                    text = concatenate(plmn, spn);
+                    if (Objects.equals(plmn, spn)) {
+                        text = plmn;
+                    } else {
+                        text = concatenate(plmn, spn);
+                    }
                 }
                 displayText =  makeCarrierStringOnEmergencyCapable(
                         getContext().getText(R.string.keyguard_missing_sim_message_short), text);
@@ -293,11 +298,7 @@
         final boolean plmnValid = !TextUtils.isEmpty(plmn);
         final boolean spnValid = !TextUtils.isEmpty(spn);
         if (plmnValid && spnValid) {
-            if (plmn.equals(spn)) {
-                return plmn;
-            } else {
-                return new StringBuilder().append(plmn).append(mSeparator).append(spn).toString();
-            }
+            return new StringBuilder().append(plmn).append(mSeparator).append(spn).toString();
         } else if (plmnValid) {
             return plmn;
         } else if (spnValid) {
diff --git a/packages/SettingsLib/src/com/android/settingslib/deviceinfo/StorageMeasurement.java b/packages/SettingsLib/src/com/android/settingslib/deviceinfo/StorageMeasurement.java
new file mode 100644
index 0000000..e0af29d
--- /dev/null
+++ b/packages/SettingsLib/src/com/android/settingslib/deviceinfo/StorageMeasurement.java
@@ -0,0 +1,441 @@
+/*
+ * 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.settingslib.deviceinfo;
+
+import android.app.ActivityManager;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.content.ServiceConnection;
+import android.content.pm.ApplicationInfo;
+import android.content.pm.IPackageStatsObserver;
+import android.content.pm.PackageManager;
+import android.content.pm.PackageStats;
+import android.content.pm.UserInfo;
+import android.os.Environment;
+import android.os.Handler;
+import android.os.HandlerThread;
+import android.os.IBinder;
+import android.os.Looper;
+import android.os.Message;
+import android.os.UserHandle;
+import android.os.UserManager;
+import android.os.storage.StorageVolume;
+import android.os.storage.VolumeInfo;
+import android.util.Log;
+import android.util.SparseLongArray;
+
+import com.android.internal.app.IMediaContainerService;
+import com.android.internal.util.ArrayUtils;
+import com.google.android.collect.Sets;
+
+import java.io.File;
+import java.lang.ref.WeakReference;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Objects;
+import java.util.Set;
+
+/**
+ * Utility for measuring the disk usage of internal storage or a physical
+ * {@link StorageVolume}. Connects with a remote {@link IMediaContainerService}
+ * and delivers results to {@link MeasurementReceiver}.
+ */
+public class StorageMeasurement {
+    private static final String TAG = "StorageMeasurement";
+
+    private static final boolean LOCAL_LOGV = true;
+    static final boolean LOGV = LOCAL_LOGV && Log.isLoggable(TAG, Log.VERBOSE);
+
+    private static final String DEFAULT_CONTAINER_PACKAGE = "com.android.defcontainer";
+
+    public static final ComponentName DEFAULT_CONTAINER_COMPONENT = new ComponentName(
+            DEFAULT_CONTAINER_PACKAGE, "com.android.defcontainer.DefaultContainerService");
+
+    /** Media types to measure on external storage. */
+    private static final Set<String> sMeasureMediaTypes = Sets.newHashSet(
+            Environment.DIRECTORY_DCIM, Environment.DIRECTORY_MOVIES,
+            Environment.DIRECTORY_PICTURES, Environment.DIRECTORY_MUSIC,
+            Environment.DIRECTORY_ALARMS, Environment.DIRECTORY_NOTIFICATIONS,
+            Environment.DIRECTORY_RINGTONES, Environment.DIRECTORY_PODCASTS,
+            Environment.DIRECTORY_DOWNLOADS, Environment.DIRECTORY_ANDROID);
+
+    public static class MeasurementDetails {
+        /**
+         * Total apps disk usage.
+         * <p>
+         * When measuring internal storage, this value includes the code size of
+         * all apps (regardless of install status for current user), and
+         * internal disk used by the current user's apps. When the device
+         * emulates external storage, this value also includes emulated storage
+         * used by the current user's apps.
+         * <p>
+         * When measuring a physical {@link StorageVolume}, this value includes
+         * usage by all apps on that volume.
+         */
+        public long appsSize;
+
+        /**
+         * Total cache disk usage by apps.
+         */
+        public long cacheSize;
+
+        /**
+         * Total media disk usage, categorized by types such as
+         * {@link Environment#DIRECTORY_MUSIC}.
+         * <p>
+         * When measuring internal storage, this reflects media on emulated
+         * storage for the current user.
+         * <p>
+         * When measuring a physical {@link StorageVolume}, this reflects media
+         * on that volume.
+         */
+        public HashMap<String, Long> mediaSize = new HashMap<>();
+
+        /**
+         * Misc external disk usage for the current user, unaccounted in
+         * {@link #mediaSize}.
+         */
+        public long miscSize;
+
+        /**
+         * Total disk usage for users, which is only meaningful for emulated
+         * internal storage. Key is {@link UserHandle}.
+         */
+        public SparseLongArray usersSize = new SparseLongArray();
+    }
+
+    public interface MeasurementReceiver {
+        public void onDetailsChanged(MeasurementDetails details);
+    }
+
+    private WeakReference<MeasurementReceiver> mReceiver;
+
+    private final Context mContext;
+
+    private final VolumeInfo mVolume;
+    private final VolumeInfo mSharedVolume;
+
+    private final MainHandler mMainHandler;
+    private final MeasurementHandler mMeasurementHandler;
+
+    public StorageMeasurement(Context context, VolumeInfo volume, VolumeInfo sharedVolume) {
+        mContext = context.getApplicationContext();
+
+        mVolume = volume;
+        mSharedVolume = sharedVolume;
+
+        // Start the thread that will measure the disk usage.
+        final HandlerThread handlerThread = new HandlerThread("MemoryMeasurement");
+        handlerThread.start();
+
+        mMainHandler = new MainHandler();
+        mMeasurementHandler = new MeasurementHandler(handlerThread.getLooper());
+    }
+
+    public void setReceiver(MeasurementReceiver receiver) {
+        if (mReceiver == null || mReceiver.get() == null) {
+            mReceiver = new WeakReference<MeasurementReceiver>(receiver);
+        }
+    }
+
+    public void forceMeasure() {
+        invalidate();
+        measure();
+    }
+
+    public void measure() {
+        if (!mMeasurementHandler.hasMessages(MeasurementHandler.MSG_MEASURE)) {
+            mMeasurementHandler.sendEmptyMessage(MeasurementHandler.MSG_MEASURE);
+        }
+    }
+
+    public void onDestroy() {
+        mReceiver = null;
+        mMeasurementHandler.removeMessages(MeasurementHandler.MSG_MEASURE);
+        mMeasurementHandler.sendEmptyMessage(MeasurementHandler.MSG_DISCONNECT);
+    }
+
+    private void invalidate() {
+        mMeasurementHandler.sendEmptyMessage(MeasurementHandler.MSG_INVALIDATE);
+    }
+
+    private static class StatsObserver extends IPackageStatsObserver.Stub {
+        private final boolean mIsPrivate;
+        private final MeasurementDetails mDetails;
+        private final int mCurrentUser;
+        private final Message mFinished;
+
+        private int mRemaining;
+
+        public StatsObserver(boolean isPrivate, MeasurementDetails details, int currentUser,
+                Message finished, int remaining) {
+            mIsPrivate = isPrivate;
+            mDetails = details;
+            mCurrentUser = currentUser;
+            mFinished = finished;
+            mRemaining = remaining;
+        }
+
+        @Override
+        public void onGetStatsCompleted(PackageStats stats, boolean succeeded) {
+            synchronized (mDetails) {
+                if (succeeded) {
+                    addStatsLocked(stats);
+                }
+                if (--mRemaining == 0) {
+                    mFinished.sendToTarget();
+                }
+            }
+        }
+
+        private void addStatsLocked(PackageStats stats) {
+            if (mIsPrivate) {
+                long codeSize = stats.codeSize;
+                long dataSize = stats.dataSize;
+                long cacheSize = stats.cacheSize;
+                if (Environment.isExternalStorageEmulated()) {
+                    // Include emulated storage when measuring internal. OBB is
+                    // shared on emulated storage, so treat as code.
+                    codeSize += stats.externalCodeSize + stats.externalObbSize;
+                    dataSize += stats.externalDataSize + stats.externalMediaSize;
+                    cacheSize += stats.externalCacheSize;
+                }
+
+                // Count code and data for current user
+                if (stats.userHandle == mCurrentUser) {
+                    mDetails.appsSize += codeSize;
+                    mDetails.appsSize += dataSize;
+                }
+
+                // User summary only includes data (code is only counted once
+                // for the current user)
+                addValue(mDetails.usersSize, stats.userHandle, dataSize);
+
+                // Include cache for all users
+                mDetails.cacheSize += cacheSize;
+
+            } else {
+                // Physical storage; only count external sizes
+                mDetails.appsSize += stats.externalCodeSize + stats.externalDataSize
+                        + stats.externalMediaSize + stats.externalObbSize;
+                mDetails.cacheSize += stats.externalCacheSize;
+            }
+        }
+    }
+
+    private class MainHandler extends Handler {
+        @Override
+        public void handleMessage(Message msg) {
+            final MeasurementDetails details = (MeasurementDetails) msg.obj;
+            final MeasurementReceiver receiver = (mReceiver != null) ? mReceiver.get() : null;
+            if (receiver != null) {
+                receiver.onDetailsChanged(details);
+            }
+        }
+    }
+
+    private class MeasurementHandler extends Handler {
+        public static final int MSG_MEASURE = 1;
+        public static final int MSG_CONNECTED = 2;
+        public static final int MSG_DISCONNECT = 3;
+        public static final int MSG_COMPLETED = 4;
+        public static final int MSG_INVALIDATE = 5;
+
+        private Object mLock = new Object();
+
+        private IMediaContainerService mDefaultContainer;
+
+        private volatile boolean mBound = false;
+
+        private MeasurementDetails mCached;
+
+        private final ServiceConnection mDefContainerConn = new ServiceConnection() {
+            @Override
+            public void onServiceConnected(ComponentName name, IBinder service) {
+                final IMediaContainerService imcs = IMediaContainerService.Stub.asInterface(
+                        service);
+                mDefaultContainer = imcs;
+                mBound = true;
+                sendMessage(obtainMessage(MSG_CONNECTED, imcs));
+            }
+
+            @Override
+            public void onServiceDisconnected(ComponentName name) {
+                mBound = false;
+                removeMessages(MSG_CONNECTED);
+            }
+        };
+
+        public MeasurementHandler(Looper looper) {
+            super(looper);
+        }
+
+        @Override
+        public void handleMessage(Message msg) {
+            switch (msg.what) {
+                case MSG_MEASURE: {
+                    if (mCached != null) {
+                        mMainHandler.obtainMessage(0, mCached).sendToTarget();
+                        break;
+                    }
+
+                    synchronized (mLock) {
+                        if (mBound) {
+                            removeMessages(MSG_DISCONNECT);
+                            sendMessage(obtainMessage(MSG_CONNECTED, mDefaultContainer));
+                        } else {
+                            Intent service = new Intent().setComponent(DEFAULT_CONTAINER_COMPONENT);
+                            mContext.bindServiceAsUser(service, mDefContainerConn,
+                                    Context.BIND_AUTO_CREATE, UserHandle.OWNER);
+                        }
+                    }
+                    break;
+                }
+                case MSG_CONNECTED: {
+                    final IMediaContainerService imcs = (IMediaContainerService) msg.obj;
+                    measureExactStorage(imcs);
+                    break;
+                }
+                case MSG_DISCONNECT: {
+                    synchronized (mLock) {
+                        if (mBound) {
+                            mBound = false;
+                            mContext.unbindService(mDefContainerConn);
+                        }
+                    }
+                    break;
+                }
+                case MSG_COMPLETED: {
+                    mCached = (MeasurementDetails) msg.obj;
+                    mMainHandler.obtainMessage(0, mCached).sendToTarget();
+                    break;
+                }
+                case MSG_INVALIDATE: {
+                    mCached = null;
+                    break;
+                }
+            }
+        }
+    }
+
+    private void measureExactStorage(IMediaContainerService imcs) {
+        final UserManager userManager = mContext.getSystemService(UserManager.class);
+        final PackageManager packageManager = mContext.getPackageManager();
+
+        final List<UserInfo> users = userManager.getUsers();
+        final int currentUser = ActivityManager.getCurrentUser();
+
+        final MeasurementDetails details = new MeasurementDetails();
+        final Message finished = mMeasurementHandler.obtainMessage(MeasurementHandler.MSG_COMPLETED,
+                details);
+
+        if (mSharedVolume != null && mSharedVolume.isMountedReadable()) {
+            final File basePath = mSharedVolume.getPathForUser(currentUser);
+
+            // Measure media types for emulated storage, or for primary physical
+            // external volume
+            for (String type : sMeasureMediaTypes) {
+                final File path = new File(basePath, type);
+                final long size = getDirectorySize(imcs, path);
+                details.mediaSize.put(type, size);
+            }
+
+            // Measure misc files not counted under media
+            details.miscSize = measureMisc(imcs, basePath);
+
+            if (mSharedVolume.getType() == VolumeInfo.TYPE_EMULATED) {
+                // Measure total emulated storage of all users; internal apps data
+                // will be spliced in later
+                for (UserInfo user : users) {
+                    final File userPath = mSharedVolume.getPathForUser(user.id);
+                    final long size = getDirectorySize(imcs, userPath);
+                    addValue(details.usersSize, user.id, size);
+                }
+            }
+        }
+
+        // Measure all apps hosted on this volume for all users
+        if (mVolume.getType() == VolumeInfo.TYPE_PRIVATE) {
+            final List<ApplicationInfo> apps = packageManager.getInstalledApplications(
+                    PackageManager.GET_UNINSTALLED_PACKAGES
+                    | PackageManager.GET_DISABLED_COMPONENTS);
+
+            final List<ApplicationInfo> volumeApps = new ArrayList<>();
+            for (ApplicationInfo app : apps) {
+                if (Objects.equals(app.volumeUuid, mVolume.getFsUuid())) {
+                    volumeApps.add(app);
+                }
+            }
+
+            final int count = users.size() * volumeApps.size();
+            if (count == 0) {
+                finished.sendToTarget();
+                return;
+            }
+
+            final StatsObserver observer = new StatsObserver(
+                    true, details, currentUser, finished, count);
+            for (UserInfo user : users) {
+                for (ApplicationInfo app : volumeApps) {
+                    packageManager.getPackageSizeInfo(app.packageName, user.id, observer);
+                }
+            }
+
+        } else {
+            finished.sendToTarget();
+            return;
+        }
+    }
+
+    private static long getDirectorySize(IMediaContainerService imcs, File path) {
+        try {
+            final long size = imcs.calculateDirectorySize(path.toString());
+            Log.d(TAG, "getDirectorySize(" + path + ") returned " + size);
+            return size;
+        } catch (Exception e) {
+            Log.w(TAG, "Could not read memory from default container service for " + path, e);
+            return 0;
+        }
+    }
+
+    private long measureMisc(IMediaContainerService imcs, File dir) {
+        final File[] files = dir.listFiles();
+        if (ArrayUtils.isEmpty(files)) return 0;
+
+        // Get sizes of all top level nodes except the ones already computed
+        long miscSize = 0;
+        for (File file : files) {
+            final String name = file.getName();
+            if (sMeasureMediaTypes.contains(name)) {
+                continue;
+            }
+
+            if (file.isFile()) {
+                miscSize += file.length();
+            } else if (file.isDirectory()) {
+                miscSize += getDirectorySize(imcs, file);
+            }
+        }
+        return miscSize;
+    }
+
+    private static void addValue(SparseLongArray array, int key, long value) {
+        array.put(key, array.get(key) + value);
+    }
+}
diff --git a/packages/SettingsProvider/src/com/android/providers/settings/SettingsState.java b/packages/SettingsProvider/src/com/android/providers/settings/SettingsState.java
index 0385d1e..8d99a64 100644
--- a/packages/SettingsProvider/src/com/android/providers/settings/SettingsState.java
+++ b/packages/SettingsProvider/src/com/android/providers/settings/SettingsState.java
@@ -387,6 +387,7 @@
         } catch (Throwable t) {
             Slog.wtf(LOG_TAG, "Failed to write settings, restoring backup", t);
             destination.failWrite(out);
+            throw new IllegalStateException("Failed to write settings, restoring backup", t);
         } finally {
             IoUtils.closeQuietly(out);
         }
@@ -408,10 +409,9 @@
             parser.setInput(in, null);
             parseStateLocked(parser);
 
-            // Any error while parsing is fatal.
-        } catch (Throwable t) {
+        } catch (XmlPullParserException | IOException e) {
             throw new IllegalStateException("Failed parsing settings file: "
-                    + mStatePersistFile , t);
+                    + mStatePersistFile , e);
         } finally {
             IoUtils.closeQuietly(in);
         }
diff --git a/packages/SystemUI/docs/demo_mode.md b/packages/SystemUI/docs/demo_mode.md
index f694b8c..18ae4cb 100644
--- a/packages/SystemUI/docs/demo_mode.md
+++ b/packages/SystemUI/docs/demo_mode.md
@@ -22,38 +22,39 @@
 <br/>
 Commands are sent as string extras with key ```command``` (required). Possible values are:
 
-Command              | Subcommand         | Argument      | Description
----                  | ---                | ---           | ---
-```enter```          |                    |               | Enters demo mode, bar state allowed to be modified (for convenience, any of the other non-exit commands will automatically flip demo mode on, no need to call this explicitly in practice)
-```exit```           |                    |               | Exits demo mode, bars back to their system-driven state
-```battery```        |                    |               | Control the battery display
-                     | ```level```        |               | Sets the battery level (0 - 100)
-                     | ```plugged```      |               | Sets charging state (```true```, ```false```)
-```network```        |                    |               | Control the RSSI display
-                     | ```airplane```     |               | ```show``` to show icon, any other value to hide
-                     | ```fully```        |               | Sets MCS state to fully connected (```true```, ```false```)
-                     | ```wifi```         |               | ```show``` to show icon, any other value to hide
-                     |                    |```level```    | Sets wifi level (null or 0-4)
-                     | ```mobile```       |               | ```show``` to show icon, any other value to hide
-                     |                    |```datatype``` | Values: ```1x```, ```3g```, ```4g```, ```e```, ```g```, ```h```, ```lte```, ```roam```, any other value to hide
-                     |                    |```level```    | Sets mobile signal strength level (null or 0-4)
-```bars```           |                    |               | Control the visual style of the bars (opaque, translucent, etc)
-                     | ```mode```         |               | Sets the bars visual style (opaque, translucent, semi-transparent)
-```status```         |                    |               | Control the system status icons
-                     | ```volume```       |               | Sets the icon in the volume slot (```silent```, ```vibrate```, any other value to hide)
-                     | ```bluetooth```    |               | Sets the icon in the bluetooth slot (```connected```, ```disconnected```, any other value to hide)
-                     | ```location```     |               | Sets the icon in the location slot (```show```, any other value to hide)
-                     | ```alarm```        |               | Sets the icon in the alarm_clock slot (```show```, any other value to hide)
-                     | ```sync```         |               | Sets the icon in the sync_active slot (```show```, any other value to hide)
-                     | ```tty```          |               | Sets the icon in the tty slot (```show```, any other value to hide)
-                     | ```eri```          |               | Sets the icon in the cdma_eri slot (```show```, any other value to hide)
-                     | ```mute```         |               | Sets the icon in the mute slot (```show```, any other value to hide)
-                     | ```speakerphone``` |               | Sets the icon in the speakerphone slot (```show```, any other value to hide)
-```notifications```  |                    |               | Control the notification icons
-                     | ```visible```      |               | ```false``` to hide the notification icons, any other value to show
-```clock```          |                    |               | Control the clock display
-                     | ```millis```       |               | Sets the time in millis
-                     | ```hhmm```         |               | Sets the time in hh:mm
+Command              | Subcommand                 | Argument       | Description
+---                  | ---                        | ---            | ---
+```enter```          |                            |                | Enters demo mode, bar state allowed to be modified (for convenience, any of the other non-exit commands will automatically flip demo mode on, no need to call this explicitly in practice)
+```exit```           |                            |                | Exits demo mode, bars back to their system-driven state
+```battery```        |                            |                | Control the battery display
+                     | ```level```                |                | Sets the battery level (0 - 100)
+                     | ```plugged```              |                | Sets charging state (```true```, ```false```)
+```network```        |                            |                | Control the RSSI display
+                     | ```airplane```             |                | ```show``` to show icon, any other value to hide
+                     | ```fully```                |                | Sets MCS state to fully connected (```true```, ```false```)
+                     | ```wifi```                 |                | ```show``` to show icon, any other value to hide
+                     |                            | ```level```    | Sets wifi level (null or 0-4)
+                     | ```mobile```               |                | ```show``` to show icon, any other value to hide
+                     |                            | ```datatype``` | Values: ```1x```, ```3g```, ```4g```, ```e```, ```g```, ```h```, ```lte```, ```roam```, any other value to hide
+                     |                            | ```level```    | Sets mobile signal strength level (null or 0-4)
+                     | ```carriernetworkchange``` |                | Sets mobile signal icon to carrier network change UX when disconnected (```show``` to show icon, any other value to hide)
+```bars```           |                            |                | Control the visual style of the bars (opaque, translucent, etc)
+                     | ```mode```                 |                | Sets the bars visual style (opaque, translucent, semi-transparent)
+```status```         |                            |                | Control the system status icons
+                     | ```volume```               |                | Sets the icon in the volume slot (```silent```, ```vibrate```, any other value to hide)
+                     | ```bluetooth```            |                | Sets the icon in the bluetooth slot (```connected```, ```disconnected```, any other value to hide)
+                     | ```location```             |                | Sets the icon in the location slot (```show```, any other value to hide)
+                     | ```alarm```                |                | Sets the icon in the alarm_clock slot (```show```, any other value to hide)
+                     | ```sync```                 |                | Sets the icon in the sync_active slot (```show```, any other value to hide)
+                     | ```tty```                  |                | Sets the icon in the tty slot (```show```, any other value to hide)
+                     | ```eri```                  |                | Sets the icon in the cdma_eri slot (```show```, any other value to hide)
+                     | ```mute```                 |                | Sets the icon in the mute slot (```show```, any other value to hide)
+                     | ```speakerphone```         |                | Sets the icon in the speakerphone slot (```show```, any other value to hide)
+```notifications```  |                            |                | Control the notification icons
+                     | ```visible```              |                | ```false``` to hide the notification icons, any other value to show
+```clock```          |                            |                | Control the clock display
+                     | ```millis```               |                | Sets the time in millis
+                     | ```hhmm```                 |                | Sets the time in hh:mm
 
 ## Examples
 Enter demo mode
diff --git a/packages/SystemUI/res/values/dimens.xml b/packages/SystemUI/res/values/dimens.xml
index ccbd0a6..6e59029 100644
--- a/packages/SystemUI/res/values/dimens.xml
+++ b/packages/SystemUI/res/values/dimens.xml
@@ -570,4 +570,7 @@
     <!-- Padding to be used on the bottom of the fingerprint icon on Keyguard so it better aligns
          with the other icons. -->
     <dimen name="fingerprint_icon_additional_padding">12dp</dimen>
+
+    <!-- Minimum margin of the notification panel on the side, when being positioned dynamically -->
+    <dimen name="notification_panel_min_side_margin">48dp</dimen>
 </resources>
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
index 03e5746..7d61099 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
@@ -187,6 +187,9 @@
     private boolean mExpansionIsFromHeadsUp;
     private int mBottomBarHeight;
     private boolean mExpandingFromHeadsUp;
+    private int mPositionMinSideMargin;
+    private int mLastOrientation = -1;
+
     private Runnable mHeadsUpExistenceChangedRunnable = new Runnable() {
         @Override
         public void run() {
@@ -236,6 +239,7 @@
         mAfforanceHelper = new KeyguardAffordanceHelper(this, getContext());
         mSecureCameraLaunchManager =
                 new SecureCameraLaunchManager(getContext(), mKeyguardBottomArea);
+        mLastOrientation = getResources().getConfiguration().orientation;
 
         // recompute internal state when qspanel height changes
         mQsContainer.addOnLayoutChangeListener(new OnLayoutChangeListener() {
@@ -268,6 +272,8 @@
                 getResources().getDimensionPixelSize(R.dimen.notification_scrim_wait_distance);
         mQsFalsingThreshold = getResources().getDimensionPixelSize(
                 R.dimen.qs_falsing_threshold);
+        mPositionMinSideMargin = getResources().getDimensionPixelSize(
+                R.dimen.notification_panel_min_side_margin);
     }
 
     public void updateResources() {
@@ -692,6 +698,9 @@
         if (!mHeadsUpTouchHelper.isTrackingHeadsUp() && handleQSTouch(event)) {
             return true;
         }
+        if (event.getActionMasked() == MotionEvent.ACTION_DOWN && isFullyCollapsed()) {
+            updateVerticalPanelPosition(event.getX());
+        }
         super.onTouchEvent(event);
         return true;
     }
@@ -740,7 +749,7 @@
     }
 
     private boolean isInQsArea(float x, float y) {
-        return (x >= mScrollView.getLeft() && x <= mScrollView.getRight()) &&
+        return (x >= mScrollView.getX() && x <= mScrollView.getX() + mScrollView.getWidth()) &&
                 (y <= mNotificationStackScroller.getBottomMostNotificationBottom()
                 || y <= mQsContainer.getY() + mQsContainer.getHeight());
     }
@@ -939,7 +948,7 @@
             mKeyguardStatusBar.setAlpha(1f);
             mKeyguardStatusBar.setVisibility(keyguardShowing ? View.VISIBLE : View.INVISIBLE);
         }
-
+        resetVerticalPanelPosition();
         updateQsState();
     }
 
@@ -1376,7 +1385,7 @@
             return false;
         }
         View header = mKeyguardShowing ? mKeyguardStatusBar : mHeader;
-        boolean onHeader = x >= header.getLeft() && x <= header.getRight()
+        boolean onHeader = x >= header.getX() && x <= header.getX() + header.getWidth()
                 && y >= header.getTop() && y <= header.getBottom();
         if (mQsExpanded) {
             return onHeader || (mScrollView.isScrolledToBottom() && yDiff < 0) && isInQsArea(x, y);
@@ -1771,6 +1780,10 @@
     protected void onConfigurationChanged(Configuration newConfig) {
         super.onConfigurationChanged(newConfig);
         mAfforanceHelper.onConfigurationChanged();
+        if (newConfig.orientation != mLastOrientation) {
+            resetVerticalPanelPosition();
+        }
+        mLastOrientation = newConfig.orientation;
     }
 
     @Override
@@ -2185,4 +2198,42 @@
             mExpandingFromHeadsUp = true;
         }
     }
+
+    @Override
+    protected void onClosingFinished() {
+        super.onClosingFinished();
+        resetVerticalPanelPosition();
+    }
+
+    /**
+     * Updates the vertical position of the panel so it is positioned closer to the touch
+     * responsible for opening the panel.
+     *
+     * @param x the x-coordinate the touch event
+     */
+    private void updateVerticalPanelPosition(float x) {
+        if (mNotificationStackScroller.getWidth() * 1.75f > getWidth()) {
+            resetVerticalPanelPosition();
+            return;
+        }
+        float leftMost = mPositionMinSideMargin + mNotificationStackScroller.getWidth() / 2;
+        float rightMost = getWidth() - mPositionMinSideMargin
+                - mNotificationStackScroller.getWidth() / 2;
+        if (Math.abs(x - getWidth() / 2) < mNotificationStackScroller.getWidth() / 4) {
+            x = getWidth() / 2;
+        }
+        x = Math.min(rightMost, Math.max(leftMost, x));
+        setVerticalPanelTranslation(x -
+                (mNotificationStackScroller.getLeft() + mNotificationStackScroller.getWidth()/2));
+     }
+
+    private void resetVerticalPanelPosition() {
+        setVerticalPanelTranslation(0f);
+    }
+
+    private void setVerticalPanelTranslation(float translation) {
+        mNotificationStackScroller.setTranslationX(translation);
+        mScrollView.setTranslationX(translation);
+        mHeader.setTranslationX(translation);
+    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
index b6dbfce..c854d63 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
@@ -3249,6 +3249,10 @@
         mKeyguardFadingAway = false;
     }
 
+    public void stopWaitingForKeyguardExit() {
+        mWaitingForKeyguardExit = false;
+    }
+
     private void updatePublicMode() {
         setLockscreenPublicMode(
                 mStatusBarKeyguardViewManager.isShowing() && mStatusBarKeyguardViewManager
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java
index 194a19a..0caf51a 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java
@@ -145,6 +145,7 @@
         if (mShowing) {
             if (mOccluded) {
                 mPhoneStatusBar.hideKeyguard();
+                mPhoneStatusBar.stopWaitingForKeyguardExit();
                 mBouncer.hide(false /* destroyView */);
             } else {
                 showBouncerOrKeyguard();
diff --git a/services/core/java/com/android/server/AlarmManagerService.java b/services/core/java/com/android/server/AlarmManagerService.java
index 5d02576..0e3867d 100644
--- a/services/core/java/com/android/server/AlarmManagerService.java
+++ b/services/core/java/com/android/server/AlarmManagerService.java
@@ -566,13 +566,22 @@
     }
 
     void restorePendingWhileIdleAlarmsLocked() {
+        // Bring pending alarms back into the main list.
         final long nowElapsed = SystemClock.elapsedRealtime();
-        for (int i=mPendingWhileIdleAlarms.size() - 1; i >= 0 && mPendingIdleUntil != null; i --) {
+        for (int i=mPendingWhileIdleAlarms.size() - 1; i >= 0 && mPendingIdleUntil == null; i--) {
             Alarm a = mPendingWhileIdleAlarms.remove(i);
             reAddAlarmLocked(a, nowElapsed, false);
         }
+
+        // Reschedule everything.
         rescheduleKernelAlarmsLocked();
         updateNextAlarmClockLocked();
+
+        // And send a TIME_TICK right now, since it is important to get the UI updated.
+        try {
+            mTimeTickSender.send();
+        } catch (PendingIntent.CanceledException e) {
+        }
     }
 
     static final class InFlight extends Intent {
diff --git a/services/core/java/com/android/server/LockSettingsService.java b/services/core/java/com/android/server/LockSettingsService.java
index a31a1a7..5df74c5 100644
--- a/services/core/java/com/android/server/LockSettingsService.java
+++ b/services/core/java/com/android/server/LockSettingsService.java
@@ -220,6 +220,35 @@
                 setString("migrated_biometric_weak", "true", 0);
                 Slog.i(TAG, "Migrated biometric weak to use the fallback instead");
             }
+
+            // Migrates lockscreen.disabled. Prior to M, the flag was ignored when more than one
+            // user was present on the system, so if we're upgrading to M and there is more than one
+            // user we disable the flag to remain consistent.
+            if (getString("migrated_lockscreen_disabled", null, 0) == null) {
+                final UserManager um = (UserManager) mContext.getSystemService(USER_SERVICE);
+
+                final List<UserInfo> users = um.getUsers();
+                final int userCount = users.size();
+                int switchableUsers = 0;
+                for (int i = 0; i < userCount; i++) {
+                    if (users.get(i).supportsSwitchTo()) {
+                        switchableUsers++;
+                    }
+                }
+
+                if (switchableUsers > 1) {
+                    for (int i = 0; i < userCount; i++) {
+                        int id = users.get(i).id;
+
+                        if (getBoolean(LockPatternUtils.DISABLE_LOCKSCREEN_KEY, false, id)) {
+                            setBoolean(LockPatternUtils.DISABLE_LOCKSCREEN_KEY, false, id);
+                        }
+                    }
+                }
+
+                setString("migrated_lockscreen_disabled", "true", 0);
+                Slog.i(TAG, "Migrated lockscreen disabled flag");
+            }
         } catch (RemoteException re) {
             Slog.e(TAG, "Unable to migrate old data", re);
         }
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index 9d5ae8e..a48a4d9 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -437,6 +437,11 @@
      */
     SparseArray<String[]> mLockTaskPackages = new SparseArray<>();
 
+    /**
+     * The package name of the DeviceOwner. This package is not permitted to have its data cleared.
+     */
+    String mDeviceOwnerName;
+
     public class PendingAssistExtras extends Binder implements Runnable {
         public final ActivityRecord activity;
         public final Bundle extras;
@@ -4831,6 +4836,9 @@
     public boolean clearApplicationUserData(final String packageName,
             final IPackageDataObserver observer, int userId) {
         enforceNotIsolatedCaller("clearApplicationUserData");
+        if (packageName != null && packageName.equals(mDeviceOwnerName)) {
+            throw new SecurityException("Clearing DeviceOwner data is forbidden.");
+        }
         int uid = Binder.getCallingUid();
         int pid = Binder.getCallingPid();
         userId = handleIncomingUser(pid, uid,
@@ -8563,6 +8571,17 @@
     }
 
     @Override
+    public void updateDeviceOwner(String packageName) {
+        final int callingUid = Binder.getCallingUid();
+        if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
+            throw new SecurityException("updateDeviceOwner called from non-system process");
+        }
+        synchronized (this) {
+            mDeviceOwnerName = packageName;
+        }
+    }
+
+    @Override
     public void updateLockTaskPackages(int userId, String[] packages) {
         final int callingUid = Binder.getCallingUid();
         if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
diff --git a/services/core/java/com/android/server/pm/Settings.java b/services/core/java/com/android/server/pm/Settings.java
index b3aa966..252c16a 100644
--- a/services/core/java/com/android/server/pm/Settings.java
+++ b/services/core/java/com/android/server/pm/Settings.java
@@ -4275,6 +4275,8 @@
                 Slog.wtf(PackageManagerService.TAG,
                         "Failed to write settings, restoring backup", t);
                 destination.failWrite(out);
+                throw new IllegalStateException("Failed to write runtime permissions,"
+                        + " restoring backup", t);
             } finally {
                 IoUtils.closeQuietly(out);
             }
@@ -4322,10 +4324,9 @@
                 parser.setInput(in, null);
                 parseRuntimePermissionsLPr(parser, userId);
 
-                // Any error while parsing is fatal.
-            } catch (Throwable t) {
+            } catch (XmlPullParserException | IOException e) {
                 throw new IllegalStateException("Failed parsing permissions file: "
-                        + permissionsFile , t);
+                        + permissionsFile , e);
             } finally {
                 IoUtils.closeQuietly(in);
             }
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
index 9bb97f7..eb9234a 100644
--- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
@@ -1106,6 +1106,7 @@
     void loadDeviceOwner() {
         synchronized (this) {
             mDeviceOwner = DeviceOwner.load();
+            updateDeviceOwnerLocked();
         }
     }
 
@@ -1629,20 +1630,25 @@
         // sufficiently what is currently set.  Note that this is only
         // a sanity check in case the two get out of sync; this should
         // never normally happen.
-        LockPatternUtils utils = new LockPatternUtils(mContext);
-        if (utils.getActivePasswordQuality(userHandle) < policy.mActivePasswordQuality) {
-            Slog.w(LOG_TAG, "Active password quality 0x"
-                    + Integer.toHexString(policy.mActivePasswordQuality)
-                    + " does not match actual quality 0x"
-                    + Integer.toHexString(utils.getActivePasswordQuality(userHandle)));
-            policy.mActivePasswordQuality = DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED;
-            policy.mActivePasswordLength = 0;
-            policy.mActivePasswordUpperCase = 0;
-            policy.mActivePasswordLowerCase = 0;
-            policy.mActivePasswordLetters = 0;
-            policy.mActivePasswordNumeric = 0;
-            policy.mActivePasswordSymbols = 0;
-            policy.mActivePasswordNonLetter = 0;
+        final long identity = Binder.clearCallingIdentity();
+        try {
+            LockPatternUtils utils = new LockPatternUtils(mContext);
+            if (utils.getActivePasswordQuality(userHandle) < policy.mActivePasswordQuality) {
+                Slog.w(LOG_TAG, "Active password quality 0x"
+                        + Integer.toHexString(policy.mActivePasswordQuality)
+                        + " does not match actual quality 0x"
+                        + Integer.toHexString(utils.getActivePasswordQuality(userHandle)));
+                policy.mActivePasswordQuality = DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED;
+                policy.mActivePasswordLength = 0;
+                policy.mActivePasswordUpperCase = 0;
+                policy.mActivePasswordLowerCase = 0;
+                policy.mActivePasswordLetters = 0;
+                policy.mActivePasswordNumeric = 0;
+                policy.mActivePasswordSymbols = 0;
+                policy.mActivePasswordNonLetter = 0;
+            }
+        } finally {
+            Binder.restoreCallingIdentity(identity);
         }
 
         validatePasswordOwnerLocked(policy);
@@ -1667,6 +1673,18 @@
         }
     }
 
+    private void updateDeviceOwnerLocked() {
+        IActivityManager am = ActivityManagerNative.getDefault();
+        long ident = Binder.clearCallingIdentity();
+        try {
+            am.updateDeviceOwner(getDeviceOwner());
+        } catch (RemoteException e) {
+            // Not gonna happen.
+        } finally {
+            Binder.restoreCallingIdentity(ident);
+        }
+    }
+
     static void validateQualityConstant(int quality) {
         switch (quality) {
             case DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED:
@@ -3990,14 +4008,13 @@
             if (mDeviceOwner == null) {
                 // Device owner is not set and does not exist, set it.
                 mDeviceOwner = DeviceOwner.createWithDeviceOwner(packageName, ownerName);
-                mDeviceOwner.writeOwnerFile();
-                return true;
             } else {
                 // Device owner is not set but a profile owner exists, update Device owner state.
                 mDeviceOwner.setDeviceOwner(packageName, ownerName);
-                mDeviceOwner.writeOwnerFile();
-                return true;
             }
+            mDeviceOwner.writeOwnerFile();
+            updateDeviceOwnerLocked();
+            return true;
         }
     }
 
@@ -4079,6 +4096,7 @@
                 if (mDeviceOwner != null) {
                     mDeviceOwner.clearDeviceOwner();
                     mDeviceOwner.writeOwnerFile();
+                    updateDeviceOwnerLocked();
                 }
             } finally {
                 Binder.restoreCallingIdentity(ident);
@@ -4107,15 +4125,13 @@
 
             if (mDeviceOwner == null) {
                 // Device owner state does not exist, create it.
-                mDeviceOwner = DeviceOwner.createWithDeviceInitializer(
-                        initializer, ownerName);
+                mDeviceOwner = DeviceOwner.createWithDeviceInitializer(initializer, ownerName);
             } else {
                 // Device owner already exists, update it.
                 mDeviceOwner.setDeviceInitializer(initializer, ownerName);
             }
 
             addDeviceInitializerToLockTaskPackagesLocked(UserHandle.USER_OWNER);
-
             mDeviceOwner.writeOwnerFile();
             return true;
         }
diff --git a/telecomm/java/android/telecom/Call.java b/telecomm/java/android/telecom/Call.java
index bbd5e30..2a30384 100644
--- a/telecomm/java/android/telecom/Call.java
+++ b/telecomm/java/android/telecom/Call.java
@@ -66,9 +66,18 @@
     public static final int STATE_DISCONNECTED = 7;
 
     /**
-     * The state of an outgoing {@code Call}, but waiting for user input before proceeding.
+     * The state of an outgoing {@code Call} when waiting on user to select a
+     * {@link PhoneAccount} through which to place the call.
      */
-    public static final int STATE_PRE_DIAL_WAIT = 8;
+    public static final int STATE_SELECT_PHONE_ACCOUNT = 8;
+
+    /**
+     * @hide
+     * @deprecated use STATE_SELECT_PHONE_ACCOUNT.
+     */
+    @Deprecated
+    @SystemApi
+    public static final int STATE_PRE_DIAL_WAIT = STATE_SELECT_PHONE_ACCOUNT;
 
     /**
      * The initial state of an outgoing {@code Call}.
@@ -929,7 +938,7 @@
             mVideoCall = parcelableCall.getVideoCall();
         }
 
-        int state = stateFromParcelableCallState(parcelableCall.getState());
+        int state = parcelableCall.getState();
         boolean stateChanged = mState != state;
         if (stateChanged) {
             mState = state;
@@ -1064,32 +1073,4 @@
             callback.onConferenceableCallsChanged(this, mUnmodifiableConferenceableCalls);
         }
     }
-
-    private int stateFromParcelableCallState(int parcelableCallState) {
-        switch (parcelableCallState) {
-            case CallState.NEW:
-                return STATE_NEW;
-            case CallState.CONNECTING:
-                return STATE_CONNECTING;
-            case CallState.PRE_DIAL_WAIT:
-                return STATE_PRE_DIAL_WAIT;
-            case CallState.DIALING:
-                return STATE_DIALING;
-            case CallState.RINGING:
-                return STATE_RINGING;
-            case CallState.ACTIVE:
-                return STATE_ACTIVE;
-            case CallState.ON_HOLD:
-                return STATE_HOLDING;
-            case CallState.DISCONNECTED:
-                return STATE_DISCONNECTED;
-            case CallState.ABORTED:
-                return STATE_DISCONNECTED;
-            case CallState.DISCONNECTING:
-                return STATE_DISCONNECTING;
-            default:
-                Log.wtf(this, "Unrecognized CallState %s", parcelableCallState);
-                return STATE_NEW;
-        }
-    }
 }
diff --git a/telecomm/java/android/telecom/CallState.java b/telecomm/java/android/telecom/CallState.java
deleted file mode 100644
index 5584226..0000000
--- a/telecomm/java/android/telecom/CallState.java
+++ /dev/null
@@ -1,134 +0,0 @@
-/*
- * Copyright 2014, 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 android.telecom;
-
-/**
- * Defines call-state constants of the different states in which a call can exist. Although states
- * have the notion of normal transitions, due to the volatile nature of telephony systems, code
- * that uses these states should be resilient to unexpected state changes outside of what is
- * considered traditional.
- */
-public final class CallState {
-
-    private CallState() {}
-
-    /**
-     * Indicates that a call is new and not connected. This is used as the default state internally
-     * within Telecom and should not be used between Telecom and call services. Call services are
-     * not expected to ever interact with NEW calls, but {@link InCallService}s will see calls in
-     * this state.
-     */
-    public static final int NEW = 0;
-
-    /**
-     * The initial state of an outgoing {@code Call}.
-     * Common transitions are to {@link #DIALING} state for a successful call or
-     * {@link #DISCONNECTED} if it failed.
-     */
-    public static final int CONNECTING = 1;
-
-    /**
-     * Indicates that the call is about to go into the outgoing and dialing state but is waiting for
-     * user input before it proceeds. For example, where no default {@link PhoneAccount} is set,
-     * this is the state where the InCallUI is waiting for the user to select a
-     * {@link PhoneAccount} to call from.
-     */
-    public static final int PRE_DIAL_WAIT = 2;
-
-    /**
-     * Indicates that a call is outgoing and in the dialing state. A call transitions to this state
-     * once an outgoing call has begun (e.g., user presses the dial button in Dialer). Calls in this
-     * state usually transition to {@link #ACTIVE} if the call was answered or {@link #DISCONNECTED}
-     * if the call was disconnected somehow (e.g., failure or cancellation of the call by the user).
-     */
-    public static final int DIALING = 3;
-
-    /**
-     * Indicates that a call is incoming and the user still has the option of answering, rejecting,
-     * or doing nothing with the call. This state is usually associated with some type of audible
-     * ringtone. Normal transitions are to {@link #ACTIVE} if answered or {@link #DISCONNECTED}
-     * otherwise.
-     */
-    public static final int RINGING = 4;
-
-    /**
-     * Indicates that a call is currently connected to another party and a communication channel is
-     * open between them. The normal transition to this state is by the user answering a
-     * {@link #DIALING} call or a {@link #RINGING} call being answered by the other party.
-     */
-    public static final int ACTIVE = 5;
-
-    /**
-     * Indicates that the call is currently on hold. In this state, the call is not terminated
-     * but no communication is allowed until the call is no longer on hold. The typical transition
-     * to this state is by the user putting an {@link #ACTIVE} call on hold by explicitly performing
-     * an action, such as clicking the hold button.
-     */
-    public static final int ON_HOLD = 6;
-
-    /**
-     * Indicates that a call is currently disconnected. All states can transition to this state
-     * by the call service giving notice that the connection has been severed. When the user
-     * explicitly ends a call, it will not transition to this state until the call service confirms
-     * the disconnection or communication was lost to the call service currently responsible for
-     * this call (e.g., call service crashes).
-     */
-    public static final int DISCONNECTED = 7;
-
-    /**
-     * Indicates that the call was attempted (mostly in the context of outgoing, at least at the
-     * time of writing) but cancelled before it was successfully connected.
-     */
-    public static final int ABORTED = 8;
-
-    /**
-     * Indicates that the call is in the process of being disconnected and will transition next
-     * to a {@link #DISCONNECTED} state.
-     * <p>
-     * This state is not expected to be communicated from the Telephony layer, but will be reported
-     * to the InCall UI for calls where disconnection has been initiated by the user but the
-     * ConnectionService has confirmed the call as disconnected.
-     */
-    public static final int DISCONNECTING = 9;
-
-    public static String toString(int callState) {
-        switch (callState) {
-            case NEW:
-                return "NEW";
-            case CONNECTING:
-                return "CONNECTING";
-            case PRE_DIAL_WAIT:
-                return "PRE_DIAL_WAIT";
-            case DIALING:
-                return "DIALING";
-            case RINGING:
-                return "RINGING";
-            case ACTIVE:
-                return "ACTIVE";
-            case ON_HOLD:
-                return "ON_HOLD";
-            case DISCONNECTED:
-                return "DISCONNECTED";
-            case ABORTED:
-                return "ABORTED";
-            case DISCONNECTING:
-                return "DISCONNECTING";
-            default:
-                return "UNKNOWN";
-        }
-    }
-}
diff --git a/telecomm/java/android/telecom/DefaultDialerManager.java b/telecomm/java/android/telecom/DefaultDialerManager.java
new file mode 100644
index 0000000..eef72fb
--- /dev/null
+++ b/telecomm/java/android/telecom/DefaultDialerManager.java
@@ -0,0 +1,174 @@
+/*
+ * Copyright (C) 2015 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 android.telecom;
+
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.content.pm.ActivityInfo;
+import android.content.pm.PackageManager;
+import android.content.pm.ResolveInfo;
+import android.provider.Settings;
+import android.text.TextUtils;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Class for managing the default dialer application that will receive incoming calls, and be
+ * allowed to make emergency outgoing calls.
+ *
+ * @hide
+ */
+public class DefaultDialerManager {
+    private static final String TAG = "DefaultDialerManager";
+
+    /**
+     * Sets the specified package name as the default dialer application. The caller of this method
+     * needs to have permission to write to secure settings.
+     *
+     * @hide
+     * */
+    public static void setDefaultPhoneApplication(Context context, String packageName) {
+        // Get old package name
+        String oldPackageName = Settings.Secure.getString(context.getContentResolver(),
+                Settings.Secure.DIALER_DEFAULT_APPLICATION);
+
+        if (packageName != null && oldPackageName != null && packageName.equals(oldPackageName)) {
+            // No change
+            return;
+        }
+
+        // Only make the change if the new package belongs to a valid phone application
+        List<ComponentName> componentNames = getInstalledDialerApplications(context);
+        final ComponentName foundComponent = getComponentName(componentNames, packageName);
+
+        if (foundComponent != null) {
+            // Update the secure setting.
+            Settings.Secure.putString(context.getContentResolver(),
+                    Settings.Secure.DIALER_DEFAULT_APPLICATION, foundComponent.getPackageName());
+        }
+    }
+
+    /**
+     * Returns the installed dialer application that will be used to receive incoming calls, and is
+     * allowed to make emergency calls.
+     *
+     * The application will be returned in order of preference:
+     * 1) User selected phone application (if still installed)
+     * 2) Pre-installed system dialer (if not disabled)
+     * 3) Null
+     *
+     * @hide
+     * */
+    public static ComponentName getDefaultDialerApplication(Context context) {
+        String defaultPackageName = Settings.Secure.getString(context.getContentResolver(),
+                Settings.Secure.DIALER_DEFAULT_APPLICATION);
+
+        final List<ComponentName> componentNames = getInstalledDialerApplications(context);
+        if (!TextUtils.isEmpty(defaultPackageName)) {
+            final ComponentName defaultDialer =
+                    getComponentName(componentNames, defaultPackageName);
+            if (defaultDialer != null) {
+                return defaultDialer;
+            }
+        }
+
+        // No user-set dialer found, fallback to system dialer
+        ComponentName systemDialer = getTelecomManager(context).getDefaultPhoneApp();
+
+        if (systemDialer == null) {
+            // No system dialer configured at build time
+            return null;
+        }
+
+        // Verify that the system dialer has not been disabled.
+        return getComponentName(componentNames, systemDialer.getPackageName());
+    }
+
+    /**
+     * Returns a list of installed and available dialer applications.
+     *
+     * In order to appear in the list, a dialer application must implement an intent-filter with
+     * the DIAL intent for the following schemes:
+     *
+     * 1) Empty scheme
+     * 2) tel Uri scheme
+     *
+     * @hide
+     **/
+    public static List<ComponentName> getInstalledDialerApplications(Context context) {
+        PackageManager packageManager = context.getPackageManager();
+
+        // Get the list of apps registered for the DIAL intent with empty scheme
+        Intent intent = new Intent(Intent.ACTION_DIAL);
+        List<ResolveInfo> resolveInfoList = packageManager.queryIntentActivities(intent, 0);
+
+        List<ComponentName> componentNames = new ArrayList<ComponentName> ();
+
+        for (ResolveInfo resolveInfo : resolveInfoList) {
+            final ActivityInfo activityInfo = resolveInfo.activityInfo;
+            if (activityInfo == null) {
+                continue;
+            }
+            final ComponentName componentName =
+                    new ComponentName(activityInfo.packageName, activityInfo.name);
+            componentNames.add(componentName);
+        }
+
+        // TODO: Filter for apps that don't handle DIAL intent with tel scheme
+        return componentNames;
+    }
+
+    /**
+     * Returns the {@link ComponentName} for the installed dialer application for a given package
+     * name.
+     *
+     * @param context A valid context.
+     * @param packageName to retrieve the {@link ComponentName} for.
+     *
+     * @return The {@link ComponentName} for the installed dialer application corresponding to the
+     * package name, or null if none is found.
+     *
+     * @hide
+     */
+    public static ComponentName getDialerApplicationForPackageName(Context context,
+            String packageName) {
+        return getComponentName(getInstalledDialerApplications(context), packageName);
+    }
+
+    /**
+     * Returns the component from a list of application components that corresponds to the package
+     * name.
+     *
+     * @param componentNames A list of component names
+     * @param packageName The package name to look for
+     * @return The {@link ComponentName} that matches the provided packageName, or null if not
+     *         found.
+     */
+    private static ComponentName getComponentName(List<ComponentName> componentNames,
+            String packageName) {
+        for (ComponentName componentName : componentNames) {
+            if (TextUtils.equals(packageName, componentName.getPackageName())) {
+                return componentName;
+            }
+        }
+        return null;
+    }
+
+    private static TelecomManager getTelecomManager(Context context) {
+        return (TelecomManager) context.getSystemService(Context.TELECOM_SERVICE);
+    }
+}
diff --git a/telecomm/java/android/telecom/TelecomManager.java b/telecomm/java/android/telecom/TelecomManager.java
index a72172c..fd95327 100644
--- a/telecomm/java/android/telecom/TelecomManager.java
+++ b/telecomm/java/android/telecom/TelecomManager.java
@@ -17,6 +17,7 @@
 import android.annotation.SystemApi;
 import android.content.ComponentName;
 import android.content.Context;
+import android.content.Intent;
 import android.net.Uri;
 import android.os.Bundle;
 import android.os.RemoteException;
@@ -1057,6 +1058,39 @@
         }
     }
 
+    /**
+     * Places a new outgoing call to the provided address using the system telecom service with
+     * the specified extras.
+     *
+     * This method is equivalent to placing an outgoing call using {@link Intent#ACTION_CALL},
+     * except that the outgoing call will always be sent via the system telecom service. If
+     * method-caller is either the user selected default dialer app or preloaded system dialer
+     * app, then emergency calls will also be allowed.
+     *
+     * Requires permission: {@link android.Manifest.permission#CALL_PHONE}
+     *
+     * Usage example:
+     * <pre>
+     * Uri uri = Uri.fromParts("tel", "12345", null);
+     * Bundle extras = new Bundle();
+     * extras.putBoolean(TelecomManager.EXTRA_START_CALL_WITH_SPEAKERPHONE, true);
+     * telecomManager.placeCall(uri, extras);
+     * </pre>
+     *
+     * @param address The address to make the call to.
+     * @param extras Bundle of extras to use with the call.
+     */
+    public void placeCall(Uri address, Bundle extras) {
+        ITelecomService service = getTelecomService();
+        if (service != null) {
+            try {
+                service.placeCall(address, extras, mContext.getOpPackageName());
+            } catch (RemoteException e) {
+                Log.e(TAG, "Error calling ITelecomService#placeCall", e);
+            }
+        }
+    }
+
     private ITelecomService getTelecomService() {
         return ITelecomService.Stub.asInterface(ServiceManager.getService(Context.TELECOM_SERVICE));
     }
diff --git a/telecomm/java/com/android/internal/telecom/ITelecomService.aidl b/telecomm/java/com/android/internal/telecom/ITelecomService.aidl
index 727fd4bb..45b2482 100644
--- a/telecomm/java/com/android/internal/telecom/ITelecomService.aidl
+++ b/telecomm/java/com/android/internal/telecom/ITelecomService.aidl
@@ -210,4 +210,9 @@
      * @see TelecomServiceImpl#addNewUnknownCall
      */
     void addNewUnknownCall(in PhoneAccountHandle phoneAccount, in Bundle extras);
+
+    /**
+     * @see TelecomServiceImpl#placeCall
+     */
+    void placeCall(in Uri handle, in Bundle extras, String callingPackage);
 }
diff --git a/telephony/java/android/telephony/CarrierConfigManager.java b/telephony/java/android/telephony/CarrierConfigManager.java
index d103fbf..7d1a2fa 100644
--- a/telephony/java/android/telephony/CarrierConfigManager.java
+++ b/telephony/java/android/telephony/CarrierConfigManager.java
@@ -71,6 +71,11 @@
     public static final String BOOL_SHOW_APN_SETTING_CDMA = "bool_show_apn_setting_cdma";
 
     /**
+     * Control whether users can edit APNs in Settings.
+     */
+    public static final String BOOL_APN_EXPAND = "bool_apn_expand";
+
+    /**
      * If Voice Radio Technology is RIL_RADIO_TECHNOLOGY_LTE:14 or RIL_RADIO_TECHNOLOGY_UNKNOWN:0
      * this is the value that should be used instead. A configuration value of
      * RIL_RADIO_TECHNOLOGY_UNKNOWN:0 means there is no replacement value and that the default
@@ -121,6 +126,7 @@
         sDefaults.putBoolean(BOOL_CARRIER_VOLTE_PROVISIONED, false);
         sDefaults.putBoolean(BOOL_CARRIER_VOLTE_TTY_SUPPORTED, true);
         sDefaults.putBoolean(BOOL_SHOW_APN_SETTING_CDMA, false);
+        sDefaults.putBoolean(BOOL_APN_EXPAND, true);
 
         sDefaults.putInt(INT_VOLTE_REPLACEMENT_RAT, 0);
 
diff --git a/telephony/java/android/telephony/RadioAccessFamily.java b/telephony/java/android/telephony/RadioAccessFamily.java
index d10a7ea..9fea418 100644
--- a/telephony/java/android/telephony/RadioAccessFamily.java
+++ b/telephony/java/android/telephony/RadioAccessFamily.java
@@ -48,6 +48,13 @@
     public static final int RAF_GSM = (1 << ServiceState.RIL_RADIO_TECHNOLOGY_GSM);
     public static final int RAF_TD_SCDMA = (1 << ServiceState.RIL_RADIO_TECHNOLOGY_TD_SCDMA);
 
+    // Grouping of RAFs
+    private static final int GSM = RAF_GSM | RAF_GPRS | RAF_EDGE;
+    private static final int HS = RAF_HSUPA | RAF_HSDPA | RAF_HSPA | RAF_HSPAP;
+    private static final int CDMA = RAF_IS95A | RAF_IS95B | RAF_1xRTT;
+    private static final int EVDO = RAF_EVDO_0 | RAF_EVDO_A | RAF_EVDO_B | RAF_EHRPD;
+    private static final int WCDMA = HS | RAF_UMTS;
+
     /* Phone ID of phone */
     private int mPhoneId;
 
@@ -136,12 +143,6 @@
     };
 
     public static int getRafFromNetworkType(int type) {
-        final int GSM = RAF_GSM | RAF_GPRS | RAF_EDGE;
-        final int HS = RAF_HSUPA | RAF_HSDPA | RAF_HSPA | RAF_HSPAP;
-        final int CDMA = RAF_IS95A | RAF_IS95B | RAF_1xRTT;
-        final int EVDO = RAF_EVDO_0 | RAF_EVDO_A | RAF_EVDO_B;
-        final int WCDMA = HS | RAF_UMTS;
-
         int raf;
 
         switch (type) {
@@ -158,7 +159,7 @@
                 raf = GSM | WCDMA;
                 break;
             case RILConstants.NETWORK_MODE_CDMA:
-                raf = CDMA;
+                raf = CDMA | EVDO;
                 break;
             case RILConstants.NETWORK_MODE_LTE_CDMA_EVDO:
                 raf = RAF_LTE | CDMA | EVDO;
@@ -188,7 +189,71 @@
                 raf = RAF_UNKNOWN;
                 break;
         }
+
         return raf;
     }
+
+    /**
+     * if the raf includes ANY bit set for a group
+     * adjust it to contain ALL the bits for that group
+     */
+    private static int getAdjustedRaf(int raf) {
+        raf = ((GSM & raf) > 0) ? (GSM | raf) : raf;
+        raf = ((WCDMA & raf) > 0) ? (WCDMA | raf) : raf;
+        raf = ((CDMA & raf) > 0) ? (CDMA | raf) : raf;
+        raf = ((EVDO & raf) > 0) ? (EVDO | raf) : raf;
+
+        return raf;
+    }
+
+    public static int getNetworkTypeFromRaf(int raf) {
+        int type;
+
+        raf = getAdjustedRaf(raf);
+
+        switch (raf) {
+            case (GSM | WCDMA):
+                type = RILConstants.NETWORK_MODE_WCDMA_PREF;
+                break;
+            case GSM:
+                type = RILConstants.NETWORK_MODE_GSM_ONLY;
+                break;
+            case WCDMA:
+                type = RILConstants.NETWORK_MODE_WCDMA_ONLY;
+                break;
+            case (CDMA | EVDO):
+                type = RILConstants.NETWORK_MODE_CDMA;
+                break;
+            case (RAF_LTE | CDMA | EVDO):
+                type = RILConstants.NETWORK_MODE_LTE_CDMA_EVDO;
+                break;
+            case (RAF_LTE | GSM | WCDMA):
+                type = RILConstants.NETWORK_MODE_LTE_GSM_WCDMA;
+                break;
+            case (RAF_LTE | CDMA | EVDO | GSM | WCDMA):
+                type = RILConstants.NETWORK_MODE_LTE_CDMA_EVDO_GSM_WCDMA;
+                break;
+            case RAF_LTE:
+                type = RILConstants.NETWORK_MODE_LTE_ONLY;
+                break;
+            case (RAF_LTE | WCDMA):
+                type = RILConstants.NETWORK_MODE_LTE_WCDMA;
+                break;
+            case CDMA:
+                type = RILConstants.NETWORK_MODE_CDMA_NO_EVDO;
+                break;
+            case EVDO:
+                type = RILConstants.NETWORK_MODE_EVDO_NO_CDMA;
+                break;
+            case (GSM | WCDMA | CDMA | EVDO):
+                type = RILConstants.NETWORK_MODE_GLOBAL;
+                break;
+            default:
+                type = RILConstants.PREFERRED_NETWORK_MODE ;
+                break;
+        }
+
+        return type;
+    }
 }