Merge "merge from master" into mm-wireless-dev
diff --git a/api/current.txt b/api/current.txt
index 2914b2c..b0d0646 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -27003,7 +27003,10 @@
   public static final class Telephony.Sms.Intents {
     method public static android.telephony.SmsMessage[] getMessagesFromIntent(android.content.Intent);
     field public static final java.lang.String ACTION_CHANGE_DEFAULT = "android.provider.Telephony.ACTION_CHANGE_DEFAULT";
+    field public static final java.lang.String ACTION_DEFAULT_SMS_PACKAGE_CHANGED = "android.provider.action.DEFAULT_SMS_PACKAGE_CHANGED";
+    field public static final java.lang.String ACTION_EXTERNAL_PROVIDER_CHANGE = "android.provider.action.EXTERNAL_PROVIDER_CHANGE";
     field public static final java.lang.String DATA_SMS_RECEIVED_ACTION = "android.intent.action.DATA_SMS_RECEIVED";
+    field public static final java.lang.String EXTRA_IS_DEFAULT_SMS_APP = "android.provider.extra.IS_DEFAULT_SMS_APP";
     field public static final java.lang.String EXTRA_PACKAGE_NAME = "package";
     field public static final int RESULT_SMS_DUPLICATED = 5; // 0x5
     field public static final int RESULT_SMS_GENERIC_ERROR = 2; // 0x2
@@ -30585,6 +30588,7 @@
     field public static final java.lang.String KEY_AUTO_RETRY_ENABLED_BOOL = "auto_retry_enabled_bool";
     field public static final java.lang.String KEY_CARRIER_ALLOW_TURNOFF_IMS_BOOL = "carrier_allow_turnoff_ims_bool";
     field public static final java.lang.String KEY_CARRIER_SETTINGS_ENABLE_BOOL = "carrier_settings_enable_bool";
+    field public static final java.lang.String KEY_CARRIER_USE_IMS_FIRST_FOR_EMERGENCY_BOOL = "carrier_use_ims_first_for_emergency_bool";
     field public static final java.lang.String KEY_CARRIER_VOLTE_AVAILABLE_BOOL = "carrier_volte_available_bool";
     field public static final java.lang.String KEY_CARRIER_VOLTE_PROVISIONING_REQUIRED_BOOL = "carrier_volte_provisioning_required_bool";
     field public static final java.lang.String KEY_CARRIER_VOLTE_TTY_SUPPORTED_BOOL = "carrier_volte_tty_supported_bool";
diff --git a/api/system-current.txt b/api/system-current.txt
index 3fd78e1..69777f9 100644
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -29066,7 +29066,10 @@
   public static final class Telephony.Sms.Intents {
     method public static android.telephony.SmsMessage[] getMessagesFromIntent(android.content.Intent);
     field public static final java.lang.String ACTION_CHANGE_DEFAULT = "android.provider.Telephony.ACTION_CHANGE_DEFAULT";
+    field public static final java.lang.String ACTION_DEFAULT_SMS_PACKAGE_CHANGED = "android.provider.action.DEFAULT_SMS_PACKAGE_CHANGED";
+    field public static final java.lang.String ACTION_EXTERNAL_PROVIDER_CHANGE = "android.provider.action.EXTERNAL_PROVIDER_CHANGE";
     field public static final java.lang.String DATA_SMS_RECEIVED_ACTION = "android.intent.action.DATA_SMS_RECEIVED";
+    field public static final java.lang.String EXTRA_IS_DEFAULT_SMS_APP = "android.provider.extra.IS_DEFAULT_SMS_APP";
     field public static final java.lang.String EXTRA_PACKAGE_NAME = "package";
     field public static final int RESULT_SMS_DUPLICATED = 5; // 0x5
     field public static final int RESULT_SMS_GENERIC_ERROR = 2; // 0x2
@@ -32829,6 +32832,7 @@
     field public static final java.lang.String KEY_AUTO_RETRY_ENABLED_BOOL = "auto_retry_enabled_bool";
     field public static final java.lang.String KEY_CARRIER_ALLOW_TURNOFF_IMS_BOOL = "carrier_allow_turnoff_ims_bool";
     field public static final java.lang.String KEY_CARRIER_SETTINGS_ENABLE_BOOL = "carrier_settings_enable_bool";
+    field public static final java.lang.String KEY_CARRIER_USE_IMS_FIRST_FOR_EMERGENCY_BOOL = "carrier_use_ims_first_for_emergency_bool";
     field public static final java.lang.String KEY_CARRIER_VOLTE_AVAILABLE_BOOL = "carrier_volte_available_bool";
     field public static final java.lang.String KEY_CARRIER_VOLTE_PROVISIONING_REQUIRED_BOOL = "carrier_volte_provisioning_required_bool";
     field public static final java.lang.String KEY_CARRIER_VOLTE_TTY_SUPPORTED_BOOL = "carrier_volte_tty_supported_bool";
diff --git a/core/java/android/content/pm/UserInfo.java b/core/java/android/content/pm/UserInfo.java
index c03be32..4d9c176 100644
--- a/core/java/android/content/pm/UserInfo.java
+++ b/core/java/android/content/pm/UserInfo.java
@@ -37,8 +37,8 @@
      */
 
     /**
-     * Primary user. Only one user can have this flag set. Meaning of this
-     * flag TBD.
+     * Primary user. Only one user can have this flag set. It identifies the first human user
+     * on a device.
      */
     public static final int FLAG_PRIMARY = 0x00000001;
 
diff --git a/core/java/android/os/IUserManager.aidl b/core/java/android/os/IUserManager.aidl
index 64877aa..364c0eb 100644
--- a/core/java/android/os/IUserManager.aidl
+++ b/core/java/android/os/IUserManager.aidl
@@ -40,6 +40,7 @@
     void setUserName(int userHandle, String name);
     void setUserIcon(int userHandle, in Bitmap icon);
     ParcelFileDescriptor getUserIcon(int userHandle);
+    UserInfo getPrimaryUser();
     List<UserInfo> getUsers(boolean excludeDying);
     List<UserInfo> getProfiles(int userHandle, boolean enabledOnly);
     boolean canAddMoreManagedProfiles();
diff --git a/core/java/android/os/UserHandle.java b/core/java/android/os/UserHandle.java
index bfca719..48ede4f 100644
--- a/core/java/android/os/UserHandle.java
+++ b/core/java/android/os/UserHandle.java
@@ -55,12 +55,26 @@
     /** @hide An undefined user id */
     public static final int USER_NULL = -10000;
 
-    /** @hide A user id constant to indicate the "owner" user of the device */
+    /**
+     * @hide A user id constant to indicate the "owner" user of the device
+     * @deprecated Consider using either USER_SYSTEM constant or
+     * UserInfo.isPrimary().
+     */
     public static final int USER_OWNER = 0;
 
-    /** @hide A user handle to indicate the primary/owner user of the device */
+    /**
+     * @hide A user handle to indicate the primary/owner user of the device
+     * @deprecated Consider using either SYSTEM constant or
+     * UserInfo.isPrimary().
+     */
     public static final UserHandle OWNER = new UserHandle(USER_OWNER);
 
+    /** @hide A user id constant to indicate the "system" user of the device */
+    public static final int USER_SYSTEM = 0;
+
+    /** @hide A user handle to indicate the "system" user of the device */
+    public static final UserHandle SYSTEM = new UserHandle(USER_SYSTEM);
+
     /**
      * @hide Enable multi-user related side effects. Set this to false if
      * there are problems with single user use-cases.
@@ -120,7 +134,7 @@
         if (MU_ENABLED) {
             return uid / PER_USER_RANGE;
         } else {
-            return 0;
+            return UserHandle.USER_SYSTEM;
         }
     }
 
diff --git a/core/java/android/os/UserManager.java b/core/java/android/os/UserManager.java
index 045c1e8..e2cf08e5 100644
--- a/core/java/android/os/UserManager.java
+++ b/core/java/android/os/UserManager.java
@@ -563,6 +563,18 @@
     }
 
     /**
+     * Used to check if this process is running under the primary user. The primary user
+     * is the first human user on a device.
+     *
+     * @return whether this process is running under the primary user.
+     * @hide
+     */
+    public boolean isPrimaryUser() {
+        UserInfo user = getUserInfo(UserHandle.myUserId());
+        return user != null ? user.isPrimary() : false;
+    }
+
+    /**
      * Used to check if this process is running under the system user. The system user
      * is the initial user that is implicitly created on first boot and hosts most of the
      * system services.
@@ -570,9 +582,8 @@
      * @return whether this process is running under the system user.
      */
     public boolean isSystemUser() {
-        return UserHandle.myUserId() == UserHandle.USER_OWNER;
+        return UserHandle.myUserId() == UserHandle.USER_SYSTEM;
     }
-
     /**
      * @hide
      * Returns whether the caller is running as an admin user. There can be more than one admin
@@ -971,6 +982,22 @@
     }
 
     /**
+     * Returns information for Primary user.
+     * Requires {@link android.Manifest.permission#MANAGE_USERS} permission.
+     *
+     * @return the Primary user, null if not found.
+     * @hide
+     */
+    public UserInfo getPrimaryUser() {
+        try {
+            return mService.getPrimaryUser();
+        } catch (RemoteException re) {
+            Log.w(TAG, "Could not get Primary user", re);
+            return null;
+        }
+    }
+
+    /**
      * Checks whether it's possible to add more users. Caller must hold the MANAGE_USERS
      * permission.
      *
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index 746e110..6a64817 100644
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -7498,6 +7498,18 @@
                 "sms_short_codes_metadata_url";
 
         /**
+         * URL for apn_db updates
+         * @hide
+         */
+        public static final String APN_DB_UPDATE_CONTENT_URL = "apn_db_content_url";
+
+        /**
+         * URL for apn_db update metadata
+         * @hide
+         */
+        public static final String APN_DB_UPDATE_METADATA_URL = "apn_db_metadata_url";
+
+        /**
          * URL for cert pinlist updates
          * @hide
          */
@@ -7653,7 +7665,7 @@
         public static final String REQUIRE_PASSWORD_TO_DECRYPT = "require_password_to_decrypt";
 
         /**
-         * Whether the Volte/VT is enabled
+         * Whether the Volte is enabled
          * <p>
          * Type: int (0 for false, 1 for true)
          * @hide
@@ -7661,6 +7673,15 @@
         public static final String ENHANCED_4G_MODE_ENABLED = "volte_vt_enabled";
 
         /**
+         * Whether VT (Video Telephony over IMS) is enabled
+         * <p>
+         * Type: int (0 for false, 1 for true)
+         *
+         * @hide
+         */
+        public static final String VT_IMS_ENABLED = "vt_ims_enabled";
+
+        /**
          * Whether WFC is enabled
          * <p>
          * Type: int (0 for false, 1 for true)
diff --git a/core/java/com/android/internal/logging/MetricsLogger.java b/core/java/com/android/internal/logging/MetricsLogger.java
index b6240e4..9253ebb 100644
--- a/core/java/com/android/internal/logging/MetricsLogger.java
+++ b/core/java/com/android/internal/logging/MetricsLogger.java
@@ -27,6 +27,7 @@
  */
 public class MetricsLogger implements MetricsConstants {
     // Temporary constants go here, to await migration to MetricsConstants.
+
     // next value is 239;
     public static final int ACTION_ASSIST_LONG_PRESS = 239;
     public static final int FINGERPRINT_ENROLLING = 240;
@@ -46,6 +47,7 @@
     public static final int ACTION_FINGERPRINT_RENAME = 254;
     public static final int ACTION_DOUBLE_TAP_POWER_CAMERA_GESTURE = 255;
     public static final int ACTION_WIGGLE_CAMERA_GESTURE = 256;
+    public static final int ACTION_DEFAULT_SMS_APP_CHANGED = 264;
 
     public static void visible(Context context, int category) throws IllegalArgumentException {
         if (Build.IS_DEBUGGABLE && category == VIEW_UNKNOWN) {
diff --git a/core/java/com/android/internal/util/StateMachine.java b/core/java/com/android/internal/util/StateMachine.java
index 447292c..be78a12 100644
--- a/core/java/com/android/internal/util/StateMachine.java
+++ b/core/java/com/android/internal/util/StateMachine.java
@@ -1879,6 +1879,33 @@
     }
 
     /**
+     * Check if there are any pending messages with code 'what' in deferred messages queue.
+     */
+    protected final boolean hasDeferredMessages(int what) {
+        SmHandler smh = mSmHandler;
+        if (smh == null) return false;
+
+        Iterator<Message> iterator = smh.mDeferredMessages.iterator();
+        while (iterator.hasNext()) {
+            Message msg = iterator.next();
+            if (msg.what == what) return true;
+        }
+
+        return false;
+    }
+
+    /**
+     * Check if there are any pending posts of messages with code 'what' in
+     * the message queue. This does NOT check messages in deferred message queue.
+     */
+    protected final boolean hasMessages(int what) {
+        SmHandler smh = mSmHandler;
+        if (smh == null) return false;
+
+        return smh.hasMessages(what);
+    }
+
+    /**
      * Validate that the message was sent by
      * {@link StateMachine#quit} or {@link StateMachine#quitNow}.
      * */
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index 28933e1..7f25d67 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -2845,6 +2845,14 @@
             </intent-filter>
         </receiver>
 
+        <receiver android:name="com.android.server.updates.ApnDbInstallReceiver"
+                android:permission="android.permission.UPDATE_CONFIG">
+            <intent-filter>
+                <action android:name="android.intent.action.UPDATE_APN_DB" />
+                <data android:scheme="content" android:host="*" android:mimeType="*/*" />
+            </intent-filter>
+        </receiver>
+
         <receiver android:name="com.android.server.updates.CarrierProvisioningUrlsInstallReceiver"
                 android:permission="android.permission.UPDATE_CONFIG">
             <intent-filter>
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index 6d84099..8cb686a 100644
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -2081,10 +2081,6 @@
         IMS service implementation will do both.i.e.hold followed by merge. -->
     <bool name="skipHoldBeforeMerge">true</bool>
 
-    <!-- Flag indicating emergency calls will always use IMS irrespective of the state of
-    the IMS connection -->
-    <bool name="useImsAlwaysForEmergencyCall">true</bool>
-
     <!-- Flag indicating whether the IMS service can be turned off. If false then
         the service will not be turned-off completely (the ImsManager.turnOffIms() will
         be disabled) but individual Features can be disabled using ImsConfig.setFeatureValue() -->
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index 8c00251..ad3b889 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -2162,7 +2162,6 @@
   <java-symbol type="bool" name="config_carrier_vt_available" />
   <java-symbol type="bool" name="config_device_wfc_ims_available" />
   <java-symbol type="bool" name="config_carrier_wfc_ims_available" />
-  <java-symbol type="bool" name="useImsAlwaysForEmergencyCall" />
   <java-symbol type="attr" name="touchscreenBlocksFocus" />
   <java-symbol type="layout" name="resolver_list_with_default" />
   <java-symbol type="string" name="whichApplicationNamed" />
diff --git a/services/core/java/com/android/server/location/GpsLocationProvider.java b/services/core/java/com/android/server/location/GpsLocationProvider.java
index 4f42f83..9216f07 100644
--- a/services/core/java/com/android/server/location/GpsLocationProvider.java
+++ b/services/core/java/com/android/server/location/GpsLocationProvider.java
@@ -499,6 +499,12 @@
 
     private void checkSmsSuplInit(Intent intent) {
         SmsMessage[] messages = Intents.getMessagesFromIntent(intent);
+
+        if (messages == null) {
+            Log.e(TAG, "Message does not exist in the intent.");
+            return;
+        }
+
         for (int i=0; i <messages.length; i++) {
             byte[] supl_init = messages[i].getUserData();
             native_agps_ni_message(supl_init,supl_init.length);
diff --git a/services/core/java/com/android/server/pm/UserManagerService.java b/services/core/java/com/android/server/pm/UserManagerService.java
index 06c3682..dbe163b 100644
--- a/services/core/java/com/android/server/pm/UserManagerService.java
+++ b/services/core/java/com/android/server/pm/UserManagerService.java
@@ -219,7 +219,7 @@
                 mUsersDir = new File(dataDir, USER_INFO_DIR);
                 mUsersDir.mkdirs();
                 // Make zeroth user directory, for services to migrate their files to that location
-                File userZeroDir = new File(mUsersDir, "0");
+                File userZeroDir = new File(mUsersDir, String.valueOf(UserHandle.USER_SYSTEM));
                 userZeroDir.mkdirs();
                 FileUtils.setPermissions(mUsersDir.toString(),
                         FileUtils.S_IRWXU|FileUtils.S_IRWXG
@@ -252,7 +252,7 @@
                 }
             }
         }
-        onUserForeground(UserHandle.USER_OWNER);
+        onUserForeground(UserHandle.USER_SYSTEM);
         mAppOpsService = IAppOpsService.Stub.asInterface(
                 ServiceManager.getService(Context.APP_OPS_SERVICE));
         for (int i = 0; i < mUserIds.length; ++i) {
@@ -265,6 +265,20 @@
     }
 
     @Override
+    public UserInfo getPrimaryUser() {
+        checkManageUsersPermission("query users");
+        synchronized (mPackagesLock) {
+            for (int i = 0; i < mUsers.size(); i++) {
+                UserInfo ui = mUsers.valueAt(i);
+                if (ui.isPrimary()) {
+                    return ui;
+                }
+            }
+        }
+        return null;
+    }
+
+    @Override
     public List<UserInfo> getUsers(boolean excludeDying) {
         checkManageUsersPermission("query users");
         synchronized (mPackagesLock) {
@@ -836,22 +850,23 @@
     }
 
     private void fallbackToSingleUserLocked() {
-        // Create the primary user
-        UserInfo primary = new UserInfo(UserHandle.USER_OWNER,
+        // Create the system user
+        // TODO: UserInfo.FLAG_PRIMARY flag should be set on the first human user.
+        UserInfo system = new UserInfo(UserHandle.USER_SYSTEM,
                 mContext.getResources().getString(com.android.internal.R.string.owner_name), null,
                 UserInfo.FLAG_ADMIN | UserInfo.FLAG_PRIMARY | UserInfo.FLAG_INITIALIZED);
-        mUsers.put(0, primary);
+        mUsers.put(system.id, system);
         mNextSerialNumber = MIN_USER_ID;
         mUserVersion = USER_VERSION;
 
         Bundle restrictions = new Bundle();
-        mUserRestrictions.append(UserHandle.USER_OWNER, restrictions);
+        mUserRestrictions.append(UserHandle.USER_SYSTEM, restrictions);
 
         updateUserIdsLocked();
         initDefaultGuestRestrictions();
 
         writeUserListLocked();
-        writeUserLocked(primary);
+        writeUserLocked(system);
     }
 
     private void scheduleWriteUserLocked(UserInfo userInfo) {
diff --git a/services/core/java/com/android/server/updates/ApnDbInstallReceiver.java b/services/core/java/com/android/server/updates/ApnDbInstallReceiver.java
new file mode 100644
index 0000000..3b6f9d6
--- /dev/null
+++ b/services/core/java/com/android/server/updates/ApnDbInstallReceiver.java
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.updates;
+
+import android.content.ContentResolver;
+import android.content.ContentUris;
+import android.content.Context;
+import android.content.Intent;
+import android.net.Uri;
+import android.provider.Telephony;
+
+public class ApnDbInstallReceiver extends ConfigUpdateInstallReceiver {
+
+    private static final Uri UPDATE_APN_DB = Uri.withAppendedPath(Telephony.Carriers.CONTENT_URI,
+            "update_db");
+
+    public ApnDbInstallReceiver() {
+        super("/data/misc/", "apns-conf.xml", "metadata/", "version");
+    }
+
+    @Override
+    protected void postInstall(Context context, Intent intent) {
+        ContentResolver resolver = context.getContentResolver();
+        resolver.delete(UPDATE_APN_DB, null, null);
+    }
+}
diff --git a/services/java/com/android/server/SystemServer.java b/services/java/com/android/server/SystemServer.java
index 0e475b0..0619d76 100644
--- a/services/java/com/android/server/SystemServer.java
+++ b/services/java/com/android/server/SystemServer.java
@@ -432,6 +432,7 @@
         NsdService serviceDiscovery= null;
         WindowManagerService wm = null;
         UsbService usb = null;
+        BluetoothManagerService bluetooth = null;
         SerialService serial = null;
         NetworkTimeUpdateService networkTimeUpdater = null;
         CommonTimeManagementService commonTimeMgmtService = null;
@@ -441,7 +442,6 @@
         AudioService audioService = null;
         MmsServiceBroker mmsService = null;
         EntropyMixer entropyMixer = null;
-        CameraService cameraService = null;
 
         boolean disableStorage = SystemProperties.getBoolean("config.disable_storage", false);
         boolean disableBluetooth = SystemProperties.getBoolean("config.disable_bluetooth", false);
@@ -1333,7 +1333,7 @@
         intent.setComponent(new ComponentName("com.android.systemui",
                     "com.android.systemui.SystemUIService"));
         //Slog.d(TAG, "Starting service: " + intent);
-        context.startServiceAsUser(intent, UserHandle.OWNER);
+        context.startServiceAsUser(intent, UserHandle.SYSTEM);
     }
 
     private static void traceBeginAndSlog(String name) {
diff --git a/telecomm/java/android/telecom/Conference.java b/telecomm/java/android/telecom/Conference.java
index 77fdb65..094b3a9 100644
--- a/telecomm/java/android/telecom/Conference.java
+++ b/telecomm/java/android/telecom/Conference.java
@@ -65,6 +65,7 @@
     private final List<Connection> mUnmodifiableConferenceableConnections =
             Collections.unmodifiableList(mConferenceableConnections);
 
+    private String mTelecomCallId;
     private PhoneAccountHandle mPhoneAccount;
     private CallAudioState mCallAudioState;
     private int mState = Connection.STATE_NEW;
@@ -94,6 +95,26 @@
     }
 
     /**
+     * Returns the telecom internal call ID associated with this conference.
+     *
+     * @return The telecom call ID.
+     * @hide
+     */
+    public final String getTelecomCallId() {
+        return mTelecomCallId;
+    }
+
+    /**
+     * Sets the telecom internal call ID associated with this conference.
+     *
+     * @param telecomCallId The telecom call ID.
+     * @hide
+     */
+    public final void setTelecomCallId(String telecomCallId) {
+        mTelecomCallId = telecomCallId;
+    }
+
+    /**
      * Returns the {@link PhoneAccountHandle} the conference call is being placed through.
      *
      * @return A {@code PhoneAccountHandle} object representing the PhoneAccount of the conference.
diff --git a/telecomm/java/android/telecom/Connection.java b/telecomm/java/android/telecom/Connection.java
index 430760a..4115756 100644
--- a/telecomm/java/android/telecom/Connection.java
+++ b/telecomm/java/android/telecom/Connection.java
@@ -1074,6 +1074,8 @@
     private final List<Conferenceable> mUnmodifiableConferenceables =
             Collections.unmodifiableList(mConferenceables);
 
+    // The internal telecom call ID associated with this connection.
+    private String mTelecomCallId;
     private int mState = STATE_NEW;
     private CallAudioState mCallAudioState;
     private Uri mAddress;
@@ -1098,6 +1100,17 @@
     public Connection() {}
 
     /**
+     * Returns the Telecom internal call ID associated with this connection.  Should only be used
+     * for debugging and tracing purposes.
+     *
+     * @return The Telecom call ID.
+     * @hide
+     */
+    public final String getTelecomCallId() {
+        return mTelecomCallId;
+    }
+
+    /**
      * @return The address (e.g., phone number) to which this Connection is currently communicating.
      */
     public final Uri getAddress() {
@@ -1259,6 +1272,17 @@
     }
 
     /**
+     * Sets the telecom call ID associated with this Connection.  The Telecom Call ID should be used
+     * ONLY for debugging purposes.
+     *
+     * @param callId The telecom call ID.
+     * @hide
+     */
+    public void setTelecomCallId(String callId) {
+        mTelecomCallId = callId;
+    }
+
+    /**
      * Inform this Connection that the state of its audio output has been changed externally.
      *
      * @param state The new audio state.
diff --git a/telecomm/java/android/telecom/ConnectionRequest.java b/telecomm/java/android/telecom/ConnectionRequest.java
index 6863214..aba38fe 100644
--- a/telecomm/java/android/telecom/ConnectionRequest.java
+++ b/telecomm/java/android/telecom/ConnectionRequest.java
@@ -32,6 +32,7 @@
     private final Uri mAddress;
     private final Bundle mExtras;
     private final int mVideoState;
+    private final String mTelecomCallId;
 
     /**
      * @param accountHandle The accountHandle which should be used to place the call.
@@ -42,7 +43,7 @@
             PhoneAccountHandle accountHandle,
             Uri handle,
             Bundle extras) {
-        this(accountHandle, handle, extras, VideoProfile.STATE_AUDIO_ONLY);
+        this(accountHandle, handle, extras, VideoProfile.STATE_AUDIO_ONLY, null);
     }
 
     /**
@@ -56,10 +57,28 @@
             Uri handle,
             Bundle extras,
             int videoState) {
+        this(accountHandle, handle, extras, videoState, null);
+    }
+
+    /**
+     * @param accountHandle The accountHandle which should be used to place the call.
+     * @param handle The handle (e.g., phone number) to which the {@link Connection} is to connect.
+     * @param extras Application-specific extra data.
+     * @param videoState Determines the video state for the connection.
+     * @param telecomCallId The telecom call ID.
+     * @hide
+     */
+    public ConnectionRequest(
+            PhoneAccountHandle accountHandle,
+            Uri handle,
+            Bundle extras,
+            int videoState,
+            String telecomCallId) {
         mAccountHandle = accountHandle;
         mAddress = handle;
         mExtras = extras;
         mVideoState = videoState;
+        mTelecomCallId = telecomCallId;
     }
 
     private ConnectionRequest(Parcel in) {
@@ -67,6 +86,7 @@
         mAddress = in.readParcelable(getClass().getClassLoader());
         mExtras = in.readParcelable(getClass().getClassLoader());
         mVideoState = in.readInt();
+        mTelecomCallId = in.readString();
     }
 
     /**
@@ -99,6 +119,16 @@
         return mVideoState;
     }
 
+    /**
+     * Returns the internal Telecom ID associated with the connection request.
+     *
+     * @return The Telecom ID.
+     * @hide
+     */
+    public String getTelecomCallId() {
+        return mTelecomCallId;
+    }
+
     @Override
     public String toString() {
         return String.format("ConnectionRequest %s %s",
@@ -134,5 +164,6 @@
         destination.writeParcelable(mAddress, 0);
         destination.writeParcelable(mExtras, 0);
         destination.writeInt(mVideoState);
+        destination.writeString(mTelecomCallId);
     }
 }
diff --git a/telecomm/java/android/telecom/ConnectionService.java b/telecomm/java/android/telecom/ConnectionService.java
index 4e330bdb..6223495 100644
--- a/telecomm/java/android/telecom/ConnectionService.java
+++ b/telecomm/java/android/telecom/ConnectionService.java
@@ -116,6 +116,8 @@
 
     private boolean mAreAccountsInitialized = false;
     private Conference sNullConference;
+    private Object mIdSyncRoot = new Object();
+    private int mId = 0;
 
     private final IBinder mBinder = new IConnectionService.Stub() {
         @Override
@@ -629,7 +631,8 @@
             boolean isIncoming,
             boolean isUnknown) {
         Log.d(this, "createConnection, callManagerAccount: %s, callId: %s, request: %s, " +
-                "isIncoming: %b, isUnknown: %b", callManagerAccount, callId, request, isIncoming,
+                        "isIncoming: %b, isUnknown: %b", callManagerAccount, callId, request,
+                isIncoming,
                 isUnknown);
 
         Connection connection = isUnknown ? onCreateUnknownConnection(callManagerAccount, request)
@@ -641,6 +644,7 @@
                     new DisconnectCause(DisconnectCause.ERROR));
         }
 
+        connection.setTelecomCallId(callId);
         if (connection.getState() != Connection.STATE_DISCONNECTED) {
             addConnection(callId, connection);
         }
@@ -953,6 +957,7 @@
                     connectionIds.add(mIdByConnection.get(connection));
                 }
             }
+            conference.setTelecomCallId(id);
             ParcelableConference parcelableConference = new ParcelableConference(
                     conference.getPhoneAccountHandle(),
                     conference.getState(),
@@ -989,7 +994,7 @@
     public final void addExistingConnection(PhoneAccountHandle phoneAccountHandle,
             Connection connection) {
 
-        String id = addExistingConnectionInternal(connection);
+        String id = addExistingConnectionInternal(phoneAccountHandle, connection);
         if (id != null) {
             List<String> emptyList = new ArrayList<>(0);
 
@@ -1151,18 +1156,29 @@
     }
 
     /**
-     * Adds an existing connection to the list of connections, identified by a new UUID.
+     * Adds an existing connection to the list of connections, identified by a new call ID unique
+     * to this connection service.
      *
      * @param connection The connection.
-     * @return The UUID of the connection (e.g. the call-id).
+     * @return The ID of the connection (e.g. the call-id).
      */
-    private String addExistingConnectionInternal(Connection connection) {
-        String id = UUID.randomUUID().toString();
+    private String addExistingConnectionInternal(PhoneAccountHandle handle, Connection connection) {
+        String id;
+        if (handle == null) {
+            // If no phone account handle was provided, we cannot be sure the call ID is unique,
+            // so just use a random UUID.
+            id = UUID.randomUUID().toString();
+        } else {
+            // Phone account handle was provided, so use the ConnectionService class name as a
+            // prefix for a unique incremental call ID.
+            id = handle.getComponentName().getClassName() + "@" + getNextCallId();
+        }
         addConnection(id, connection);
         return id;
     }
 
     private void addConnection(String callId, Connection connection) {
+        connection.setTelecomCallId(callId);
         mConnectionById.put(callId, connection);
         mIdByConnection.put(connection, callId);
         connection.addConnectionListener(mConnectionListener);
@@ -1183,6 +1199,9 @@
         if (mIdByConference.containsKey(conference)) {
             Log.w(this, "Re-adding an existing conference: %s.", conference);
         } else if (conference != null) {
+            // Conferences do not (yet) have a PhoneAccountHandle associated with them, so we
+            // cannot determine a ConnectionService class name to associate with the ID, so use
+            // a unique UUID (for now).
             String id = UUID.randomUUID().toString();
             mConferenceById.put(id, conference);
             mIdByConference.put(conference, id);
@@ -1284,4 +1303,15 @@
             conference.onDisconnect();
         }
     }
+
+    /**
+     * Retrieves the next call ID as maintainted by the connection service.
+     *
+     * @return The call ID.
+     */
+    private int getNextCallId() {
+        synchronized(mIdSyncRoot) {
+            return ++mId;
+        }
+    }
 }
diff --git a/telephony/java/android/telephony/CarrierConfigManager.java b/telephony/java/android/telephony/CarrierConfigManager.java
index 29e54a3..5392a5a 100644
--- a/telephony/java/android/telephony/CarrierConfigManager.java
+++ b/telephony/java/android/telephony/CarrierConfigManager.java
@@ -282,6 +282,13 @@
     public static final String KEY_CARRIER_INSTANT_LETTERING_AVAILABLE_BOOL =
             "carrier_instant_lettering_available_bool";
 
+    /*
+     * Flag specifying whether IMS should be the first phone attempted for E911 even if the
+     * phone is not in service.
+     */
+    public static final String KEY_CARRIER_USE_IMS_FIRST_FOR_EMERGENCY_BOOL
+            = "carrier_use_ims_first_for_emergency_bool";
+
     /**
      * When IMS instant lettering is available for a carrier (see
      * {@link #KEY_CARRIER_INSTANT_LETTERING_AVAILABLE_BOOL}), determines the list of characters
@@ -514,6 +521,7 @@
         sDefaults.putBoolean(KEY_CARRIER_INSTANT_LETTERING_AVAILABLE_BOOL, false);
         sDefaults.putString(KEY_CARRIER_INSTANT_LETTERING_INVALID_CHARS_STRING, "");
         sDefaults.putString(KEY_CARRIER_INSTANT_LETTERING_ESCAPED_CHARS_STRING, "");
+        sDefaults.putBoolean(KEY_CARRIER_USE_IMS_FIRST_FOR_EMERGENCY_BOOL, true);
         sDefaults.putBoolean(KEY_DISABLE_CDMA_ACTIVATION_CODE_BOOL, false);
         sDefaults.putBoolean(KEY_DTMF_TYPE_ENABLED_BOOL, false);
         sDefaults.putBoolean(KEY_ENABLE_DIALER_KEY_VIBRATION_BOOL, true);
diff --git a/telephony/java/android/telephony/CellLocation.java b/telephony/java/android/telephony/CellLocation.java
index f9a222f..5bcaa6e 100644
--- a/telephony/java/android/telephony/CellLocation.java
+++ b/telephony/java/android/telephony/CellLocation.java
@@ -81,6 +81,12 @@
     public abstract boolean isEmpty();
 
     /**
+     * Invalidate this object.  The location area code and the cell id are set to -1.
+     * @hide
+     */
+    public abstract void setStateInvalid();
+
+    /**
      * Return a new CellLocation object representing an unknown
      * location, or null for unknown/none phone radio types.
      *
diff --git a/telephony/java/android/telephony/PhoneNumberUtils.java b/telephony/java/android/telephony/PhoneNumberUtils.java
index b430340..553221d 100644
--- a/telephony/java/android/telephony/PhoneNumberUtils.java
+++ b/telephony/java/android/telephony/PhoneNumberUtils.java
@@ -2354,7 +2354,7 @@
                         tempDialStr = postDialStr.substring(dialableIndex);
                     } else {
                         // Non-dialable character such as P/W should not be at the end of
-                        // the dial string after P/W processing in CdmaConnection.java
+                        // the dial string after P/W processing in GsmCdmaConnection.java
                         // Set the postDialStr to "" to break out of the loop
                         if (dialableIndex < 0) {
                             postDialStr = "";
diff --git a/telephony/java/android/telephony/ServiceState.java b/telephony/java/android/telephony/ServiceState.java
index 1337487..8537f9c 100644
--- a/telephony/java/android/telephony/ServiceState.java
+++ b/telephony/java/android/telephony/ServiceState.java
@@ -906,7 +906,7 @@
 
     /**
      * In CDMA, mOperatorAlphaLong can be set from the ERI text.
-     * This is done from the CDMAPhone and not from the CdmaServiceStateTracker.
+     * This is done from the GsmCdmaPhone and not from the ServiceStateTracker.
      *
      * @hide
      */
diff --git a/telephony/java/android/telephony/SubscriptionManager.java b/telephony/java/android/telephony/SubscriptionManager.java
index 32b7383..36407e1 100644
--- a/telephony/java/android/telephony/SubscriptionManager.java
+++ b/telephony/java/android/telephony/SubscriptionManager.java
@@ -75,7 +75,7 @@
 
     /**
      * Indicates the caller wants the default phone id.
-     * Used in SubscriptionController and PhoneBase but do we really need it???
+     * Used in SubscriptionController and Phone but do we really need it???
      * @hide
      */
     public static final int DEFAULT_PHONE_INDEX = Integer.MAX_VALUE;
diff --git a/telephony/java/android/telephony/TelephonyManager.java b/telephony/java/android/telephony/TelephonyManager.java
index 6b1b6296..3b281e2 100644
--- a/telephony/java/android/telephony/TelephonyManager.java
+++ b/telephony/java/android/telephony/TelephonyManager.java
@@ -4848,4 +4848,21 @@
         }
         return null;
     }
-}
+
+    /**
+     * Returns the service state information on specified subscription. Callers require
+     * either READ_PRIVILEGED_PHONE_STATE or READ_PHONE_STATE to retrieve the information.
+     * @hide
+     */
+    public ServiceState getServiceStateForSubscriber(int subId) {
+        try {
+            ITelephony service = getITelephony();
+            if (service != null) {
+                return service.getServiceStateForSubscriber(subId, getOpPackageName());
+            }
+        } catch (RemoteException e) {
+            Log.e(TAG, "Error calling ITelephony#getServiceStateForSubscriber", e);
+        }
+        return null;
+    }
+}
\ No newline at end of file
diff --git a/telephony/java/android/telephony/cdma/CdmaCellLocation.java b/telephony/java/android/telephony/cdma/CdmaCellLocation.java
index 6cfae6a..7c10569 100644
--- a/telephony/java/android/telephony/cdma/CdmaCellLocation.java
+++ b/telephony/java/android/telephony/cdma/CdmaCellLocation.java
@@ -123,6 +123,7 @@
     /**
      * Invalidate this object.  The cell location data is set to invalid values.
      */
+    @Override
     public void setStateInvalid() {
         this.mBaseStationId = -1;
         this.mBaseStationLatitude = INVALID_LAT_LONG;
@@ -134,7 +135,7 @@
     /**
      * Set the cell location data.
      */
-     public void setCellLocationData(int baseStationId, int baseStationLatitude,
+    public void setCellLocationData(int baseStationId, int baseStationLatitude,
          int baseStationLongitude) {
          // The following values have to be written in the correct sequence
          this.mBaseStationId = baseStationId;
diff --git a/telephony/java/android/telephony/gsm/GsmCellLocation.java b/telephony/java/android/telephony/gsm/GsmCellLocation.java
index a3889b2..1717802 100644
--- a/telephony/java/android/telephony/gsm/GsmCellLocation.java
+++ b/telephony/java/android/telephony/gsm/GsmCellLocation.java
@@ -72,6 +72,7 @@
     /**
      * Invalidate this object.  The location area code and the cell id are set to -1.
      */
+    @Override
     public void setStateInvalid() {
         mLac = -1;
         mCid = -1;
diff --git a/telephony/java/com/android/internal/telephony/GsmAlphabet.java b/telephony/java/com/android/internal/telephony/GsmAlphabet.java
index ef39a6c..4785169 100644
--- a/telephony/java/com/android/internal/telephony/GsmAlphabet.java
+++ b/telephony/java/com/android/internal/telephony/GsmAlphabet.java
@@ -1012,7 +1012,7 @@
      *
      * @param tables the new list of enabled single shift tables
      */
-    static synchronized void setEnabledSingleShiftTables(int[] tables) {
+    public static synchronized void setEnabledSingleShiftTables(int[] tables) {
         sEnabledSingleShiftTables = tables;
         sDisableCountryEncodingCheck = true;
 
@@ -1030,7 +1030,7 @@
      *
      * @param tables the new list of enabled locking shift tables
      */
-    static synchronized void setEnabledLockingShiftTables(int[] tables) {
+    public static synchronized void setEnabledLockingShiftTables(int[] tables) {
         sEnabledLockingShiftTables = tables;
         sDisableCountryEncodingCheck = true;
     }
@@ -1042,7 +1042,7 @@
      *
      * @return the list of enabled single shift tables
      */
-    static synchronized int[] getEnabledSingleShiftTables() {
+    public static synchronized int[] getEnabledSingleShiftTables() {
         return sEnabledSingleShiftTables;
     }
 
@@ -1053,7 +1053,7 @@
      *
      * @return the list of enabled locking shift tables
      */
-    static synchronized int[] getEnabledLockingShiftTables() {
+    public static synchronized int[] getEnabledLockingShiftTables() {
         return sEnabledLockingShiftTables;
     }
 
diff --git a/telephony/java/com/android/internal/telephony/ITelephony.aidl b/telephony/java/com/android/internal/telephony/ITelephony.aidl
index dcece26..8172e94 100644
--- a/telephony/java/com/android/internal/telephony/ITelephony.aidl
+++ b/telephony/java/com/android/internal/telephony/ITelephony.aidl
@@ -21,9 +21,10 @@
 import android.telecom.PhoneAccount;
 import android.telephony.CellInfo;
 import android.telephony.IccOpenLogicalChannelResponse;
+import android.telephony.ModemActivityInfo;
 import android.telephony.NeighboringCellInfo;
 import android.telephony.RadioAccessFamily;
-import android.telephony.ModemActivityInfo;
+import android.telephony.ServiceState;
 import com.android.internal.telephony.CellNetworkScanResult;
 import com.android.internal.telephony.OperatorInfo;
 import java.util.List;
@@ -1005,4 +1006,12 @@
      * Return the modem activity info.
      */
     ModemActivityInfo getModemActivityInfo();
+
+    /**
+     * Get the service state on specified subscription
+     * @param subId Subscription id
+     * @param callingPackage The package making the call
+     * @return Service state on specified subscription.
+     */
+    ServiceState getServiceStateForSubscriber(int subId, String callingPackage);
 }
diff --git a/telephony/java/com/android/internal/telephony/PhoneConstants.java b/telephony/java/com/android/internal/telephony/PhoneConstants.java
index 572cc6f..a183de5 100644
--- a/telephony/java/com/android/internal/telephony/PhoneConstants.java
+++ b/telephony/java/com/android/internal/telephony/PhoneConstants.java
@@ -59,6 +59,9 @@
     public static final int PHONE_TYPE_SIP = RILConstants.SIP_PHONE;
     public static final int PHONE_TYPE_THIRD_PARTY = RILConstants.THIRD_PARTY_PHONE;
     public static final int PHONE_TYPE_IMS = RILConstants.IMS_PHONE;
+    // Currently this is used only to differentiate CDMA and CDMALTE Phone in GsmCdma* files. For
+    // anything outside of that, a cdma + lte phone is still CDMA_PHONE
+    public static final int PHONE_TYPE_CDMA_LTE = RILConstants.CDMA_LTE_PHONE;
 
     // Modes for LTE_ON_CDMA
     public static final int LTE_ON_CDMA_UNKNOWN = RILConstants.LTE_ON_CDMA_UNKNOWN;
diff --git a/telephony/java/com/android/internal/telephony/RILConstants.java b/telephony/java/com/android/internal/telephony/RILConstants.java
index 7088be8..3c4c04b 100644
--- a/telephony/java/com/android/internal/telephony/RILConstants.java
+++ b/telephony/java/com/android/internal/telephony/RILConstants.java
@@ -118,6 +118,7 @@
     int SIP_PHONE  = 3;
     int THIRD_PARTY_PHONE = 4;
     int IMS_PHONE = 5;
+    int CDMA_LTE_PHONE = 6;
 
     int LTE_ON_CDMA_UNKNOWN = -1;
     int LTE_ON_CDMA_FALSE = 0;