Merge "[Settings] Refactor PhoneStateListener"
diff --git a/src/com/android/settings/network/telephony/Enhanced4gBasePreferenceController.java b/src/com/android/settings/network/telephony/Enhanced4gBasePreferenceController.java
index 869091a..668f763 100644
--- a/src/com/android/settings/network/telephony/Enhanced4gBasePreferenceController.java
+++ b/src/com/android/settings/network/telephony/Enhanced4gBasePreferenceController.java
@@ -17,7 +17,6 @@
 package com.android.settings.network.telephony;
 
 import android.content.Context;
-import android.os.Looper;
 import android.os.PersistableBundle;
 import android.telephony.CarrierConfigManager;
 import android.telephony.PhoneStateListener;
@@ -47,7 +46,6 @@
         implements LifecycleObserver, OnStart, OnStop {
 
     private Preference mPreference;
-    private TelephonyManager mTelephonyManager;
     private CarrierConfigManager mCarrierConfigManager;
     private PersistableBundle mCarrierConfig;
     @VisibleForTesting
@@ -67,7 +65,7 @@
         super(context, key);
         mCarrierConfigManager = context.getSystemService(CarrierConfigManager.class);
         m4gLteListeners = new ArrayList<>();
-        mPhoneStateListener = new PhoneCallStateListener(Looper.getMainLooper());
+        mPhoneStateListener = new PhoneCallStateListener();
     }
 
     public Enhanced4gBasePreferenceController init(int subId) {
@@ -75,8 +73,6 @@
             return this;
         }
         mSubId = subId;
-        mTelephonyManager = mContext.getSystemService(TelephonyManager.class)
-                .createForSubscriptionId(mSubId);
         mCarrierConfig = mCarrierConfigManager.getConfigForSubId(mSubId);
         if (mSubId != SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
             mImsManager = ImsManager.getInstance(mContext, SubscriptionManager.getPhoneId(mSubId));
@@ -123,7 +119,7 @@
 
     @Override
     public void onStart() {
-        mPhoneStateListener.register(mSubId);
+        mPhoneStateListener.register(mContext, mSubId);
     }
 
     @Override
@@ -192,18 +188,23 @@
 
     private class PhoneCallStateListener extends PhoneStateListener {
 
-        public PhoneCallStateListener(Looper looper) {
-            super(looper);
+        PhoneCallStateListener() {
+            super();
         }
 
+        private TelephonyManager mTelephonyManager;
+
         @Override
         public void onCallStateChanged(int state, String incomingNumber) {
             mCallState = state;
             updateState(mPreference);
         }
 
-        public void register(int subId) {
-            Enhanced4gBasePreferenceController.this.mSubId = subId;
+        public void register(Context context, int subId) {
+            mTelephonyManager = context.getSystemService(TelephonyManager.class);
+            if (subId != SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
+                mTelephonyManager = mTelephonyManager.createForSubscriptionId(subId);
+            }
             mTelephonyManager.listen(this, PhoneStateListener.LISTEN_CALL_STATE);
         }
 
diff --git a/src/com/android/settings/network/telephony/VideoCallingPreferenceController.java b/src/com/android/settings/network/telephony/VideoCallingPreferenceController.java
index 22a3b7c..9aa390c 100644
--- a/src/com/android/settings/network/telephony/VideoCallingPreferenceController.java
+++ b/src/com/android/settings/network/telephony/VideoCallingPreferenceController.java
@@ -17,7 +17,6 @@
 package com.android.settings.network.telephony;
 
 import android.content.Context;
-import android.os.Looper;
 import android.os.PersistableBundle;
 import android.telephony.CarrierConfigManager;
 import android.telephony.PhoneStateListener;
@@ -47,7 +46,6 @@
         Enhanced4gBasePreferenceController.On4gLteUpdateListener {
 
     private Preference mPreference;
-    private TelephonyManager mTelephonyManager;
     private CarrierConfigManager mCarrierConfigManager;
     @VisibleForTesting
     ImsManager mImsManager;
@@ -60,7 +58,7 @@
         super(context, key);
         mCarrierConfigManager = context.getSystemService(CarrierConfigManager.class);
         mDataContentObserver = new MobileDataEnabledListener(context, this);
-        mPhoneStateListener = new PhoneCallStateListener(Looper.getMainLooper());
+        mPhoneStateListener = new PhoneCallStateListener();
     }
 
     @Override
@@ -79,7 +77,7 @@
 
     @Override
     public void onStart() {
-        mPhoneStateListener.register(mSubId);
+        mPhoneStateListener.register(mContext, mSubId);
         mDataContentObserver.start(mSubId);
     }
 
@@ -120,9 +118,7 @@
 
     public VideoCallingPreferenceController init(int subId) {
         mSubId = subId;
-        mTelephonyManager = mContext.getSystemService(TelephonyManager.class);
         if (mSubId != SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
-            mTelephonyManager = mTelephonyManager.createForSubscriptionId(mSubId);
             mImsManager = ImsManager.getInstance(mContext, SubscriptionManager.getPhoneId(mSubId));
         }
 
@@ -177,18 +173,23 @@
 
     private class PhoneCallStateListener extends PhoneStateListener {
 
-        public PhoneCallStateListener(Looper looper) {
-            super(looper);
+        PhoneCallStateListener() {
+            super();
         }
 
+        private TelephonyManager mTelephonyManager;
+
         @Override
         public void onCallStateChanged(int state, String incomingNumber) {
             mCallState = state;
             updateState(mPreference);
         }
 
-        public void register(int subId) {
-            VideoCallingPreferenceController.this.mSubId = subId;
+        public void register(Context context, int subId) {
+            mTelephonyManager = context.getSystemService(TelephonyManager.class);
+            if (subId != SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
+                mTelephonyManager = mTelephonyManager.createForSubscriptionId(subId);
+            }
             mTelephonyManager.listen(this, PhoneStateListener.LISTEN_CALL_STATE);
         }
 
diff --git a/src/com/android/settings/network/telephony/WifiCallingPreferenceController.java b/src/com/android/settings/network/telephony/WifiCallingPreferenceController.java
index efd24e6..2f176ef 100644
--- a/src/com/android/settings/network/telephony/WifiCallingPreferenceController.java
+++ b/src/com/android/settings/network/telephony/WifiCallingPreferenceController.java
@@ -20,7 +20,6 @@
 import android.content.Intent;
 import android.content.pm.PackageManager;
 import android.content.pm.ResolveInfo;
-import android.os.Looper;
 import android.os.PersistableBundle;
 import android.provider.Settings;
 import android.telecom.PhoneAccountHandle;
@@ -49,7 +48,8 @@
 public class WifiCallingPreferenceController extends TelephonyBasePreferenceController implements
         LifecycleObserver, OnStart, OnStop {
 
-    private TelephonyManager mTelephonyManager;
+    @VisibleForTesting
+    Integer mCallState;
     @VisibleForTesting
     CarrierConfigManager mCarrierConfigManager;
     @VisibleForTesting
@@ -63,8 +63,7 @@
     public WifiCallingPreferenceController(Context context, String key) {
         super(context, key);
         mCarrierConfigManager = context.getSystemService(CarrierConfigManager.class);
-        mTelephonyManager = context.getSystemService(TelephonyManager.class);
-        mPhoneStateListener = new PhoneCallStateListener(Looper.getMainLooper());
+        mPhoneStateListener = new PhoneCallStateListener();
     }
 
     @Override
@@ -77,7 +76,7 @@
 
     @Override
     public void onStart() {
-        mPhoneStateListener.register(mSubId);
+        mPhoneStateListener.register(mContext, mSubId);
     }
 
     @Override
@@ -98,6 +97,9 @@
     @Override
     public void updateState(Preference preference) {
         super.updateState(preference);
+        if (mCallState == null) {
+            return;
+        }
         if (mSimCallManager != null) {
             final Intent intent = MobileNetworkUtils.buildPhoneAccountConfigureIntent(mContext,
                     mSimCallManager);
@@ -126,7 +128,8 @@
                                         .KEY_USE_WFC_HOME_NETWORK_MODE_IN_ROAMING_NETWORK_BOOL);
                     }
                 }
-                final boolean isRoaming = mTelephonyManager.isNetworkRoaming();
+                final boolean isRoaming = getTelephonyManager(mContext, mSubId)
+                        .isNetworkRoaming();
                 final int wfcMode = (isRoaming && !useWfcHomeModeForRoaming)
                         ? mImsMmTelManager.getVoWiFiRoamingModeSetting() :
                         mImsMmTelManager.getVoWiFiModeSetting();
@@ -147,14 +150,11 @@
             }
             preference.setSummary(resId);
         }
-        preference.setEnabled(
-                mTelephonyManager.getCallState(mSubId) == TelephonyManager.CALL_STATE_IDLE);
+        preference.setEnabled(mCallState == TelephonyManager.CALL_STATE_IDLE);
     }
 
     public WifiCallingPreferenceController init(int subId) {
         mSubId = subId;
-        mTelephonyManager = mContext.getSystemService(TelephonyManager.class)
-                .createForSubscriptionId(mSubId);
         mImsManager = ImsManager.getInstance(mContext, SubscriptionManager.getPhoneId(mSubId));
         mImsMmTelManager = getImsMmTelManager(mSubId);
         mSimCallManager = mContext.getSystemService(TelecomManager.class)
@@ -167,23 +167,39 @@
         return ImsMmTelManager.createForSubscriptionId(subId);
     }
 
+    @VisibleForTesting
+    TelephonyManager getTelephonyManager(Context context, int subId) {
+        final TelephonyManager telephonyMgr = context.getSystemService(TelephonyManager.class);
+        if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
+            return telephonyMgr;
+        }
+        final TelephonyManager subscriptionTelephonyMgr =
+                telephonyMgr.createForSubscriptionId(subId);
+        return (subscriptionTelephonyMgr == null) ? telephonyMgr : subscriptionTelephonyMgr;
+    }
+
+
     private class PhoneCallStateListener extends PhoneStateListener {
 
-        public PhoneCallStateListener(Looper looper) {
-            super(looper);
+        PhoneCallStateListener() {
+            super();
         }
 
+        private TelephonyManager mTelephonyManager;
+
         @Override
         public void onCallStateChanged(int state, String incomingNumber) {
+            mCallState = state;
             updateState(mPreference);
         }
 
-        public void register(int subId) {
-            WifiCallingPreferenceController.this.mSubId = subId;
+        public void register(Context context, int subId) {
+            mTelephonyManager = getTelephonyManager(context, subId);
             mTelephonyManager.listen(this, PhoneStateListener.LISTEN_CALL_STATE);
         }
 
         public void unregister() {
+            mCallState = null;
             mTelephonyManager.listen(this, PhoneStateListener.LISTEN_NONE);
         }
     }
diff --git a/tests/robotests/src/com/android/settings/network/telephony/Enhanced4gBasePreferenceControllerTest.java b/tests/robotests/src/com/android/settings/network/telephony/Enhanced4gBasePreferenceControllerTest.java
index 9c1dc4f..714eb4e 100644
--- a/tests/robotests/src/com/android/settings/network/telephony/Enhanced4gBasePreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/network/telephony/Enhanced4gBasePreferenceControllerTest.java
@@ -71,7 +71,7 @@
         MockitoAnnotations.initMocks(this);
 
         mContext = spy(RuntimeEnvironment.application);
-        doReturn(mTelephonyManager).when(mContext).getSystemService(Context.TELEPHONY_SERVICE);
+        doReturn(mTelephonyManager).when(mContext).getSystemService(TelephonyManager.class);
         doReturn(mSubscriptionManager).when(mContext).getSystemService(SubscriptionManager.class);
         doReturn(mCarrierConfigManager).when(mContext).getSystemService(CarrierConfigManager.class);
         doReturn(mTelephonyManager).when(mTelephonyManager).createForSubscriptionId(SUB_ID);
diff --git a/tests/robotests/src/com/android/settings/network/telephony/WifiCallingPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/network/telephony/WifiCallingPreferenceControllerTest.java
index a320c6e..1c79266 100644
--- a/tests/robotests/src/com/android/settings/network/telephony/WifiCallingPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/network/telephony/WifiCallingPreferenceControllerTest.java
@@ -72,22 +72,22 @@
         MockitoAnnotations.initMocks(this);
 
         mContext = spy(RuntimeEnvironment.application);
-        when(mContext.getSystemService(Context.TELEPHONY_SERVICE)).thenReturn(mTelephonyManager);
-        when(mContext.getSystemService(TelephonyManager.class)).thenReturn(mTelephonyManager);
-        when(mTelephonyManager.createForSubscriptionId(SUB_ID)).thenReturn(mTelephonyManager);
 
         mPreference = new Preference(mContext);
-        mController = new WifiCallingPreferenceController(mContext, "wifi_calling") {
+        mController = spy(new WifiCallingPreferenceController(mContext, "wifi_calling") {
             @Override
             protected ImsMmTelManager getImsMmTelManager(int subId) {
                 return mImsMmTelManager;
             }
-        };
+        });
         mController.mCarrierConfigManager = mCarrierConfigManager;
         mController.init(SUB_ID);
         mController.mImsManager = mImsManager;
+        mController.mCallState = TelephonyManager.CALL_STATE_IDLE;
         mPreference.setKey(mController.getPreferenceKey());
 
+        when(mController.getTelephonyManager(mContext, SUB_ID)).thenReturn(mTelephonyManager);
+
         mCarrierConfig = new PersistableBundle();
         when(mCarrierConfigManager.getConfigForSubId(SUB_ID)).thenReturn(mCarrierConfig);
 
@@ -112,8 +112,7 @@
 
     @Test
     public void updateState_notCallIdle_disable() {
-        when(mTelephonyManager.getCallState(SUB_ID)).thenReturn(
-                TelephonyManager.CALL_STATE_RINGING);
+        mController.mCallState = TelephonyManager.CALL_STATE_RINGING;
 
         mController.updateState(mPreference);