Merge "Set presence capability based on carrier config."
diff --git a/res/drawable/ic_settings_lock_outline.xml b/res/drawable/ic_settings_lock_outline.xml
new file mode 100644
index 0000000..fdc67f5
--- /dev/null
+++ b/res/drawable/ic_settings_lock_outline.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+     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.
+-->
+
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+        android:width="24dp"
+        android:height="24dp"
+        android:viewportWidth="24.0"
+        android:viewportHeight="24.0"
+        android:tint="?android:attr/colorAccent">
+    <path
+            android:fillColor="@android:color/white"
+            android:pathData="M12 17c1.1 0 2-.9 2-2s-.9-2-2-2-2 .9-2 2 .9 2 2 2zm6-9h-1V6c0-2.76-2.24-5-5-5S7 3.24 7 6v2H6c-1.1 0-2 .9-2 2v10c0 1.1.9 2 2 2h12c1.1 0 2-.9 2-2V10c0-1.1-.9-2-2-2zM8.9 6c0-1.71 1.39-3.1 3.1-3.1s3.1 1.39 3.1 3.1v2H8.9V6zM18 20H6V10h12v10z" />
+</vector>
diff --git a/res/values-b+sr+Latn/strings.xml b/res/values-b+sr+Latn/strings.xml
index 34968aa..bef9186 100644
--- a/res/values-b+sr+Latn/strings.xml
+++ b/res/values-b+sr+Latn/strings.xml
@@ -143,7 +143,7 @@
     <string name="vm_change_failed" msgid="3352934863246208918">"Nije moguće promeniti broj govorne pošte.\nKontaktirajte mobilnog operatera ako se ovaj problem nastavi."</string>
     <string name="fw_change_failed" msgid="5298103228470214665">"Nije moguće promeniti broj za preusmeravanje.\nKontaktirajte mobilnog operatera ako se ovaj problem nastavi."</string>
     <string name="fw_get_in_vm_failed" msgid="8862896836093833973">"Nije moguće preuzeti i sačuvati trenutna podešavanja broja za prosleđivanje.\nŽelite li da ipak pređete na novog dobavljača?"</string>
-    <string name="no_change" msgid="3186040086622435212">"Nisu načinjene promene."</string>
+    <string name="no_change" msgid="3186040086622435212">"Nisu izvršene nikakve promene."</string>
     <string name="sum_voicemail_choose_provider" msgid="59911196126278922">"Odaberite uslugu govorne pošte"</string>
     <string name="voicemail_default" msgid="2001233554889016880">"Mobilni operater"</string>
     <string name="mobile_networks" msgid="2843854043339307375">"Podešavanja mobilne mreže"</string>
diff --git a/res/values-mk-rMK/strings.xml b/res/values-mk-rMK/strings.xml
index 5c53aac..de50ece 100644
--- a/res/values-mk-rMK/strings.xml
+++ b/res/values-mk-rMK/strings.xml
@@ -58,7 +58,7 @@
     <string name="labelCDMAMore" msgid="1630676740428229339">"CDMA подесувања на повик"</string>
     <string name="labelCdmaMore_with_label" msgid="6333588719319970399">"Поставки за повик преку CDMA (<xliff:g id="SUBSCRIPTIONLABEL">%s</xliff:g>)"</string>
     <string name="apn_settings" msgid="9043423184895642077">"Имиња на точка на пристап"</string>
-    <string name="settings_label" msgid="3876743539816984008">"Подесувања на мрежа"</string>
+    <string name="settings_label" msgid="3876743539816984008">"Поставки на мрежа"</string>
     <string name="phone_accounts" msgid="6376603393888116364">"Сметки за повикување"</string>
     <string name="phone_accounts_make_calls_with" msgid="1969188078933152231">"Повикувајте со"</string>
     <string name="phone_accounts_make_sip_calls_with" msgid="4677789312053828493">"Повикувајте со СИП со"</string>
@@ -77,13 +77,13 @@
     <string name="voicemail_abbreviated" msgid="2215592488517217448">"ГП:"</string>
     <string name="networks" msgid="8873030692174541976">"Оператори на мрежа"</string>
     <string name="cell_broadcast_settings" msgid="8740238216690502563">"Итни емитувања"</string>
-    <string name="call_settings" msgid="6112441768261754562">"Подесувања на повик"</string>
+    <string name="call_settings" msgid="6112441768261754562">"Поставки на повик"</string>
     <string name="additional_gsm_call_settings" msgid="1391795981938800617">"Дополнителни подесувања"</string>
     <string name="additional_gsm_call_settings_with_label" msgid="1385241520708457376">"Дополнителни поставки (<xliff:g id="SUBSCRIPTIONLABEL">%s</xliff:g>)"</string>
     <string name="sum_gsm_call_settings" msgid="4076647190996778012">"Дополнителни подесувања на повик само за GSM"</string>
     <string name="additional_cdma_call_settings" msgid="8628958775721886909">"Дополнителни CDMA подесувања на повик"</string>
     <string name="sum_cdma_call_settings" msgid="284753265979035549">"Дополнителни подесувања на повик само за CDMA"</string>
-    <string name="labelNwService" msgid="4699970172021870983">"Подесувања на мрежна услуга"</string>
+    <string name="labelNwService" msgid="4699970172021870983">"Поставки на мрежна услуга"</string>
     <string name="labelCallerId" msgid="3888899447379069198">"ИД на повикувач"</string>
     <string name="sum_loading_settings" msgid="1826692909391168620">"Вчитување на подесувањата..."</string>
     <string name="sum_hide_caller_id" msgid="1071407020290873782">"Број скриен при појдовни повици"</string>
@@ -92,7 +92,7 @@
     <string name="labelCW" msgid="6120513814915920200">"Повик на чекање"</string>
     <string name="sum_cw_enabled" msgid="8083061901633671397">"За време на повик, извести ме за дојдовни повици"</string>
     <string name="sum_cw_disabled" msgid="3648693907300104575">"За време на повик, извести ме за дојдовни повици"</string>
-    <string name="call_forwarding_settings" msgid="3378927671091537173">"Подесувања за проследување повик"</string>
+    <string name="call_forwarding_settings" msgid="3378927671091537173">"Поставки за проследување повик"</string>
     <string name="call_forwarding_settings_with_label" msgid="8569489414006897127">"Поставки за проследување повик (<xliff:g id="SUBSCRIPTIONLABEL">%s</xliff:g>)"</string>
     <string name="labelCF" msgid="2574386948026924737">"Препраќање повик"</string>
     <string name="labelCFU" msgid="8147177368148660600">"Секогаш препраќај"</string>
@@ -116,7 +116,7 @@
     <string name="sum_cfnrc_enabled" msgid="7010898346095497421">"Препраќање на <xliff:g id="PHONENUMBER">{0}</xliff:g>"</string>
     <string name="sum_cfnrc_disabled" msgid="7222141261321276464">"Оневозможено"</string>
     <string name="disable_cfnrc_forbidden" msgid="5646361343094064333">"Вашиот оператор не поддржува оневозможување проследување повик кога вашиот телефон е недостапен."</string>
-    <string name="updating_title" msgid="6146755386174019046">"Подесувања на повик"</string>
+    <string name="updating_title" msgid="6146755386174019046">"Поставки на повик"</string>
     <string name="call_settings_admin_user_only" msgid="4526094783818216374">"Поставките за повик може да ги измени само администраторскиот корисник."</string>
     <string name="call_settings_with_label" msgid="3401177261468593519">"Поставки (<xliff:g id="SUBSCRIPTIONLABEL">%s</xliff:g>)"</string>
     <string name="error_updating_title" msgid="7970259216988931777">"Грешка со подесување повици"</string>
@@ -335,7 +335,7 @@
   </string-array>
     <string name="cdma_activate_device" msgid="3793805892364814518">"Активирај уред"</string>
     <string name="cdma_lte_data_service" msgid="4255018217292548962">"Подеси услуга на податоци"</string>
-    <string name="carrier_settings_title" msgid="9028166176523012300">"Подесувања на оператор"</string>
+    <string name="carrier_settings_title" msgid="9028166176523012300">"Поставки на оператор"</string>
     <string name="fdn" msgid="7878832555095183202">"Броеви на фиксно бирање"</string>
     <string name="fdn_with_label" msgid="187084204115493366">"Броеви за фиксно бирање (<xliff:g id="SUBSCRIPTIONLABEL">%s</xliff:g>)"</string>
     <string name="manage_fdn_list" msgid="8777755791892122369">"FDN список"</string>
diff --git a/res/values-sr/strings.xml b/res/values-sr/strings.xml
index 319660e..403f09d 100644
--- a/res/values-sr/strings.xml
+++ b/res/values-sr/strings.xml
@@ -143,7 +143,7 @@
     <string name="vm_change_failed" msgid="3352934863246208918">"Није могуће променити број говорне поште.\nКонтактирајте мобилног оператера ако се овај проблем настави."</string>
     <string name="fw_change_failed" msgid="5298103228470214665">"Није могуће променити број за преусмеравање.\nКонтактирајте мобилног оператера ако се овај проблем настави."</string>
     <string name="fw_get_in_vm_failed" msgid="8862896836093833973">"Није могуће преузети и сачувати тренутна подешавања броја за прослеђивање.\nЖелите ли да ипак пређете на новог добављача?"</string>
-    <string name="no_change" msgid="3186040086622435212">"Нису начињене промене."</string>
+    <string name="no_change" msgid="3186040086622435212">"Нису извршене никакве промене."</string>
     <string name="sum_voicemail_choose_provider" msgid="59911196126278922">"Одаберите услугу говорне поште"</string>
     <string name="voicemail_default" msgid="2001233554889016880">"Мобилни оператер"</string>
     <string name="mobile_networks" msgid="2843854043339307375">"Подешавања мобилне мреже"</string>
diff --git a/res/values/dimens.xml b/res/values/dimens.xml
index a3c62a9..886d829 100644
--- a/res/values/dimens.xml
+++ b/res/values/dimens.xml
@@ -107,4 +107,8 @@
     <dimen name="floating_action_button_width">67dp</dimen>
     <dimen name="floating_action_button_height">67dp</dimen>
     <dimen name="floating_action_button_margin_bottom">26dp</dimen>
+
+    <!-- Lock icon for preferences locked by admin -->
+    <dimen name="restricted_lock_icon_size">16dp</dimen>
+    <dimen name="restricted_lock_icon_padding">4dp</dimen>
 </resources>
diff --git a/res/xml/network_setting.xml b/res/xml/network_setting.xml
index 58c19f7..875e1f3 100644
--- a/res/xml/network_setting.xml
+++ b/res/xml/network_setting.xml
@@ -21,7 +21,7 @@
         android:title="@string/cdma_lte_data_service">
     </PreferenceScreen>
 
-    <SwitchPreference
+    <com.android.phone.RestrictedSwitchPreference
         android:key="button_roaming_key"
         android:title="@string/roaming"
         android:persistent="false"
diff --git a/src/com/android/phone/CallStateMonitor.java b/src/com/android/phone/CallStateMonitor.java
index 512c30b..027eba7 100644
--- a/src/com/android/phone/CallStateMonitor.java
+++ b/src/com/android/phone/CallStateMonitor.java
@@ -123,32 +123,4 @@
             handler.handleMessage(msg);
         }
     }
-
-    /**
-     * When radio technology changes, we need to to reregister for all the events which are
-     * all tied to the old radio.
-     */
-    public void updateAfterRadioTechnologyChange() {
-        if (DBG) Log.d(LOG_TAG, "updateCallNotifierRegistrationsAfterRadioTechnologyChange...");
-
-        // Unregister all events from the old obsolete phone
-        //callManager.unregisterForNewRingingConnection(this);
-        //callManager.unregisterForPreciseCallStateChanged(this);
-        callManager.unregisterForDisconnect(this);
-        //callManager.unregisterForUnknownConnection(this);
-        //callManager.unregisterForCallWaiting(this);
-        callManager.unregisterForDisplayInfo(this);
-        callManager.unregisterForSignalInfo(this);
-        callManager.unregisterForCdmaOtaStatusChange(this);
-        //callManager.unregisterForRingbackTone(this);
-        //callManager.unregisterForResendIncallMute(this);
-        callManager.unregisterForInCallVoicePrivacyOn(this);
-        callManager.unregisterForInCallVoicePrivacyOff(this);
-        //callManager.unregisterForPostDialCharacter(this);
-        callManager.unregisterForSuppServiceFailed(this);
-        callManager.unregisterForTtyModeReceived(this);
-
-        registerForNotifications();
-    }
-
 }
diff --git a/src/com/android/phone/MobileNetworkSettings.java b/src/com/android/phone/MobileNetworkSettings.java
index 2522611..68c6047 100644
--- a/src/com/android/phone/MobileNetworkSettings.java
+++ b/src/com/android/phone/MobileNetworkSettings.java
@@ -35,7 +35,6 @@
 import android.content.Intent;
 import android.content.IntentFilter;
 import android.content.pm.PackageManager.NameNotFoundException;
-import android.content.pm.UserInfo;
 import android.net.Uri;
 import android.os.AsyncResult;
 import android.os.Bundle;
@@ -43,7 +42,6 @@
 import android.os.Message;
 import android.os.PersistableBundle;
 import android.os.SystemProperties;
-import android.os.UserHandle;
 import android.os.UserManager;
 import android.preference.ListPreference;
 import android.preference.Preference;
@@ -111,7 +109,7 @@
     //UI objects
     private ListPreference mButtonPreferredNetworkMode;
     private ListPreference mButtonEnabledNetworks;
-    private SwitchPreference mButtonDataRoam;
+    private RestrictedSwitchPreference mButtonDataRoam;
     private SwitchPreference mButton4glte;
     private Preference mLteDataServicePref;
 
@@ -449,7 +447,7 @@
         //get UI object references
         PreferenceScreen prefSet = getPreferenceScreen();
 
-        mButtonDataRoam = (SwitchPreference) prefSet.findPreference(BUTTON_ROAMING_KEY);
+        mButtonDataRoam = (RestrictedSwitchPreference) prefSet.findPreference(BUTTON_ROAMING_KEY);
         mButtonPreferredNetworkMode = (ListPreference) prefSet.findPreference(
                 BUTTON_PREFERED_NETWORK_MODE);
         mButtonEnabledNetworks = (ListPreference) prefSet.findPreference(
@@ -743,6 +741,9 @@
                 ImsManager.isNonTtyOrTtyOnVolteEnabled(getApplicationContext()) &&
                 carrierConfig.getBoolean(CarrierConfigManager.KEY_EDITABLE_ENHANCED_4G_LTE_BOOL);
         mButtonDataRoam.setEnabled(hasActiveSubscriptions);
+        if (mButtonDataRoam.isEnabled()) {
+            mButtonDataRoam.checkRestrictionAndSetDisabled(UserManager.DISALLOW_DATA_ROAMING);
+        }
         mButtonPreferredNetworkMode.setEnabled(hasActiveSubscriptions);
         mButtonEnabledNetworks.setEnabled(hasActiveSubscriptions);
         mButton4glte.setEnabled(hasActiveSubscriptions && canChange4glte);
diff --git a/src/com/android/phone/PhoneGlobals.java b/src/com/android/phone/PhoneGlobals.java
index c6081b1..be3bcfa 100644
--- a/src/com/android/phone/PhoneGlobals.java
+++ b/src/com/android/phone/PhoneGlobals.java
@@ -751,16 +751,6 @@
         }
 
         notifier.updateCallNotifierRegistrationsAfterRadioTechnologyChange();
-        callStateMonitor.updateAfterRadioTechnologyChange();
-
-        // Update registration for ICC status after radio technology change
-        IccCard sim = phone == null ? null : phone.getIccCard();
-        if (sim != null) {
-            if (DBG) Log.d(LOG_TAG, "Update registration for ICC status...");
-
-            //Register all events new to the new active phone
-            sim.registerForNetworkLocked(mHandler, EVENT_SIM_NETWORK_LOCKED, null);
-        }
     }
 
     /**
diff --git a/src/com/android/phone/PhoneInterfaceManager.java b/src/com/android/phone/PhoneInterfaceManager.java
index b996f69..d59c726 100644
--- a/src/com/android/phone/PhoneInterfaceManager.java
+++ b/src/com/android/phone/PhoneInterfaceManager.java
@@ -37,6 +37,7 @@
 import android.preference.PreferenceManager;
 import android.provider.Settings;
 import android.telecom.PhoneAccount;
+import android.telecom.PhoneAccountHandle;
 import android.telecom.TelecomManager;
 import android.telephony.CarrierConfigManager;
 import android.telephony.CellInfo;
@@ -75,6 +76,7 @@
 import com.android.internal.telephony.uicc.UiccCard;
 import com.android.internal.telephony.uicc.UiccController;
 import com.android.internal.util.HexDump;
+import com.android.phone.settings.VoicemailNotificationSettingsUtil;
 
 import static com.android.internal.telephony.PhoneConstants.SUBSCRIPTION_KEY;
 
@@ -600,7 +602,7 @@
                     if (ar.exception == null && ar.result != null) {
                         request.result = ar.result;     // Integer
                     } else {
-                        request.result = -1;
+                        request.result = null;
                         if (ar.result == null) {
                             loge("getPreferredNetworkType: Empty response");
                         } else if (ar.exception instanceof CommandException) {
@@ -2907,4 +2909,40 @@
 
         return phone.getServiceState();
     }
+
+    /**
+     * Returns the URI for the per-account voicemail ringtone set in Phone settings.
+     *
+     * @param accountHandle The handle for the {@link PhoneAccount} for which to retrieve the
+     * voicemail ringtone.
+     * @return The URI for the ringtone to play when receiving a voicemail from a specific
+     * PhoneAccount.
+     */
+    @Override
+    public Uri getVoicemailRingtoneUri(PhoneAccountHandle accountHandle) {
+        final Phone phone = PhoneUtils.getPhoneForPhoneAccountHandle(accountHandle);
+        if (phone == null) {
+            return null;
+        }
+
+        return VoicemailNotificationSettingsUtil.getRingtoneUri(phone);
+    }
+
+    /**
+     * Returns whether vibration is set for voicemail notification in Phone settings.
+     *
+     * @param accountHandle The handle for the {@link PhoneAccount} for which to retrieve the
+     * voicemail vibration setting.
+     * @return {@code true} if the vibration is set for this PhoneAccount, {@code false} otherwise.
+     */
+    @Override
+    public boolean isVoicemailVibrationEnabled(PhoneAccountHandle accountHandle) {
+        final Phone phone = PhoneUtils.getPhoneForPhoneAccountHandle(accountHandle);
+        if (phone == null) {
+            return false;
+        }
+
+        return VoicemailNotificationSettingsUtil.isVibrationEnabled(phone);
+    }
+
 }
diff --git a/src/com/android/phone/PhoneUtils.java b/src/com/android/phone/PhoneUtils.java
index 983967c..1749df2 100644
--- a/src/com/android/phone/PhoneUtils.java
+++ b/src/com/android/phone/PhoneUtils.java
@@ -2429,15 +2429,21 @@
     }
 
     public static int getSubIdForPhoneAccountHandle(PhoneAccountHandle handle) {
-        if (handle != null && handle.getComponentName().equals(getPstnConnectionServiceName())) {
-            Phone phone = getPhoneFromIccId(handle.getId());
-            if (phone != null) {
-                return phone.getSubId();
-            }
+        Phone phone = getPhoneForPhoneAccountHandle(handle);
+        if (phone != null) {
+            return phone.getSubId();
         }
         return SubscriptionManager.INVALID_SUBSCRIPTION_ID;
     }
 
+    static Phone getPhoneForPhoneAccountHandle(PhoneAccountHandle handle) {
+        if (handle != null && handle.getComponentName().equals(getPstnConnectionServiceName())) {
+            return getPhoneFromIccId(handle.getId());
+        }
+        return null;
+    }
+
+
     /**
      * Determine if a given phone account corresponds to an active SIM
      *
diff --git a/src/com/android/phone/RestrictedSwitchPreference.java b/src/com/android/phone/RestrictedSwitchPreference.java
new file mode 100644
index 0000000..6af75b7
--- /dev/null
+++ b/src/com/android/phone/RestrictedSwitchPreference.java
@@ -0,0 +1,95 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.phone;
+
+import android.content.Context;
+import android.content.Intent;
+import android.graphics.drawable.Drawable;
+import android.os.UserManager;
+import android.preference.PreferenceScreen;
+import android.preference.SwitchPreference;
+import android.provider.Settings;
+import android.util.AttributeSet;
+import android.view.View;
+import android.widget.TextView;
+
+public class RestrictedSwitchPreference extends SwitchPreference {
+    private final Context mContext;
+    private final Drawable mRestrictedPadlock;
+    private final int mRestrictedPadlockPadding;
+    private boolean mDisabledByAdmin;
+
+    public RestrictedSwitchPreference(Context context, AttributeSet attrs,
+            int defStyleAttr, int defStyleRes) {
+        super(context, attrs, defStyleAttr, defStyleRes);
+        mContext = context;
+        mRestrictedPadlock = mContext
+                .getDrawable(R.drawable.ic_settings_lock_outline);
+        final int iconSize = mContext.getResources().getDimensionPixelSize(
+                R.dimen.restricted_lock_icon_size);
+        mRestrictedPadlock.setBounds(0, 0, iconSize, iconSize);
+        mRestrictedPadlockPadding = mContext.getResources()
+                .getDimensionPixelSize(R.dimen.restricted_lock_icon_padding);
+    }
+
+    public RestrictedSwitchPreference(Context context, AttributeSet attrs, int defStyleAttr) {
+        this(context, attrs, defStyleAttr, 0);
+    }
+
+    public RestrictedSwitchPreference(Context context, AttributeSet attrs) {
+        this(context, attrs, com.android.internal.R.attr.switchPreferenceStyle);
+    }
+
+    public RestrictedSwitchPreference(Context context) {
+        this(context, null);
+    }
+
+    @Override
+    public void onBindView(View view) {
+        super.onBindView(view);
+        final TextView titleView = (TextView) view.findViewById(com.android.internal.R.id.title);
+        if (titleView != null) {
+            if (mDisabledByAdmin) {
+                view.setEnabled(true);
+                titleView.setCompoundDrawablesRelative(null, null, mRestrictedPadlock, null);
+                titleView.setCompoundDrawablePadding(mRestrictedPadlockPadding);
+            } else {
+                titleView.setCompoundDrawablesRelative(null, null, null, null);
+            }
+        }
+    }
+
+    public void checkRestrictionAndSetDisabled(String userRestriction) {
+        final UserManager mUm = (UserManager) mContext.getSystemService(Context.USER_SERVICE);
+        if (mUm.hasUserRestriction(userRestriction)) {
+            mDisabledByAdmin = true;
+            setEnabled(false);
+        } else {
+            mDisabledByAdmin = false;
+        }
+    }
+
+    @Override
+    public void performClick(PreferenceScreen preferenceScreen) {
+        if (mDisabledByAdmin) {
+            Intent intent = new Intent(Settings.ACTION_SHOW_ADMIN_SUPPORT_DETAILS);
+            mContext.startActivity(intent);
+        } else {
+            super.performClick(preferenceScreen);
+        }
+    }
+}
diff --git a/src/com/android/phone/common/mail/store/ImapFolder.java b/src/com/android/phone/common/mail/store/ImapFolder.java
index 10f4afe..1d17ea9 100644
--- a/src/com/android/phone/common/mail/store/ImapFolder.java
+++ b/src/com/android/phone/common/mail/store/ImapFolder.java
@@ -16,17 +16,15 @@
 package com.android.phone.common.mail.store;
 
 import android.content.Context;
+import android.content.SharedPreferences;
+import android.preference.PreferenceManager;
+import android.provider.VoicemailContract;
 import android.text.TextUtils;
 import android.util.Base64DataException;
+import android.util.Log;
 
-import com.android.phone.common.mail.store.ImapStore.ImapException;
-import com.android.phone.common.mail.store.ImapStore.ImapMessage;
-import com.android.phone.common.mail.store.imap.ImapConstants;
-import com.android.phone.common.mail.store.imap.ImapElement;
-import com.android.phone.common.mail.store.imap.ImapList;
-import com.android.phone.common.mail.store.imap.ImapResponse;
-import com.android.phone.common.mail.store.imap.ImapString;
-import com.android.phone.common.mail.store.imap.ImapUtility;
+import com.android.internal.annotations.VisibleForTesting;
+import com.android.phone.common.R;
 import com.android.phone.common.mail.AuthenticationFailedException;
 import com.android.phone.common.mail.Body;
 import com.android.phone.common.mail.FetchProfile;
@@ -39,30 +37,25 @@
 import com.android.phone.common.mail.internet.MimeHeader;
 import com.android.phone.common.mail.internet.MimeMultipart;
 import com.android.phone.common.mail.internet.MimeUtility;
-import com.android.phone.common.mail.utility.CountingOutputStream;
-import com.android.phone.common.mail.utility.EOLConvertingOutputStream;
-import com.android.phone.common.mail.utils.Utility;
+import com.android.phone.common.mail.store.ImapStore.ImapException;
+import com.android.phone.common.mail.store.ImapStore.ImapMessage;
+import com.android.phone.common.mail.store.imap.ImapConstants;
+import com.android.phone.common.mail.store.imap.ImapElement;
+import com.android.phone.common.mail.store.imap.ImapList;
+import com.android.phone.common.mail.store.imap.ImapResponse;
+import com.android.phone.common.mail.store.imap.ImapString;
 import com.android.phone.common.mail.utils.LogUtils;
-import com.android.internal.annotations.VisibleForTesting;
-import com.android.phone.common.R;
+import com.android.phone.common.mail.utils.Utility;
 
-import org.apache.commons.io.IOUtils;
-
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileOutputStream;
 import java.io.IOException;
 import java.io.InputStream;
 import java.io.OutputStream;
-import java.text.SimpleDateFormat;
 import java.util.ArrayList;
-import java.util.Arrays;
 import java.util.Date;
 import java.util.HashMap;
 import java.util.LinkedHashSet;
 import java.util.List;
 import java.util.Locale;
-import java.util.TimeZone;
 
 public class ImapFolder {
     private static final String TAG = "ImapFolder";
@@ -329,7 +322,7 @@
             mConnection.sendCommand(String.format(Locale.US,
                     ImapConstants.UID_FETCH + " %s (%s)", ImapStore.joinMessageUids(messages),
                     Utility.combine(fetchFields.toArray(new String[fetchFields.size()]), ' ')
-                    ), false);
+            ), false);
             ImapResponse response;
             do {
                 response = null;
@@ -745,6 +738,44 @@
         mExists = true;
     }
 
+    public class Quota {
+
+        public final int occupied;
+        public final int total;
+
+        public Quota(int occupied, int total) {
+            this.occupied = occupied;
+            this.total = total;
+        }
+    }
+
+    public Quota getQuota() throws MessagingException {
+        try {
+            final List<ImapResponse> responses = mConnection.executeSimpleCommand(
+                    String.format(Locale.US, ImapConstants.GETQUOTAROOT + " \"%s\"", mName));
+
+            for (ImapResponse response : responses) {
+                if (!response.isDataResponse(0, ImapConstants.QUOTA)) {
+                    continue;
+                }
+                ImapList list = response.getListOrEmpty(2);
+                for (int i = 0; i < list.size(); i += 3) {
+                    if (!list.getStringOrEmpty(i).is("voice")) {
+                        continue;
+                    }
+                    return new Quota(
+                            list.getStringOrEmpty(i + 1).getNumber(-1),
+                            list.getStringOrEmpty(i + 2).getNumber(-1));
+                }
+            }
+        } catch (IOException ioe) {
+            throw ioExceptionHandler(mConnection, ioe);
+        } finally {
+            destroyResponses();
+        }
+        return null;
+    }
+
     private void checkOpen() throws MessagingException {
         if (!isOpen()) {
             throw new MessagingException("Folder " + mName + " is not open.");
diff --git a/src/com/android/phone/common/mail/store/ImapStore.java b/src/com/android/phone/common/mail/store/ImapStore.java
index 605abbb..63a5c36 100644
--- a/src/com/android/phone/common/mail/store/ImapStore.java
+++ b/src/com/android/phone/common/mail/store/ImapStore.java
@@ -19,11 +19,10 @@
 import android.content.Context;
 import android.net.Network;
 
-import com.android.phone.common.mail.internet.MimeMessage;
 import com.android.phone.common.mail.MailTransport;
 import com.android.phone.common.mail.Message;
 import com.android.phone.common.mail.MessagingException;
-import com.android.phone.common.mail.store.ImapFolder;
+import com.android.phone.common.mail.internet.MimeMessage;
 
 import java.io.IOException;
 import java.io.InputStream;
diff --git a/src/com/android/phone/common/mail/store/imap/ImapConstants.java b/src/com/android/phone/common/mail/store/imap/ImapConstants.java
index cde1616..63dda8c 100644
--- a/src/com/android/phone/common/mail/store/imap/ImapConstants.java
+++ b/src/com/android/phone/common/mail/store/imap/ImapConstants.java
@@ -97,6 +97,14 @@
     public static final String APPENDUID = "APPENDUID";
     public static final String NIL = "NIL";
 
+    /**
+     * extensions
+     */
+    public static final String GETQUOTA = "GETQUOTA";
+    public static final String GETQUOTAROOT = "GETQUOTAROOT";
+    public static final String QUOTAROOT = "QUOTAROOT";
+    public static final String QUOTA = "QUOTA";
+
     /** response codes within IMAP responses */
     public static final String EXPIRED = "EXPIRED";
     public static final String AUTHENTICATIONFAILED = "AUTHENTICATIONFAILED";
diff --git a/src/com/android/phone/common/mail/store/imap/ImapString.java b/src/com/android/phone/common/mail/store/imap/ImapString.java
index f38a993..a33ba24 100644
--- a/src/com/android/phone/common/mail/store/imap/ImapString.java
+++ b/src/com/android/phone/common/mail/store/imap/ImapString.java
@@ -107,11 +107,18 @@
     }
 
     /**
-     * @return value parsed as a number.
+     * @return value parsed as a number, or 0 if the string is not a number.
      */
     public final int getNumberOrZero() {
+        return getNumber(0);
+    }
+
+    /**
+     * @return value parsed as a number, or {@code defaultValue} if the string is not a number.
+     */
+    public final int getNumber(int defaultValue) {
         if (!isNumber()) {
-            return 0;
+            return defaultValue;
         }
         return mParsedInteger;
     }
diff --git a/src/com/android/phone/settings/VisualVoicemailSettingsUtil.java b/src/com/android/phone/settings/VisualVoicemailSettingsUtil.java
index 888a5f9..62abffd 100644
--- a/src/com/android/phone/settings/VisualVoicemailSettingsUtil.java
+++ b/src/com/android/phone/settings/VisualVoicemailSettingsUtil.java
@@ -164,7 +164,7 @@
                 NO_PRIOR_FULL_SYNC);
     }
 
-    private static String getVisualVoicemailSharedPrefsKey(String key,
+    public static String getVisualVoicemailSharedPrefsKey(String key,
             PhoneAccountHandle phoneAccount) {
         return VISUAL_VOICEMAIL_SHARED_PREFS_KEY_PREFIX + key + "_" + phoneAccount.getId();
     }
diff --git a/src/com/android/phone/vvm/omtp/imap/ImapHelper.java b/src/com/android/phone/vvm/omtp/imap/ImapHelper.java
index 5a69ed2..fd56c77 100644
--- a/src/com/android/phone/vvm/omtp/imap/ImapHelper.java
+++ b/src/com/android/phone/vvm/omtp/imap/ImapHelper.java
@@ -16,11 +16,15 @@
 package com.android.phone.vvm.omtp.imap;
 
 import android.content.Context;
+import android.content.SharedPreferences;
 import android.net.Network;
+import android.preference.PreferenceManager;
+import android.provider.VoicemailContract;
 import android.telecom.PhoneAccountHandle;
 import android.telecom.Voicemail;
 import android.telephony.TelephonyManager;
 import android.util.Base64;
+import android.util.Log;
 
 import com.android.phone.PhoneUtils;
 import com.android.phone.common.mail.Address;
@@ -63,6 +67,13 @@
     private Context mContext;
     private PhoneAccountHandle mPhoneAccount;
 
+    SharedPreferences mPrefs;
+    private static final String PREF_KEY_QUOTA_OCCUPIED = "quota_occupied_";
+    private static final String PREF_KEY_QUOTA_TOTAL = "quota_total_";
+
+    private int mQuotaOccupied;
+    private int mQuotaTotal;
+
     public ImapHelper(Context context, PhoneAccountHandle phoneAccount, Network network) {
         try {
             mContext = context;
@@ -93,6 +104,14 @@
         } catch (NumberFormatException e) {
             LogUtils.w(TAG, "Could not parse port number");
         }
+
+        mPrefs = PreferenceManager.getDefaultSharedPreferences(context);
+        mQuotaOccupied = mPrefs.getInt(getSharedPrefsKey(PREF_KEY_QUOTA_OCCUPIED),
+                VoicemailContract.Status.QUOTA_UNAVAILABLE);
+        mQuotaTotal = mPrefs.getInt(getSharedPrefsKey(PREF_KEY_QUOTA_TOTAL),
+                VoicemailContract.Status.QUOTA_UNAVAILABLE);
+
+        Log.v(TAG, "Quota:" + mQuotaOccupied + "/" + mQuotaTotal);
     }
 
     /**
@@ -165,7 +184,6 @@
                     result.add(getVoicemailFromMessageStructure(messageStructureWrapper));
                 }
             }
-
             return result;
         } catch (MessagingException e) {
             LogUtils.e(TAG, e, "Messaging Exception");
@@ -323,6 +341,43 @@
         }
     }
 
+    public void updateQuota() {
+        try {
+            mFolder = openImapFolder(ImapFolder.MODE_READ_WRITE);
+            if (mFolder == null) {
+                // This means we were unable to successfully open the folder.
+                return;
+            }
+            updateQuota(mFolder);
+        } catch (MessagingException e) {
+            LogUtils.e(TAG, e, "Messaging Exception");
+        } finally {
+            closeImapFolder();
+        }
+    }
+
+    private void updateQuota(ImapFolder folder) throws MessagingException {
+        setQuota(folder.getQuota());
+    }
+
+    private void setQuota(ImapFolder.Quota quota) {
+        if (quota == null) {
+            return;
+        }
+        if (quota.occupied == mQuotaOccupied && quota.total == mQuotaTotal) {
+            Log.v(TAG, "Quota hasn't changed");
+            return;
+        }
+        mQuotaOccupied = quota.occupied;
+        mQuotaTotal = quota.total;
+        VoicemailContract.Status
+                .setQuota(mContext, mPhoneAccount, mQuotaOccupied, mQuotaTotal);
+        mPrefs.edit()
+                .putInt(getSharedPrefsKey(PREF_KEY_QUOTA_OCCUPIED), mQuotaOccupied)
+                .putInt(getSharedPrefsKey(PREF_KEY_QUOTA_TOTAL), mQuotaTotal)
+                .apply();
+        Log.v(TAG, "Quota changed to " + mQuotaOccupied + "/" + mQuotaTotal);
+    }
     /**
      * A wrapper to hold a message with its header details and the structure for transcriptions
      * (so they can be fetched in the future).
@@ -511,4 +566,8 @@
             IoUtils.closeQuietly(out);
         }
     }
+
+    private String getSharedPrefsKey(String key) {
+        return VisualVoicemailSettingsUtil.getVisualVoicemailSharedPrefsKey(key, mPhoneAccount);
+    }
 }
\ No newline at end of file
diff --git a/src/com/android/phone/vvm/omtp/sync/OmtpVvmSyncService.java b/src/com/android/phone/vvm/omtp/sync/OmtpVvmSyncService.java
index c2e0687..b3659ae 100644
--- a/src/com/android/phone/vvm/omtp/sync/OmtpVvmSyncService.java
+++ b/src/com/android/phone/vvm/omtp/sync/OmtpVvmSyncService.java
@@ -146,7 +146,6 @@
             Log.d(TAG, "onHandleIntent: could not handle null intent");
             return;
         }
-
         String action = intent.getAction();
         PhoneAccountHandle phoneAccount = intent.getParcelableExtra(EXTRA_PHONE_ACCOUNT);
         LocalLogHelper.log(TAG, "Sync requested: " + action +
@@ -212,6 +211,7 @@
                 } else {
                     success = syncOne(imapHelper, voicemail);
                 }
+                imapHelper.updateQuota();
 
                 // Need to check again for whether visual voicemail is enabled because it could have
                 // been disabled while waiting for the response from the network.
diff --git a/src/com/android/services/telephony/ImsConference.java b/src/com/android/services/telephony/ImsConference.java
index dcc71a0..d1f4cc6 100644
--- a/src/com/android/services/telephony/ImsConference.java
+++ b/src/com/android/services/telephony/ImsConference.java
@@ -475,7 +475,8 @@
         com.android.internal.telephony.Connection originalConnection =
                 mConferenceHost.getOriginalConnection();
 
-        return originalConnection.isMultiparty() && originalConnection.isConferenceHost();
+        return originalConnection != null && originalConnection.isMultiparty() &&
+                originalConnection.isConferenceHost();
     }
 
     /**
@@ -763,7 +764,8 @@
         com.android.internal.telephony.Connection originalConnection =
                 mConferenceHost.getOriginalConnection();
 
-        if (originalConnection.getPhoneType() != PhoneConstants.PHONE_TYPE_IMS) {
+        if (originalConnection != null &&
+                originalConnection.getPhoneType() != PhoneConstants.PHONE_TYPE_IMS) {
             if (Log.VERBOSE) {
                 Log.v(this,
                         "Original connection for conference host is no longer an IMS connection; " +
diff --git a/src/com/android/services/telephony/ImsConferenceController.java b/src/com/android/services/telephony/ImsConferenceController.java
index 0c25fbb..0f9ae5d 100644
--- a/src/com/android/services/telephony/ImsConferenceController.java
+++ b/src/com/android/services/telephony/ImsConferenceController.java
@@ -274,7 +274,8 @@
         com.android.internal.telephony.Connection originalConnection =
                 telephonyConnection.getOriginalConnection();
 
-        return originalConnection.isMultiparty() && originalConnection.isMemberOfPeerConference();
+        return originalConnection != null && originalConnection.isMultiparty() &&
+                originalConnection.isMemberOfPeerConference();
     }
 
     /**
diff --git a/src/com/android/services/telephony/TelecomAccountRegistry.java b/src/com/android/services/telephony/TelecomAccountRegistry.java
index f070572..e8a93c6 100644
--- a/src/com/android/services/telephony/TelecomAccountRegistry.java
+++ b/src/com/android/services/telephony/TelecomAccountRegistry.java
@@ -27,6 +27,7 @@
 import android.net.Uri;
 import android.os.Bundle;
 import android.os.PersistableBundle;
+import android.os.ServiceManager;
 import android.telecom.PhoneAccount;
 import android.telecom.PhoneAccountHandle;
 import android.telecom.TelecomManager;
@@ -39,6 +40,7 @@
 import android.telephony.TelephonyManager;
 import android.text.TextUtils;
 
+import com.android.internal.telephony.IPhoneSubInfo;
 import com.android.internal.telephony.Phone;
 import com.android.internal.telephony.PhoneFactory;
 import com.android.phone.PhoneGlobals;
@@ -104,8 +106,7 @@
             if (line1Number == null) {
                 line1Number = "";
             }
-            String subNumber = mPhone.getPhoneSubInfo().getLine1Number(
-                    mPhone.getContext().getOpPackageName());
+            String subNumber = mPhone.getLine1Number();
             if (subNumber == null) {
                 subNumber = "";
             }
diff --git a/src/com/android/services/telephony/TelephonyConnection.java b/src/com/android/services/telephony/TelephonyConnection.java
index d6ef942..339db6d 100644
--- a/src/com/android/services/telephony/TelephonyConnection.java
+++ b/src/com/android/services/telephony/TelephonyConnection.java
@@ -1211,7 +1211,9 @@
      *     otherwise.
      */
     protected boolean isImsConnection() {
-        return getOriginalConnection().getPhoneType() == PhoneConstants.PHONE_TYPE_IMS;
+        com.android.internal.telephony.Connection originalConnection = getOriginalConnection();
+        return originalConnection != null &&
+                originalConnection.getPhoneType() == PhoneConstants.PHONE_TYPE_IMS;
     }
 
     /**