Snap for 4818534 from c271f204a0bbf3631ea72f60f2313ab31d47972d to pi-release

Change-Id: Iba77df50d2a7607303bd57541e1cf84d85505312
diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index 1757203..30760dc 100644
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -100,6 +100,7 @@
          So, declare this permission here for backwards compatibility so the phone process can send
          the broadcasts to those same receivers. -->
     <uses-permission android:name="android.permission.CONTROL_INCALL_EXPERIENCE" />
+    <uses-permission android:name="android.permission.DOWNLOAD_WITHOUT_NOTIFICATION" />
     <uses-permission android:name="android.permission.WRITE_SETTINGS" />
     <uses-permission android:name="android.permission.WRITE_SECURE_SETTINGS" />
     <uses-permission android:name="android.permission.READ_CONTACTS" />
diff --git a/src/com/android/phone/CarrierConfigLoader.java b/src/com/android/phone/CarrierConfigLoader.java
index d482811..0424a03 100644
--- a/src/com/android/phone/CarrierConfigLoader.java
+++ b/src/com/android/phone/CarrierConfigLoader.java
@@ -399,7 +399,7 @@
                                     PersistableBundle config =
                                             resultData.getParcelable(KEY_CONFIG_BUNDLE);
                                     saveConfigToXml(
-                                            mPlatformCarrierConfigPackage, iccid, config);
+                                            getCarrierPackageForPhoneId(phoneId), iccid, config);
                                     mConfigFromCarrierApp[phoneId] = config;
                                     sendMessage(
                                             obtainMessage(
diff --git a/src/com/android/phone/CellInfoUtil.java b/src/com/android/phone/CellInfoUtil.java
index c0409d8..2c5f2a8 100644
--- a/src/com/android/phone/CellInfoUtil.java
+++ b/src/com/android/phone/CellInfoUtil.java
@@ -34,6 +34,8 @@
 
 import com.android.internal.telephony.OperatorInfo;
 
+import java.util.List;
+
 /**
  * Add static Utility functions to get information from the CellInfo object.
  * TODO: Modify {@link CellInfo} for simplify those functions
@@ -166,4 +168,10 @@
         }
         return oi;
     }
+
+    /** Checks whether the network operator is forbidden. */
+    public static boolean isForbidden(CellInfo cellInfo, List<String> forbiddenPlmns) {
+        String plmn = CellInfoUtil.getOperatorInfoFromCellInfo(cellInfo).getOperatorNumeric();
+        return forbiddenPlmns != null && forbiddenPlmns.contains(plmn);
+    }
 }
diff --git a/src/com/android/phone/MobileNetworkSettings.java b/src/com/android/phone/MobileNetworkSettings.java
index 691d9ff..66c5650 100644
--- a/src/com/android/phone/MobileNetworkSettings.java
+++ b/src/com/android/phone/MobileNetworkSettings.java
@@ -1011,8 +1011,7 @@
                 // in case it is currently something else. That is possible if user
                 // changed the setting while roaming and is now back to home network.
                 settingsNetworkMode = preferredNetworkMode;
-            } else if (carrierConfig.getBoolean(
-                    CarrierConfigManager.KEY_WORLD_PHONE_BOOL) == true) {
+            } else if (isWorldMode()) {
                 prefSet.removePreference(mButtonEnabledNetworks);
                 // set the listener for the mButtonPreferredNetworkMode list preference so we can issue
                 // change Preferred Network Mode.
@@ -1898,6 +1897,7 @@
             return super.onOptionsItemSelected(item);
         }
 
+        // TODO: b/80541766 this should use the carrier config, not the resource overlay
         private boolean isWorldMode() {
             boolean worldModeOn = false;
             final String configString = getResources().getString(R.string.config_world_mode);
diff --git a/src/com/android/phone/NetworkOperatorPreference.java b/src/com/android/phone/NetworkOperatorPreference.java
index f29c038..85adf16 100644
--- a/src/com/android/phone/NetworkOperatorPreference.java
+++ b/src/com/android/phone/NetworkOperatorPreference.java
@@ -30,25 +30,30 @@
 
 import com.android.settingslib.graph.SignalDrawable;
 
+import java.util.List;
+
 /**
  * A Preference represents a network operator in the NetworkSelectSetting fragment.
  */
 public class NetworkOperatorPreference extends Preference {
 
     private static final String TAG = "NetworkOperatorPref";
-    private static final boolean DBG = true;
+    private static final boolean DBG = false;
     // number of signal strength level
     public static final int NUMBER_OF_LEVELS = SignalStrength.NUM_SIGNAL_STRENGTH_BINS;
     private CellInfo mCellInfo;
+    private List<String> mForbiddenPlmns;
     private int mLevel = -1;
 
     // The following constants are used to draw signal icon.
     private static final Drawable EMPTY_DRAWABLE = new ColorDrawable(Color.TRANSPARENT);
     private static final int NO_CELL_DATA_CONNECTED_ICON = 0;
 
-    public NetworkOperatorPreference(CellInfo cellinfo, Context context) {
+    public NetworkOperatorPreference(
+            CellInfo cellinfo, Context context, List<String> forbiddenPlmns) {
         super(context);
         mCellInfo = cellinfo;
+        mForbiddenPlmns = forbiddenPlmns;
         refresh();
     }
 
@@ -61,7 +66,11 @@
      */
     public void refresh() {
         if (DBG) Log.d(TAG, "refresh the network: " + CellInfoUtil.getNetworkTitle(mCellInfo));
-        setTitle(CellInfoUtil.getNetworkTitle(mCellInfo));
+        String networkTitle = CellInfoUtil.getNetworkTitle(mCellInfo);
+        if (CellInfoUtil.isForbidden(mCellInfo, mForbiddenPlmns)) {
+            networkTitle += " " + getContext().getResources().getString(R.string.forbidden_network);
+        }
+        setTitle(networkTitle);
         int level = CellInfoUtil.getLevel(mCellInfo);
         if (DBG) Log.d(TAG, "refresh level: " + String.valueOf(level));
         if (mLevel != level) {
diff --git a/src/com/android/phone/NetworkSelectListPreference.java b/src/com/android/phone/NetworkSelectListPreference.java
index 199942a..71a9dab 100644
--- a/src/com/android/phone/NetworkSelectListPreference.java
+++ b/src/com/android/phone/NetworkSelectListPreference.java
@@ -20,6 +20,7 @@
 import android.content.Context;
 import android.content.DialogInterface;
 import android.os.AsyncResult;
+import android.os.AsyncTask;
 import android.os.Handler;
 import android.os.Message;
 import android.os.Parcel;
@@ -52,6 +53,7 @@
 import com.android.internal.telephony.PhoneFactory;
 
 import java.util.ArrayList;
+import java.util.Arrays;
 import java.util.List;
 
 
@@ -83,6 +85,7 @@
     private int mSubId;
     private NetworkOperators mNetworkOperators;
     private boolean mNeedScanAgain;
+    private List<String> mForbiddenPlmns;
 
     private ProgressDialog mProgressDialog;
     public NetworkSelectListPreference(Context context, AttributeSet attrs) {
@@ -96,8 +99,21 @@
 
     @Override
     protected void onClick() {
-        // Scan the network with setting the isIncrementalResult as true via TelephonyManager first.
-        loadNetworksList(true);
+        showProgressDialog(DIALOG_NETWORK_LIST_LOAD);
+        TelephonyManager telephonyManager = (TelephonyManager)
+                getContext().getSystemService(Context.TELEPHONY_SERVICE);
+        new AsyncTask<Void, Void, List<String>>() {
+            @Override
+            protected List<String> doInBackground(Void... voids) {
+                return Arrays.asList(telephonyManager.getForbiddenPlmns());
+            }
+
+            @Override
+            protected void onPostExecute(List<String> result) {
+                mForbiddenPlmns = result;
+                loadNetworksList(true);
+            }
+        }.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
     }
 
     private final Handler mHandler = new Handler() {
@@ -179,6 +195,10 @@
                         if (DBG) {
                             logd("Modem does not support: try to scan network again via Phone");
                         }
+                        if (!mNeedScanAgain) {
+                            // Avoid blinking while showing the dialog again.
+                            showProgressDialog(DIALOG_NETWORK_LIST_LOAD);
+                        }
                         loadNetworksList(false);
                     } else {
                         try {
@@ -224,7 +244,7 @@
 
         /** Returns the scan results to the user, this callback will be called at lease one time. */
         public void onResults(List<CellInfo> results) {
-            if (DBG) logd("get scan results.");
+            if (DBG) logd("get scan results: " + results.toString());
             Message msg = mHandler.obtainMessage(EVENT_NETWORK_SCAN_RESULTS, results);
             msg.sendToTarget();
         }
@@ -360,12 +380,6 @@
 
     private void loadNetworksList(boolean isIncrementalResult) {
         if (DBG) logd("load networks list...");
-
-        if (!mNeedScanAgain) {
-            // Avoid blinking while showing the dialog again.
-            showProgressDialog(DIALOG_NETWORK_LIST_LOAD);
-        }
-
         try {
             if (mNetworkQueryService != null) {
                 mNetworkQueryService.startNetworkQuery(mCallback, mPhoneId, isIncrementalResult);
@@ -405,6 +419,10 @@
                 // Display each operator name only once.
                 String networkTitle = getNetworkTitle(cellInfo);
                 if (!networkEntriesList.contains(networkTitle)) {
+                    if (CellInfoUtil.isForbidden(cellInfo, mForbiddenPlmns)) {
+                        networkTitle += " "
+                                + getContext().getResources().getString(R.string.forbidden_network);
+                    }
                     networkEntriesList.add(networkTitle);
                     networkEntryValuesList.add(getOperatorNumeric(cellInfo));
                 }
diff --git a/src/com/android/phone/NetworkSelectSetting.java b/src/com/android/phone/NetworkSelectSetting.java
index efa8684..71162bb 100644
--- a/src/com/android/phone/NetworkSelectSetting.java
+++ b/src/com/android/phone/NetworkSelectSetting.java
@@ -22,6 +22,7 @@
 import android.content.Intent;
 import android.content.ServiceConnection;
 import android.os.AsyncResult;
+import android.os.AsyncTask;
 import android.os.Bundle;
 import android.os.Handler;
 import android.os.IBinder;
@@ -50,6 +51,7 @@
 import com.android.internal.telephony.PhoneFactory;
 
 import java.util.ArrayList;
+import java.util.Arrays;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
@@ -60,7 +62,7 @@
 public class NetworkSelectSetting extends PreferenceFragment {
 
     private static final String TAG = "NetworkSelectSetting";
-    private static final boolean DBG = false;
+    private static final boolean DBG = true;
 
     private static final int EVENT_NETWORK_SELECTION_DONE = 1;
     private static final int EVENT_NETWORK_SCAN_RESULTS = 2;
@@ -84,6 +86,7 @@
     private NetworkOperatorPreference mSelectedNetworkOperatorPreference;
     private TelephonyManager mTelephonyManager;
     private NetworkOperators mNetworkOperators;
+    private List<String> mForbiddenPlmns;
 
     private final Runnable mUpdateNetworkOperatorsRunnable = () -> {
         updateNetworkOperatorsPreferenceCategory();
@@ -103,7 +106,7 @@
 
     @Override
     public void onCreate(Bundle icicle) {
-        logd("onCreate");
+        if (DBG) logd("onCreate");
         super.onCreate(icicle);
 
         mPhoneId = getArguments().getInt(NetworkSelectSettingActivity.KEY_PHONE_ID);
@@ -123,7 +126,7 @@
 
     @Override
     public void onViewCreated(View view, Bundle savedInstanceState) {
-        logd("onViewCreated");
+        if (DBG) logd("onViewCreated");
         super.onViewCreated(view, savedInstanceState);
 
         if (getListView() != null) {
@@ -154,9 +157,18 @@
     public void onStart() {
         if (DBG) logd("onStart");
         super.onStart();
+        new AsyncTask<Void, Void, List<String>>() {
+            @Override
+            protected List<String> doInBackground(Void... voids) {
+                return Arrays.asList(mTelephonyManager.getForbiddenPlmns());
+            }
 
-        // Bind the NetworkQueryService
-        bindNetworkQueryService();
+            @Override
+            protected void onPostExecute(List<String> result) {
+                mForbiddenPlmns = result;
+                bindNetworkQueryService();
+            }
+        }.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
     }
 
     /**
@@ -382,8 +394,8 @@
         configConnectedNetworkOperatorsPreferenceCategory();
         for (int index = 0; index < mCellInfoList.size(); index++) {
             if (!mCellInfoList.get(index).isRegistered()) {
-                NetworkOperatorPreference pref =
-                        new NetworkOperatorPreference(mCellInfoList.get(index), getContext());
+                NetworkOperatorPreference pref = new NetworkOperatorPreference(
+                        mCellInfoList.get(index), getContext(), mForbiddenPlmns);
                 pref.setKey(CellInfoUtil.getNetworkTitle(mCellInfoList.get(index)));
                 pref.setOrder(index);
                 mNetworkOperatorsPreferences.addPreference(pref);
@@ -422,7 +434,7 @@
             if (cellInfo != null) {
                 if (DBG) logd("Currently registered cell: " + cellInfo.toString());
                 NetworkOperatorPreference pref =
-                        new NetworkOperatorPreference(cellInfo, getContext());
+                        new NetworkOperatorPreference(cellInfo, getContext(), mForbiddenPlmns);
                 pref.setTitle(mTelephonyManager.getNetworkOperatorName());
                 pref.setSummary(R.string.network_connected);
                 // Update the signal strength icon, since the default signalStrength value would be
@@ -503,7 +515,7 @@
         // Remove the current ConnectedNetworkOperatorsPreference
         removeConnectedNetworkOperatorPreference();
         final NetworkOperatorPreference pref =
-                new NetworkOperatorPreference(cellInfo, getContext());
+                new NetworkOperatorPreference(cellInfo, getContext(), mForbiddenPlmns);
         pref.setSummary(R.string.network_connected);
         mConnectedNetworkOperatorsPreference.addPreference(pref);
         PreferenceScreen preferenceScreen = getPreferenceScreen();
diff --git a/src/com/android/services/telephony/TelephonyConnection.java b/src/com/android/services/telephony/TelephonyConnection.java
index e80a06e..d6fb3ad 100644
--- a/src/com/android/services/telephony/TelephonyConnection.java
+++ b/src/com/android/services/telephony/TelephonyConnection.java
@@ -838,7 +838,11 @@
     public void onStartRtt(RttTextStream textStream) {
         if (isImsConnection()) {
             ImsPhoneConnection originalConnection = (ImsPhoneConnection) mOriginalConnection;
-            originalConnection.sendRttModifyRequest(textStream);
+            if (originalConnection.isRttEnabledForCall()) {
+                originalConnection.setCurrentRttTextStream(textStream);
+            } else {
+                originalConnection.sendRttModifyRequest(textStream);
+            }
         } else {
             Log.w(this, "onStartRtt - not in IMS, so RTT cannot be enabled.");
         }
diff --git a/testapps/ImsTestService/src/com/android/phone/testapps/imstestapp/ImsCallingActivity.java b/testapps/ImsTestService/src/com/android/phone/testapps/imstestapp/ImsCallingActivity.java
index 48944e4..58e08cc 100644
--- a/testapps/ImsTestService/src/com/android/phone/testapps/imstestapp/ImsCallingActivity.java
+++ b/testapps/ImsTestService/src/com/android/phone/testapps/imstestapp/ImsCallingActivity.java
@@ -87,7 +87,6 @@
         boolean isVoiceAvail = mCapVoiceAvailBox.isChecked();
         boolean isVideoAvail = mCapVideoAvailBox.isChecked();
         boolean isUtAvail = mCapUtAvailBox.isChecked();
-        // Not used yet
         boolean isSmsAvail = mCapSmsAvailBox.isChecked();
 
         MmTelFeature.MmTelCapabilities capabilities = new MmTelFeature.MmTelCapabilities();
@@ -100,6 +99,9 @@
         if (isUtAvail) {
             capabilities.addCapabilities(MmTelFeature.MmTelCapabilities.CAPABILITY_TYPE_UT);
         }
+        if (isSmsAvail) {
+            capabilities.addCapabilities(MmTelFeature.MmTelCapabilities.CAPABILITY_TYPE_SMS);
+        }
         TestMmTelFeatureImpl.getInstance().sendCapabilitiesUpdate(capabilities);
     }
 
diff --git a/testapps/ImsTestService/src/com/android/phone/testapps/imstestapp/TestImsSmsImpl.java b/testapps/ImsTestService/src/com/android/phone/testapps/imstestapp/TestImsSmsImpl.java
new file mode 100644
index 0000000..9d95a2e
--- /dev/null
+++ b/testapps/ImsTestService/src/com/android/phone/testapps/imstestapp/TestImsSmsImpl.java
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2018 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.testapps.imstestapp;
+
+import android.telephony.SmsManager;
+import android.telephony.SmsMessage;
+import android.telephony.ims.stub.ImsSmsImplBase;
+
+public class TestImsSmsImpl extends ImsSmsImplBase {
+
+    @Override
+    public void sendSms(int token, int messageRef, String format, String smsc, boolean isRetry,
+            byte[] pdu) {
+        // At this point, we will always fallback to CS if the phone tries to send an SMS with the
+        // test app. Will expand in the future to include UI options for more testing.
+        onSendSmsResult(token, messageRef, SEND_STATUS_ERROR_FALLBACK,
+                SmsManager.RESULT_ERROR_NO_SERVICE);
+    }
+
+    @Override
+    public void acknowledgeSms(int token, int messageRef, int result) {
+        super.acknowledgeSms(token, messageRef, result);
+    }
+
+    @Override
+    public void acknowledgeSmsReport(int token, int messageRef, int result) {
+        super.acknowledgeSmsReport(token, messageRef, result);
+    }
+
+    @Override
+    public String getSmsFormat() {
+        return SmsMessage.FORMAT_3GPP;
+    }
+}
diff --git a/testapps/ImsTestService/src/com/android/phone/testapps/imstestapp/TestMmTelFeatureImpl.java b/testapps/ImsTestService/src/com/android/phone/testapps/imstestapp/TestMmTelFeatureImpl.java
index 2a0463d..02e7a7b 100644
--- a/testapps/ImsTestService/src/com/android/phone/testapps/imstestapp/TestMmTelFeatureImpl.java
+++ b/testapps/ImsTestService/src/com/android/phone/testapps/imstestapp/TestMmTelFeatureImpl.java
@@ -19,6 +19,7 @@
 import android.telephony.ims.feature.CapabilityChangeRequest;
 import android.telephony.ims.feature.MmTelFeature;
 import android.telephony.ims.stub.ImsRegistrationImplBase;
+import android.telephony.ims.stub.ImsSmsImplBase;
 import android.util.ArraySet;
 import android.util.SparseArray;
 import android.widget.Toast;
@@ -28,6 +29,7 @@
 public class TestMmTelFeatureImpl extends MmTelFeature {
 
     public static TestMmTelFeatureImpl sTestMmTelFeatureImpl;
+    public static TestImsSmsImpl sTestImsSmsImpl;
     private boolean mIsReady = false;
     // Enabled Capabilities - not status
     private SparseArray<MmTelCapabilities> mEnabledCapabilities = new SparseArray<>();
@@ -53,6 +55,13 @@
         return sTestMmTelFeatureImpl;
     }
 
+    public static TestImsSmsImpl getSmsInstance() {
+        if (sTestImsSmsImpl == null) {
+            sTestImsSmsImpl = new TestImsSmsImpl();
+        }
+        return sTestImsSmsImpl;
+    }
+
     public void addUpdateCallback(MmTelUpdateCallback callback) {
         mCallbacks.add(callback);
     }
@@ -79,6 +88,11 @@
     }
 
     @Override
+    public ImsSmsImplBase getSmsImplementation() {
+        return getSmsInstance();
+    }
+
+    @Override
     public void onFeatureRemoved() {
         super.onFeatureRemoved();
     }