Merge "Revert back to getString to avoid issues with translation." into sc-qpr1-dev
diff --git a/src/com/android/phone/CarrierConfigLoader.java b/src/com/android/phone/CarrierConfigLoader.java
index a463243..d3792f1 100644
--- a/src/com/android/phone/CarrierConfigLoader.java
+++ b/src/com/android/phone/CarrierConfigLoader.java
@@ -107,10 +107,6 @@
     private CarrierServiceConnection[] mServiceConnection;
     // Service connection for binding to carrier config app for no SIM config.
     private CarrierServiceConnection[] mServiceConnectionForNoSimConfig;
-    // Whether we are bound to a service for each phone
-    private boolean[] mServiceBound;
-    // Whether we are bound to a service for no SIM config
-    private boolean[] mServiceBoundForNoSimConfig;
     // Whether we have sent config change broadcast for each phone id.
     private boolean[] mHasSentConfigChange;
     // Whether the broadcast was sent from EVENT_SYSTEM_UNLOCKED, to track rebroadcasts
@@ -311,7 +307,7 @@
                     final CarrierServiceConnection conn = (CarrierServiceConnection) msg.obj;
                     // If new service connection has been created, unbind.
                     if (mServiceConnection[phoneId] != conn || conn.service == null) {
-                        unbindIfBound(mContext, conn, phoneId);
+                        unbindIfBound(mContext, conn);
                         break;
                     }
                     final CarrierIdentifier carrierId = getCarrierIdentifierForPhoneId(phoneId);
@@ -320,7 +316,7 @@
                             new ResultReceiver(this) {
                                 @Override
                                 public void onReceiveResult(int resultCode, Bundle resultData) {
-                                    unbindIfBound(mContext, conn, phoneId);
+                                    unbindIfBound(mContext, conn);
                                     removeMessages(EVENT_FETCH_DEFAULT_TIMEOUT,
                                             getMessageToken(phoneId));
                                     // If new service connection has been created, this is stale.
@@ -355,7 +351,7 @@
                     } catch (RemoteException e) {
                         loge("Failed to get carrier config from default app: " +
                                 mPlatformCarrierConfigPackage + " err: " + e.toString());
-                        unbindIfBound(mContext, conn, phoneId);
+                        unbindIfBound(mContext, conn);
                         break; // So we don't set a timeout.
                     }
                     sendMessageDelayed(
@@ -375,7 +371,7 @@
                     if (mServiceConnection[phoneId] != null) {
                         // If a ResponseReceiver callback is in the queue when this happens, we will
                         // unbind twice and throw an exception.
-                        unbindIfBound(mContext, mServiceConnection[phoneId], phoneId);
+                        unbindIfBound(mContext, mServiceConnection[phoneId]);
                         broadcastConfigChangedIntent(phoneId);
                     }
                     // Put a stub bundle in place so that the rest of the logic continues smoothly.
@@ -441,7 +437,7 @@
                     final CarrierServiceConnection conn = (CarrierServiceConnection) msg.obj;
                     // If new service connection has been created, unbind.
                     if (mServiceConnection[phoneId] != conn || conn.service == null) {
-                        unbindIfBound(mContext, conn, phoneId);
+                        unbindIfBound(mContext, conn);
                         break;
                     }
                     final CarrierIdentifier carrierId = getCarrierIdentifierForPhoneId(phoneId);
@@ -450,7 +446,7 @@
                             new ResultReceiver(this) {
                                 @Override
                                 public void onReceiveResult(int resultCode, Bundle resultData) {
-                                    unbindIfBound(mContext, conn, phoneId);
+                                    unbindIfBound(mContext, conn);
                                     removeMessages(EVENT_FETCH_CARRIER_TIMEOUT,
                                             getMessageToken(phoneId));
                                     // If new service connection has been created, this is stale.
@@ -494,7 +490,7 @@
                                 + " carrierid: " + carrierId.toString());
                     } catch (RemoteException e) {
                         loge("Failed to get carrier config: " + e.toString());
-                        unbindIfBound(mContext, conn, phoneId);
+                        unbindIfBound(mContext, conn);
                         break; // So we don't set a timeout.
                     }
                     sendMessageDelayed(
@@ -515,7 +511,7 @@
                     if (mServiceConnection[phoneId] != null) {
                         // If a ResponseReceiver callback is in the queue when this happens, we will
                         // unbind twice and throw an exception.
-                        unbindIfBound(mContext, mServiceConnection[phoneId], phoneId);
+                        unbindIfBound(mContext, mServiceConnection[phoneId]);
                         broadcastConfigChangedIntent(phoneId);
                     }
                     // Put a stub bundle in place so that the rest of the logic continues smoothly.
@@ -609,8 +605,7 @@
                     if (mServiceConnectionForNoSimConfig[phoneId] != null) {
                         // If a ResponseReceiver callback is in the queue when this happens, we will
                         // unbind twice and throw an exception.
-                        unbindIfBoundForNoSimConfig(mContext,
-                                mServiceConnectionForNoSimConfig[phoneId], phoneId);
+                        unbindIfBound(mContext, mServiceConnectionForNoSimConfig[phoneId]);
                     }
                     broadcastConfigChangedIntent(phoneId, false);
                     break;
@@ -621,7 +616,7 @@
                     final CarrierServiceConnection conn = (CarrierServiceConnection) msg.obj;
                     // If new service connection has been created, unbind.
                     if (mServiceConnectionForNoSimConfig[phoneId] != conn || conn.service == null) {
-                        unbindIfBoundForNoSimConfig(mContext, conn, phoneId);
+                        unbindIfBound(mContext, conn);
                         break;
                     }
 
@@ -630,7 +625,7 @@
                             new ResultReceiver(this) {
                                 @Override
                                 public void onReceiveResult(int resultCode, Bundle resultData) {
-                                    unbindIfBoundForNoSimConfig(mContext, conn, phoneId);
+                                    unbindIfBound(mContext, conn);
                                     // If new service connection has been created, this is stale.
                                     if (mServiceConnectionForNoSimConfig[phoneId] != conn) {
                                         loge("Received response for stale request.");
@@ -662,7 +657,7 @@
                     } catch (RemoteException e) {
                         loge("Failed to get no sim carrier config from default app: " +
                                 mPlatformCarrierConfigPackage + " err: " + e.toString());
-                        unbindIfBoundForNoSimConfig(mContext, conn, phoneId);
+                        unbindIfBound(mContext, conn);
                         break; // So we don't set a timeout.
                     }
                     sendMessageDelayed(
@@ -709,11 +704,9 @@
         mOverrideConfigs = new PersistableBundle[numPhones];
         mNoSimConfig = new PersistableBundle();
         mServiceConnection = new CarrierServiceConnection[numPhones];
-        mServiceBound = new boolean[numPhones];
         mHasSentConfigChange = new boolean[numPhones];
         mFromSystemUnlocked = new boolean[numPhones];
         mServiceConnectionForNoSimConfig = new CarrierServiceConnection[numPhones];
-        mServiceBoundForNoSimConfig = new boolean[numPhones];
         logd("CarrierConfigLoader has started");
         mSubscriptionInfoUpdater = subscriptionInfoUpdater;
         mHandler.sendEmptyMessage(EVENT_CHECK_SYSTEM_UPDATE);
@@ -848,11 +841,7 @@
         try {
             if (mContext.bindService(carrierService, serviceConnection,
                     Context.BIND_AUTO_CREATE)) {
-                if (eventId == EVENT_CONNECTED_TO_DEFAULT_FOR_NO_SIM_CONFIG) {
-                    mServiceBoundForNoSimConfig[phoneId] = true;
-                } else {
-                    mServiceBound[phoneId] = true;
-                }
+                serviceConnection.isBound = true;
                 return true;
             } else {
                 return false;
@@ -1369,18 +1358,9 @@
         return mOverrideConfigs[phoneId];
     }
 
-    private void unbindIfBound(Context context, CarrierServiceConnection conn,
-            int phoneId) {
-        if (mServiceBound[phoneId]) {
-            mServiceBound[phoneId] = false;
-            context.unbindService(conn);
-        }
-    }
-
-    private void unbindIfBoundForNoSimConfig(Context context, CarrierServiceConnection conn,
-            int phoneId) {
-        if (mServiceBoundForNoSimConfig[phoneId]) {
-            mServiceBoundForNoSimConfig[phoneId] = false;
+    private void unbindIfBound(Context context, CarrierServiceConnection conn) {
+        if (conn.isBound) {
+            conn.isBound = false;
             context.unbindService(conn);
         }
     }
@@ -1605,11 +1585,15 @@
         final String pkgName;
         final int eventId;
         IBinder service;
+        // If bindService was called and return true which means unbindService
+        // must be called later to release the connection
+        boolean isBound;
 
         CarrierServiceConnection(int phoneId, String pkgName, int eventId) {
             this.phoneId = phoneId;
             this.pkgName = pkgName;
             this.eventId = eventId;
+            this.isBound = false;
         }
 
         @Override
diff --git a/src/com/android/phone/SimPhonebookProvider.java b/src/com/android/phone/SimPhonebookProvider.java
index 5188d96..04c4f48 100644
--- a/src/com/android/phone/SimPhonebookProvider.java
+++ b/src/com/android/phone/SimPhonebookProvider.java
@@ -97,6 +97,8 @@
     private static final String TAG = "SimPhonebookProvider";
     private static final Set<String> ELEMENTARY_FILES_COLUMNS_SET =
             ImmutableSet.copyOf(ELEMENTARY_FILES_ALL_COLUMNS);
+    private static final Set<String> SIM_RECORDS_COLUMNS_SET =
+            ImmutableSet.copyOf(SIM_RECORDS_ALL_COLUMNS);
     private static final Set<String> SIM_RECORDS_WRITABLE_COLUMNS = ImmutableSet.of(
             SimRecords.NAME, SimRecords.PHONE_NUMBER
     );
@@ -355,6 +357,7 @@
     }
 
     private Cursor querySimRecords(PhonebookArgs args, String[] projection) {
+        validateProjection(SIM_RECORDS_COLUMNS_SET, projection);
         validateSubscriptionAndEf(args);
         if (projection == null) {
             projection = SIM_RECORDS_ALL_COLUMNS;
@@ -409,6 +412,7 @@
     }
 
     private Cursor querySimRecordsItem(PhonebookArgs args, String[] projection) {
+        validateProjection(SIM_RECORDS_COLUMNS_SET, projection);
         if (projection == null) {
             projection = SIM_RECORDS_ALL_COLUMNS;
         }
diff --git a/src/com/android/services/telephony/DisconnectCauseUtil.java b/src/com/android/services/telephony/DisconnectCauseUtil.java
index 706cea7..9321e1e 100644
--- a/src/com/android/services/telephony/DisconnectCauseUtil.java
+++ b/src/com/android/services/telephony/DisconnectCauseUtil.java
@@ -792,7 +792,7 @@
 
     private static boolean isRadioOffForThermalMitigation(int phoneId) {
         Phone phone = PhoneFactory.getPhone(phoneId);
-        return phone.isRadioOffForThermalMitigation();
+        return phone == null ? false : phone.isRadioOffForThermalMitigation();
     }
 
     /**
diff --git a/tests/src/com/android/phone/SimPhonebookProviderTest.java b/tests/src/com/android/phone/SimPhonebookProviderTest.java
index 53f8f1a..29a653d 100644
--- a/tests/src/com/android/phone/SimPhonebookProviderTest.java
+++ b/tests/src/com/android/phone/SimPhonebookProviderTest.java
@@ -56,6 +56,7 @@
 import com.android.internal.telephony.uicc.IccConstants;
 
 import com.google.common.collect.ImmutableList;
+import com.google.common.io.Closeables;
 import com.google.common.truth.Correspondence;
 
 import org.junit.Before;
@@ -288,6 +289,33 @@
     }
 
     @Test
+    public void query_adnRecords_invalidColumnProjection_throwsIllegalArgumentException() {
+        setupSimsWithSubscriptionIds(1);
+        mIccPhoneBook.makeAllEfsSupported(1);
+        Uri contentAdn = SimRecords.getContentUri(1, EF_ADN);
+
+        assertThrows(IllegalArgumentException.class, () -> Closeables.close(
+                mResolver.query(contentAdn, new String[] {
+                        "an_unsupported_column",
+                }, null, null), false)
+        );
+
+        assertThrows(IllegalArgumentException.class, () -> Closeables.close(
+                mResolver.query(contentAdn, new String[] {
+                        SimRecords.RECORD_NUMBER,
+                        "an_unsupported_column"
+                }, null, null), false)
+        );
+
+        assertThrows(IllegalArgumentException.class, () -> Closeables.close(
+                mResolver.query(contentAdn, new String[] {
+                        "an_unsupported_column",
+                        SimRecords.RECORD_NUMBER
+                }, null, null), false)
+        );
+    }
+
+    @Test
     public void query_adnRecords_noRecords_returnsEmptyCursor() {
         setupSimsWithSubscriptionIds(1);
         mIccPhoneBook.makeAllEfsSupported(1);