Merge "add locallog for carrier config loader"
diff --git a/res/xml/phone_account_settings.xml b/res/xml/phone_account_settings.xml
index d230328..a243a65 100644
--- a/res/xml/phone_account_settings.xml
+++ b/res/xml/phone_account_settings.xml
@@ -21,19 +21,11 @@
         android:key="phone_accounts_accounts_list_category_key"
         android:title="@string/phone_accounts_settings_header">
 
-        <com.android.phone.settings.AccountSelectionPreference
-            android:key="default_outgoing_account"
-            android:title="@string/phone_accounts_make_calls_with"
-            android:defaultValue=""
-            android:persistent="false"
-            android:order="1" />
-
         <PreferenceScreen
             android:key="phone_accounts_all_calling_accounts"
             android:title="@string/phone_accounts_all_calling_accounts"
             android:summary="@string/phone_accounts_all_calling_accounts_summary"
-            android:persistent="false"
-            android:order="1000" >
+            android:persistent="false" >
 
             <intent android:action="android.intent.action.MAIN"
                 android:targetPackage="com.android.server.telecom"
@@ -43,6 +35,27 @@
     </PreferenceCategory>
 
     <PreferenceCategory
+        android:key="make_and_receive_calls_settings_category_key"
+        android:title="@string/make_and_receive_calls"
+        android:persistent="false">
+
+        <com.android.phone.settings.AccountSelectionPreference
+            android:key="default_outgoing_account"
+            android:title="@string/phone_accounts_make_calls_with"
+            android:defaultValue=""
+            android:persistent="false"/>
+
+        <PreferenceScreen
+            android:key="smart_forwarding_configuration_key"
+            android:title="@string/smart_forwarding_settings_menu"
+            android:summary="@string/smart_forwarding_settings_menu_summary"
+            android:persistent="false">
+
+        </PreferenceScreen>
+
+    </PreferenceCategory>
+
+    <PreferenceCategory
         android:key="phone_accounts_sip_settings_category_key"
         android:title="@string/sip_settings"
         android:persistent="false">
diff --git a/src/com/android/phone/PhoneGlobals.java b/src/com/android/phone/PhoneGlobals.java
index 94cd0f6..fed41b0 100644
--- a/src/com/android/phone/PhoneGlobals.java
+++ b/src/com/android/phone/PhoneGlobals.java
@@ -226,7 +226,8 @@
                     // Marks the event where the SIM goes into ready state.
                     // Right now, this is only used for the PUK-unlocking
                     // process.
-                    if (msg.obj.equals(IccCardConstants.INTENT_VALUE_ICC_READY)) {
+                    if (msg.obj.equals(IccCardConstants.INTENT_VALUE_ICC_READY)
+                            || msg.obj.equals(IccCardConstants.INTENT_VALUE_ICC_LOADED)) {
                         // when the right event is triggered and there
                         // are UI objects in the foreground, we close
                         // them to display the lock panel.
diff --git a/src/com/android/phone/PhoneInterfaceManager.java b/src/com/android/phone/PhoneInterfaceManager.java
index ab243f6..f6f5d93 100755
--- a/src/com/android/phone/PhoneInterfaceManager.java
+++ b/src/com/android/phone/PhoneInterfaceManager.java
@@ -6746,6 +6746,27 @@
         }
     }
 
+    /**
+     * Whether a modem stack is enabled or not.
+     */
+    @Override
+    public boolean isModemEnabledForSlot(int slotIndex, String callingPackage) {
+        Phone phone = PhoneFactory.getPhone(slotIndex);
+        if (phone == null) return false;
+
+        if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
+                mApp, phone.getSubId(), callingPackage, "isModemEnabledForSlot")) {
+            throw new SecurityException("Requires READ_PHONE_STATE permission.");
+        }
+
+        final long identity = Binder.clearCallingIdentity();
+        try {
+            return PhoneConfigurationManager.getInstance().getPhoneStatus(phone);
+        } finally {
+            Binder.restoreCallingIdentity(identity);
+        }
+    }
+
     @Override
     public void setMultiSimCarrierRestriction(boolean isMultiSimCarrierRestricted) {
         enforceModifyPermission();
diff --git a/src/com/android/phone/settings/PhoneAccountSettingsFragment.java b/src/com/android/phone/settings/PhoneAccountSettingsFragment.java
index ca45b31..0846be1 100644
--- a/src/com/android/phone/settings/PhoneAccountSettingsFragment.java
+++ b/src/com/android/phone/settings/PhoneAccountSettingsFragment.java
@@ -1,5 +1,6 @@
 package com.android.phone.settings;
 
+import android.content.ComponentName;
 import android.content.Context;
 import android.content.Intent;
 import android.content.pm.PackageManager;
@@ -7,6 +8,7 @@
 import android.graphics.drawable.Icon;
 import android.net.sip.SipManager;
 import android.os.Bundle;
+import android.os.PersistableBundle;
 import android.os.UserManager;
 import android.preference.ListPreference;
 import android.preference.Preference;
@@ -16,6 +18,7 @@
 import android.telecom.PhoneAccount;
 import android.telecom.PhoneAccountHandle;
 import android.telecom.TelecomManager;
+import android.telephony.CarrierConfigManager;
 import android.telephony.SubscriptionInfo;
 import android.telephony.SubscriptionManager;
 import android.telephony.TelephonyManager;
@@ -35,6 +38,7 @@
 import java.util.Comparator;
 import java.util.Iterator;
 import java.util.List;
+import java.util.stream.Collectors;
 
 public class PhoneAccountSettingsFragment extends PreferenceFragment
         implements Preference.OnPreferenceChangeListener,
@@ -43,7 +47,6 @@
     private static final String ACCOUNTS_LIST_CATEGORY_KEY =
             "phone_accounts_accounts_list_category_key";
 
-    private static final String DEFAULT_OUTGOING_ACCOUNT_KEY = "default_outgoing_account";
     private static final String ALL_CALLING_ACCOUNTS_KEY = "phone_accounts_all_calling_accounts";
 
     private static final String SIP_SETTINGS_CATEGORY_PREF_KEY =
@@ -51,6 +54,12 @@
     private static final String USE_SIP_PREF_KEY = "use_sip_calling_options_key";
     private static final String SIP_RECEIVE_CALLS_PREF_KEY = "sip_receive_calls_key";
 
+    private static final String MAKE_AND_RECEIVE_CALLS_CATEGORY_KEY =
+            "make_and_receive_calls_settings_category_key";
+    private static final String DEFAULT_OUTGOING_ACCOUNT_KEY = "default_outgoing_account";
+    private static final String SMART_FORWARDING_CONFIGURATION_PREF_KEY =
+            "smart_forwarding_configuration_key";
+
     private static final String LEGACY_ACTION_CONFIGURE_PHONE_ACCOUNT =
             "android.telecom.action.CONNECTION_SERVICE_CONFIGURE";
 
@@ -73,6 +82,9 @@
     private AccountSelectionPreference mDefaultOutgoingAccount;
     private Preference mAllCallingAccounts;
 
+    private PreferenceCategory mMakeAndReceiveCallsCategory;
+    private boolean mMakeAndReceiveCallsCategoryPresent;
+
     private ListPreference mUseSipCalling;
     private SwitchPreference mSipReceiveCallsPreference;
     private SipPreferences mSipPreferences;
@@ -136,7 +148,12 @@
                 getPreferenceScreen().findPreference(DEFAULT_OUTGOING_ACCOUNT_KEY);
         mAllCallingAccounts = getPreferenceScreen().findPreference(ALL_CALLING_ACCOUNTS_KEY);
 
+        mMakeAndReceiveCallsCategory = (PreferenceCategory) getPreferenceScreen().findPreference(
+                MAKE_AND_RECEIVE_CALLS_CATEGORY_KEY);
+        mMakeAndReceiveCallsCategoryPresent = false;
+
         updateAccounts();
+        updateMakeCallsOptions();
 
         if (isPrimaryUser() && SipUtil.isVoipSupported(getActivity())) {
             mSipPreferences = new SipPreferences(getActivity());
@@ -400,13 +417,14 @@
                 // Initialize the account list with the set of enabled & SIM accounts.
                 initAccountList(enabledAccounts);
 
-                mDefaultOutgoingAccount.setListener(this);
                 // Only show the 'Make Calls With..." option if there are multiple accounts.
                 if (enabledAccounts.size() > 1) {
-                    mAccountList.addPreference(mDefaultOutgoingAccount);
+                    mMakeAndReceiveCallsCategory.addPreference(mDefaultOutgoingAccount);
+                    mMakeAndReceiveCallsCategoryPresent = true;
+                    mDefaultOutgoingAccount.setListener(this);
                     updateDefaultOutgoingAccountsModel();
                 } else {
-                    mAccountList.removePreference(mDefaultOutgoingAccount);
+                    mMakeAndReceiveCallsCategory.removePreference(mDefaultOutgoingAccount);
                 }
 
                 // If there are no third party (nonSim) accounts,
@@ -503,4 +521,79 @@
                 .getSystemService(Context.USER_SERVICE);
         return userManager.isPrimaryUser();
     }
+
+    private void updateMakeCallsOptions() {
+        if (mMakeAndReceiveCallsCategory == null) {
+            return;
+        }
+
+        Intent smartForwardingUiIntent = getLaunchSmartForwardingMenuIntent();
+        if (smartForwardingUiIntent != null) {
+            mMakeAndReceiveCallsCategory.findPreference(SMART_FORWARDING_CONFIGURATION_PREF_KEY)
+                    .setIntent(smartForwardingUiIntent);
+            mMakeAndReceiveCallsCategoryPresent = true;
+        } else {
+            mMakeAndReceiveCallsCategory.removePreference(
+                    getPreferenceScreen().findPreference(SMART_FORWARDING_CONFIGURATION_PREF_KEY));
+        }
+
+        if (!mMakeAndReceiveCallsCategoryPresent) {
+            getPreferenceScreen().removePreference(mMakeAndReceiveCallsCategory);
+        }
+    }
+
+    /**
+     * @return Smart forwarding configuration UI Intent when supported
+     */
+    private Intent getLaunchSmartForwardingMenuIntent() {
+        if (mTelephonyManager.getPhoneCount() <= 1) {
+            return null;
+        }
+
+        final CarrierConfigManager configManager = (CarrierConfigManager)
+                getActivity().getSystemService(Context.CARRIER_CONFIG_SERVICE);
+        if (configManager == null) {
+            return null;
+        }
+
+        List<SubscriptionInfo> subscriptions =
+                mSubscriptionManager.getActiveSubscriptionInfoList();
+        if ((subscriptions == null) || (subscriptions.size() <= 1)) {
+            return null;
+        }
+
+        List<String> componentNames = subscriptions
+                .stream()
+                .map(subInfo -> configManager.getConfigForSubId(subInfo.getSubscriptionId()))
+                .filter(bundle -> (bundle != null))
+                .map(bundle -> bundle.getString(
+                        CarrierConfigManager.KEY_SMART_FORWARDING_CONFIG_COMPONENT_NAME_STRING))
+                .filter(componentName -> !TextUtils.isEmpty(componentName))
+                .collect(Collectors.toList());
+
+        String componentNameOfMenu = null;
+        for (String componentName : componentNames) {
+            if (componentNameOfMenu == null) {
+                componentNameOfMenu = componentName;
+            }
+            else if (!componentNameOfMenu.equals(componentName)) {
+                Log.w(LOG_TAG, "ignore smart forward component: " + componentName);
+            }
+        }
+
+        if (TextUtils.isEmpty(componentNameOfMenu)) {
+            return null;
+        }
+
+        Intent intent = new Intent(Intent.ACTION_MAIN);
+        intent.setComponent(ComponentName.unflattenFromString(componentNameOfMenu));
+
+        PackageManager pm = getActivity().getPackageManager();
+        List<ResolveInfo> resolutions = pm.queryIntentActivities(intent, 0);
+        if (resolutions.size() == 0) {
+            intent = null;  // set no intent if no package can handle it.
+        }
+
+        return intent;
+    }
 }