Merge "Fix CarrierSettings preference"
diff --git a/src/com/android/settings/network/telephony/CarrierPreferenceController.java b/src/com/android/settings/network/telephony/CarrierPreferenceController.java
index 8210c4b..3dab15e 100644
--- a/src/com/android/settings/network/telephony/CarrierPreferenceController.java
+++ b/src/com/android/settings/network/telephony/CarrierPreferenceController.java
@@ -17,6 +17,10 @@
 package com.android.settings.network.telephony;
 
 import android.content.Context;
+import android.content.ComponentName;
+import android.content.Intent;
+import android.content.pm.PackageManager;
+import android.content.pm.ResolveInfo;
 import android.os.PersistableBundle;
 import android.telephony.CarrierConfigManager;
 import android.telephony.SubscriptionManager;
@@ -62,10 +66,31 @@
     @Override
     public boolean handlePreferenceTreeClick(Preference preference) {
         if (getPreferenceKey().equals(preference.getKey())) {
-            //TODO(b/117651939): start carrier settings activity
+            final Intent carrierSettingsIntent = getCarrierSettingsActivityIntent(mSubId);
+            if (carrierSettingsIntent != null) {
+                mContext.startActivity(carrierSettingsIntent);
+            }
             return true;
         }
 
         return false;
     }
+
+    private Intent getCarrierSettingsActivityIntent(int subId) {
+        final PersistableBundle config = mCarrierConfigManager.getConfigForSubId(subId);
+        final ComponentName cn = ComponentName.unflattenFromString(
+                config == null ? "" : config.getString(
+                        CarrierConfigManager.KEY_CARRIER_SETTINGS_ACTIVITY_COMPONENT_NAME_STRING,
+                        "" /* default value */));
+
+        if (cn == null) return null;
+
+        final Intent intent = new Intent(Intent.ACTION_MAIN);
+        intent.setComponent(cn);
+        intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+
+        final PackageManager pm = mContext.getPackageManager();
+        final ResolveInfo resolveInfo = pm.resolveActivity(intent, 0 /* flags */);
+        return resolveInfo != null ? intent : null;
+    }
 }
diff --git a/tests/robotests/src/com/android/settings/network/telephony/CarrierPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/network/telephony/CarrierPreferenceControllerTest.java
index 8673de8..054a6bd 100644
--- a/tests/robotests/src/com/android/settings/network/telephony/CarrierPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/network/telephony/CarrierPreferenceControllerTest.java
@@ -21,10 +21,18 @@
 
 import static com.google.common.truth.Truth.assertThat;
 
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyInt;
 import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.never;
 import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.verify;
 
 import android.content.Context;
+import android.content.ComponentName;
+import android.content.Intent;
+import android.content.pm.PackageManager;
+import android.content.pm.ResolveInfo;
 import android.os.PersistableBundle;
 import android.telephony.CarrierConfigManager;
 import android.telephony.SubscriptionManager;
@@ -38,12 +46,15 @@
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.mockito.Mock;
+import org.mockito.Mockito;
 import org.mockito.MockitoAnnotations;
+import org.mockito.ArgumentCaptor;
 import org.robolectric.RuntimeEnvironment;
 
 @RunWith(SettingsRobolectricTestRunner.class)
 public class CarrierPreferenceControllerTest {
     private static final int SUB_ID = 2;
+    private static final String CARRIER_SETTINGS_COMPONENT = "packageName/className";
 
     @Mock
     private TelephonyManager mTelephonyManager;
@@ -106,4 +117,55 @@
 
         assertThat(mController.getAvailabilityStatus()).isEqualTo(AVAILABLE);
     }
+
+    @Test
+    public void handlePreferenceClick_activityFound_openCarrierSettingActivity() {
+        final PersistableBundle bundle = new PersistableBundle();
+        bundle.putString(
+                CarrierConfigManager.KEY_CARRIER_SETTINGS_ACTIVITY_COMPONENT_NAME_STRING,
+                CARRIER_SETTINGS_COMPONENT);
+        doReturn(bundle).when(mCarrierConfigManager).getConfigForSubId(SUB_ID);
+        PackageManager pm = Mockito.mock(PackageManager.class);
+        doReturn(pm).when(mContext).getPackageManager();
+        doReturn(new ResolveInfo()).when(pm).resolveActivity(any(Intent.class), anyInt());
+
+        mController.handlePreferenceTreeClick(mPreference);
+
+        final ArgumentCaptor<Intent> captor = ArgumentCaptor.forClass(Intent.class);
+        verify(mContext).startActivity(captor.capture());
+        final Intent intent = captor.getValue();
+        assertThat(intent.getComponent()).isEqualTo(
+                ComponentName.unflattenFromString(CARRIER_SETTINGS_COMPONENT));
+    }
+
+    @Test
+    public void handlePreferenceClick_activityNotFound_DoNothing() {
+        final PersistableBundle bundle = new PersistableBundle();
+        bundle.putString(
+                CarrierConfigManager.KEY_CARRIER_SETTINGS_ACTIVITY_COMPONENT_NAME_STRING,
+                CARRIER_SETTINGS_COMPONENT);
+        doReturn(bundle).when(mCarrierConfigManager).getConfigForSubId(SUB_ID);
+        PackageManager pm = Mockito.mock(PackageManager.class);
+        doReturn(pm).when(mContext).getPackageManager();
+        doReturn(null).when(pm).resolveActivity(any(Intent.class), anyInt());
+
+        mController.handlePreferenceTreeClick(mPreference);
+
+        final ArgumentCaptor<Intent> captor = ArgumentCaptor.forClass(Intent.class);
+        verify(mContext, never()).startActivity(captor.capture());
+    }
+
+    @Test
+    public void handlePreferenceClick_activityNotConfigured_DoNothing() {
+        final PersistableBundle bundle = new PersistableBundle();
+        doReturn(bundle).when(mCarrierConfigManager).getConfigForSubId(SUB_ID);
+        PackageManager pm = Mockito.mock(PackageManager.class);
+        doReturn(pm).when(mContext).getPackageManager();
+        doReturn(new ResolveInfo()).when(pm).resolveActivity(any(Intent.class), anyInt());
+
+        mController.handlePreferenceTreeClick(mPreference);
+
+        final ArgumentCaptor<Intent> captor = ArgumentCaptor.forClass(Intent.class);
+        verify(mContext, never()).startActivity(captor.capture());
+    }
 }