Merge "Merge lastest test case from master" into rvc-dev
diff --git a/src/com/android/settings/AirplaneModeEnabler.java b/src/com/android/settings/AirplaneModeEnabler.java
index a843a04..6028c18 100644
--- a/src/com/android/settings/AirplaneModeEnabler.java
+++ b/src/com/android/settings/AirplaneModeEnabler.java
@@ -19,6 +19,7 @@
 import android.app.settings.SettingsEnums;
 import android.content.Context;
 import android.content.Intent;
+import android.os.Looper;
 import android.os.UserHandle;
 import android.provider.Settings;
 import android.telephony.PhoneStateListener;
@@ -62,8 +63,6 @@
     @VisibleForTesting
     PhoneStateListener mPhoneStateListener;
 
-    private GlobalSettingsChangeListener mAirplaneModeObserver;
-
     public AirplaneModeEnabler(Context context, OnAirplaneModeChangedListener listener) {
         super(context, Settings.Global.AIRPLANE_MODE_ON);
 
@@ -73,7 +72,7 @@
 
         mTelephonyManager = context.getSystemService(TelephonyManager.class);
 
-        mPhoneStateListener = new PhoneStateListener() {
+        mPhoneStateListener = new PhoneStateListener(Looper.getMainLooper()) {
             @Override
             public void onRadioPowerStateChanged(int state) {
                 if (DEBUG) {
@@ -87,6 +86,7 @@
     /**
      * Implementation of GlobalSettingsChangeListener.onChanged
      */
+    @Override
     public void onChanged(String field) {
         if (DEBUG) {
             Log.d(LOG_TAG, "Airplane mode configuration update");
@@ -94,12 +94,18 @@
         onAirplaneModeChanged();
     }
 
-    public void resume() {
+    /**
+     * Start listening to the phone state change
+     */
+    public void start() {
         mTelephonyManager.listen(mPhoneStateListener,
                 PhoneStateListener.LISTEN_RADIO_POWER_STATE_CHANGED);
     }
 
-    public void pause() {
+    /**
+     * Stop listening to the phone state change
+     */
+    public void stop() {
         mTelephonyManager.listen(mPhoneStateListener,
                 PhoneStateListener.LISTEN_NONE);
     }
diff --git a/src/com/android/settings/media/MediaOutputIndicatorSlice.java b/src/com/android/settings/media/MediaOutputIndicatorSlice.java
index f336f27..63dd2de 100644
--- a/src/com/android/settings/media/MediaOutputIndicatorSlice.java
+++ b/src/com/android/settings/media/MediaOutputIndicatorSlice.java
@@ -25,8 +25,8 @@
 import android.graphics.Bitmap;
 import android.media.session.MediaController;
 import android.net.Uri;
-import android.util.Log;
 
+import androidx.annotation.VisibleForTesting;
 import androidx.core.graphics.drawable.IconCompat;
 import androidx.slice.Slice;
 import androidx.slice.builders.ListBuilder;
@@ -36,7 +36,6 @@
 import com.android.settings.Utils;
 import com.android.settings.slices.CustomSliceable;
 import com.android.settings.slices.SliceBackgroundWorker;
-import com.android.settings.slices.SliceBroadcastReceiver;
 import com.android.settingslib.media.MediaOutputSliceConstants;
 
 public class MediaOutputIndicatorSlice implements CustomSliceable {
@@ -60,8 +59,10 @@
         final IconCompat icon = IconCompat.createWithResource(mContext,
                 com.android.internal.R.drawable.ic_settings_bluetooth);
         final CharSequence title = mContext.getText(R.string.media_output_title);
+        final PendingIntent primaryActionIntent = PendingIntent.getActivity(mContext,
+                0 /* requestCode */, getMediaOutputSliceIntent(), 0 /* flags */);
         final SliceAction primarySliceAction = SliceAction.createDeeplink(
-                getBroadcastIntent(), icon, ListBuilder.ICON_IMAGE, title);
+                primaryActionIntent, icon, ListBuilder.ICON_IMAGE, title);
         @ColorInt final int color = Utils.getColorAccentDefaultColor(mContext);
         // To set an empty icon to indent the row
         final ListBuilder listBuilder = new ListBuilder(mContext, getUri(), ListBuilder.INFINITY)
@@ -74,18 +75,27 @@
         return listBuilder.build();
     }
 
+    @VisibleForTesting
+    Intent getMediaOutputSliceIntent() {
+        final MediaController mediaController = getWorker().getActiveLocalMediaController();
+        final Intent intent = new Intent()
+                .setPackage(Utils.SETTINGS_PACKAGE_NAME)
+                .setAction(MediaOutputSliceConstants.ACTION_MEDIA_OUTPUT)
+                .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+        if (mediaController != null) {
+            intent.putExtra(MediaOutputSliceConstants.KEY_MEDIA_SESSION_TOKEN,
+                    mediaController.getSessionToken());
+            intent.putExtra(MediaOutputSliceConstants.EXTRA_PACKAGE_NAME,
+                    mediaController.getPackageName());
+        }
+        return intent;
+    }
+
     private IconCompat createEmptyIcon() {
         final Bitmap bitmap = Bitmap.createBitmap(1, 1, Bitmap.Config.ARGB_8888);
         return IconCompat.createWithBitmap(bitmap);
     }
 
-    private PendingIntent getBroadcastIntent() {
-        final Intent intent = new Intent(getUri().toString());
-        intent.setClass(mContext, SliceBroadcastReceiver.class);
-        return PendingIntent.getBroadcast(mContext, 0, intent,
-                PendingIntent.FLAG_UPDATE_CURRENT);
-    }
-
     @Override
     public Uri getUri() {
         return MEDIA_OUTPUT_INDICATOR_SLICE_URI;
@@ -103,26 +113,6 @@
         return MediaOutputIndicatorWorker.class;
     }
 
-    @Override
-    public void onNotifyChange(Intent i) {
-        if (getWorker() == null) {
-            Log.d(TAG, "onNotifyChange: Worker is null");
-            return;
-        }
-        final MediaController mediaController = getWorker().getActiveLocalMediaController();
-        final Intent intent = new Intent()
-                .setPackage(Utils.SETTINGS_PACKAGE_NAME)
-                .setAction(MediaOutputSliceConstants.ACTION_MEDIA_OUTPUT)
-                .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
-        if (mediaController != null) {
-            intent.putExtra(MediaOutputSliceConstants.KEY_MEDIA_SESSION_TOKEN,
-                    mediaController.getSessionToken());
-            intent.putExtra(MediaOutputSliceConstants.EXTRA_PACKAGE_NAME,
-                    mediaController.getPackageName());
-        }
-        mContext.startActivity(intent);
-    }
-
     private MediaOutputIndicatorWorker getWorker() {
         if (mWorker == null) {
             mWorker = SliceBackgroundWorker.getInstance(getUri());
diff --git a/src/com/android/settings/network/AirplaneModePreferenceController.java b/src/com/android/settings/network/AirplaneModePreferenceController.java
index e852b80..122b975 100644
--- a/src/com/android/settings/network/AirplaneModePreferenceController.java
+++ b/src/com/android/settings/network/AirplaneModePreferenceController.java
@@ -35,11 +35,11 @@
 import com.android.settings.R;
 import com.android.settings.core.TogglePreferenceController;
 import com.android.settingslib.core.lifecycle.LifecycleObserver;
-import com.android.settingslib.core.lifecycle.events.OnPause;
-import com.android.settingslib.core.lifecycle.events.OnResume;
+import com.android.settingslib.core.lifecycle.events.OnStart;
+import com.android.settingslib.core.lifecycle.events.OnStop;
 
 public class AirplaneModePreferenceController extends TogglePreferenceController
-        implements LifecycleObserver, OnResume, OnPause,
+        implements LifecycleObserver, OnStart, OnStop,
         AirplaneModeEnabler.OnAirplaneModeChangedListener {
 
     public static final int REQUEST_CODE_EXIT_ECM = 1;
@@ -120,16 +120,16 @@
     }
 
     @Override
-    public void onResume() {
+    public void onStart() {
         if (isAvailable()) {
-            mAirplaneModeEnabler.resume();
+            mAirplaneModeEnabler.start();
         }
     }
 
     @Override
-    public void onPause() {
+    public void onStop() {
         if (isAvailable()) {
-            mAirplaneModeEnabler.pause();
+            mAirplaneModeEnabler.stop();
         }
     }
 
diff --git a/src/com/android/settings/network/SubscriptionsChangeListener.java b/src/com/android/settings/network/SubscriptionsChangeListener.java
index 1b50a54..192ee53 100644
--- a/src/com/android/settings/network/SubscriptionsChangeListener.java
+++ b/src/com/android/settings/network/SubscriptionsChangeListener.java
@@ -23,6 +23,7 @@
 import android.database.ContentObserver;
 import android.net.Uri;
 import android.os.Handler;
+import android.os.Looper;
 import android.provider.Settings;
 import android.telephony.SubscriptionManager;
 import android.telephony.SubscriptionManager.OnSubscriptionsChangedListener;
@@ -45,11 +46,11 @@
     private BroadcastReceiver mBroadcastReceiver;
 
     public SubscriptionsChangeListener(Context context, SubscriptionsChangeListenerClient client) {
-        super(new Handler());
+        super(new Handler(Looper.getMainLooper()));
         mContext = context;
         mClient = client;
         mSubscriptionManager = mContext.getSystemService(SubscriptionManager.class);
-        mSubscriptionsChangedListener = new OnSubscriptionsChangedListener() {
+        mSubscriptionsChangedListener = new OnSubscriptionsChangedListener(Looper.getMainLooper()) {
             @Override
             public void onSubscriptionsChanged() {
                 subscriptionsChangedCallback();
diff --git a/src/com/android/settings/network/telephony/Enhanced4gBasePreferenceController.java b/src/com/android/settings/network/telephony/Enhanced4gBasePreferenceController.java
index d3fb437..cbe0912 100644
--- a/src/com/android/settings/network/telephony/Enhanced4gBasePreferenceController.java
+++ b/src/com/android/settings/network/telephony/Enhanced4gBasePreferenceController.java
@@ -17,6 +17,7 @@
 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;
@@ -187,7 +188,7 @@
     private class PhoneCallStateListener extends PhoneStateListener {
 
         PhoneCallStateListener() {
-            super();
+            super(Looper.getMainLooper());
         }
 
         private TelephonyManager mTelephonyManager;
diff --git a/src/com/android/settings/network/telephony/VideoCallingPreferenceController.java b/src/com/android/settings/network/telephony/VideoCallingPreferenceController.java
index eed4046..d235a9a 100644
--- a/src/com/android/settings/network/telephony/VideoCallingPreferenceController.java
+++ b/src/com/android/settings/network/telephony/VideoCallingPreferenceController.java
@@ -17,6 +17,7 @@
 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;
@@ -164,7 +165,7 @@
     private class PhoneCallStateListener extends PhoneStateListener {
 
         PhoneCallStateListener() {
-            super();
+            super(Looper.getMainLooper());
         }
 
         private TelephonyManager mTelephonyManager;
diff --git a/src/com/android/settings/network/telephony/WifiCallingPreferenceController.java b/src/com/android/settings/network/telephony/WifiCallingPreferenceController.java
index e928dba..bec8a51 100644
--- a/src/com/android/settings/network/telephony/WifiCallingPreferenceController.java
+++ b/src/com/android/settings/network/telephony/WifiCallingPreferenceController.java
@@ -20,6 +20,7 @@
 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;
@@ -194,7 +195,7 @@
     private class PhoneCallStateListener extends PhoneStateListener {
 
         PhoneCallStateListener() {
-            super();
+            super(Looper.getMainLooper());
         }
 
         private TelephonyManager mTelephonyManager;
diff --git a/src/com/android/settings/slices/SlicesIndexer.java b/src/com/android/settings/slices/SlicesIndexer.java
index 3a68a32..e527fd6 100644
--- a/src/com/android/settings/slices/SlicesIndexer.java
+++ b/src/com/android/settings/slices/SlicesIndexer.java
@@ -104,7 +104,10 @@
             values.put(IndexColumns.SLICE_URI, dataRow.getUri().toSafeString());
             values.put(IndexColumns.TITLE, dataRow.getTitle());
             values.put(IndexColumns.SUMMARY, dataRow.getSummary());
-            values.put(IndexColumns.SCREENTITLE, dataRow.getScreenTitle().toString());
+            final CharSequence screenTitle = dataRow.getScreenTitle();
+            if (screenTitle != null) {
+                values.put(IndexColumns.SCREENTITLE, screenTitle.toString());
+            }
             values.put(IndexColumns.KEYWORDS, dataRow.getKeywords());
             values.put(IndexColumns.ICON_RESOURCE, dataRow.getIconResource());
             values.put(IndexColumns.FRAGMENT, dataRow.getFragmentClassName());
diff --git a/tests/robotests/src/com/android/settings/AirplaneModeEnablerTest.java b/tests/robotests/src/com/android/settings/AirplaneModeEnablerTest.java
index 24abac9..6c5b9f2 100644
--- a/tests/robotests/src/com/android/settings/AirplaneModeEnablerTest.java
+++ b/tests/robotests/src/com/android/settings/AirplaneModeEnablerTest.java
@@ -53,7 +53,7 @@
 
     @Test
     public void onRadioPowerStateChanged_beenInvoke_invokeOnAirplaneModeChanged() {
-        mAirplaneModeEnabler.resume();
+        mAirplaneModeEnabler.start();
 
         ShadowSettings.setAirplaneMode(true);
 
diff --git a/tests/robotests/src/com/android/settings/media/MediaOutputIndicatorSliceTest.java b/tests/robotests/src/com/android/settings/media/MediaOutputIndicatorSliceTest.java
index 55cc4cd..1fc3910 100644
--- a/tests/robotests/src/com/android/settings/media/MediaOutputIndicatorSliceTest.java
+++ b/tests/robotests/src/com/android/settings/media/MediaOutputIndicatorSliceTest.java
@@ -21,11 +21,8 @@
 
 import static com.google.common.truth.Truth.assertThat;
 
-import static org.mockito.ArgumentMatchers.any;
 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 static org.mockito.Mockito.when;
 
 import android.content.Context;
@@ -48,14 +45,12 @@
 import com.android.settings.slices.SliceBackgroundWorker;
 import com.android.settings.testutils.shadow.ShadowBluetoothUtils;
 import com.android.settingslib.bluetooth.LocalBluetoothManager;
-import com.android.settingslib.media.LocalMediaManager;
 import com.android.settingslib.media.MediaDevice;
 import com.android.settingslib.media.MediaOutputSliceConstants;
 
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
-import org.mockito.ArgumentCaptor;
 import org.mockito.Mock;
 import org.mockito.MockitoAnnotations;
 import org.robolectric.RobolectricTestRunner;
@@ -85,8 +80,6 @@
     @Mock
     private MediaController mMediaController;
     @Mock
-    private LocalMediaManager mLocalMediaManager;
-    @Mock
     private MediaDevice mDevice1;
     @Mock
     private MediaDevice mDevice2;
@@ -193,46 +186,32 @@
     }
 
     @Test
-    public void onNotifyChange_noWorker_doNothing() {
-        sMediaOutputIndicatorWorker = null;
-        mMediaOutputIndicatorSlice.onNotifyChange(new Intent());
-
-        verify(mContext, never()).startActivity(any());
-    }
-
-    @Test
-    public void onNotifyChange_withActiveLocalMedia_verifyIntentExtra() {
+    public void getMediaOutputSliceIntent_withActiveLocalMedia_verifyIntentExtra() {
         when(mMediaController.getSessionToken()).thenReturn(mToken);
         when(mMediaController.getPackageName()).thenReturn(TEST_PACKAGE_NAME);
         doReturn(mMediaController).when(sMediaOutputIndicatorWorker)
                 .getActiveLocalMediaController();
+        final Intent intent = mMediaOutputIndicatorSlice.getMediaOutputSliceIntent();
 
-        final ArgumentCaptor<Intent> intentCaptor = ArgumentCaptor.forClass(Intent.class);
-        mMediaOutputIndicatorSlice.onNotifyChange(new Intent());
-        verify(mContext).startActivity(intentCaptor.capture());
-
-        assertThat(TextUtils.equals(TEST_PACKAGE_NAME, intentCaptor.getValue().getStringExtra(
+        assertThat(TextUtils.equals(TEST_PACKAGE_NAME, intent.getStringExtra(
                 MediaOutputSliceConstants.EXTRA_PACKAGE_NAME))).isTrue();
-        assertThat(TextUtils.equals(Utils.SETTINGS_PACKAGE_NAME, intentCaptor.getValue()
-                .getPackage())).isTrue();
-        assertThat(mToken == intentCaptor.getValue().getExtras().getParcelable(
+        assertThat(MediaOutputSliceConstants.ACTION_MEDIA_OUTPUT).isEqualTo(intent.getAction());
+        assertThat(TextUtils.equals(Utils.SETTINGS_PACKAGE_NAME, intent.getPackage())).isTrue();
+        assertThat(mToken == intent.getExtras().getParcelable(
                 MediaOutputSliceConstants.KEY_MEDIA_SESSION_TOKEN)).isTrue();
     }
 
     @Test
-    public void onNotifyChange_withoutActiveLocalMedia_verifyIntentExtra() {
+    public void getMediaOutputSliceIntent_withoutActiveLocalMedia_verifyIntentExtra() {
         doReturn(mMediaController).when(sMediaOutputIndicatorWorker)
                 .getActiveLocalMediaController();
+        final Intent intent = mMediaOutputIndicatorSlice.getMediaOutputSliceIntent();
 
-        final ArgumentCaptor<Intent> intentCaptor = ArgumentCaptor.forClass(Intent.class);
-        mMediaOutputIndicatorSlice.onNotifyChange(new Intent());
-        verify(mContext).startActivity(intentCaptor.capture());
-
-        assertThat(TextUtils.isEmpty(intentCaptor.getValue().getStringExtra(
+        assertThat(TextUtils.isEmpty(intent.getStringExtra(
                 MediaOutputSliceConstants.EXTRA_PACKAGE_NAME))).isTrue();
-        assertThat(TextUtils.equals(Utils.SETTINGS_PACKAGE_NAME, intentCaptor.getValue()
-                .getPackage())).isTrue();
-        assertThat(intentCaptor.getValue().getExtras().getParcelable(
+        assertThat(MediaOutputSliceConstants.ACTION_MEDIA_OUTPUT).isEqualTo(intent.getAction());
+        assertThat(TextUtils.equals(Utils.SETTINGS_PACKAGE_NAME, intent.getPackage())).isTrue();
+        assertThat(intent.getExtras().getParcelable(
                 MediaOutputSliceConstants.KEY_MEDIA_SESSION_TOKEN) == null).isTrue();
     }
 
diff --git a/tests/robotests/src/com/android/settings/network/AirplaneModePreferenceControllerTest.java b/tests/robotests/src/com/android/settings/network/AirplaneModePreferenceControllerTest.java
index 54c3683..cb68e2a 100644
--- a/tests/robotests/src/com/android/settings/network/AirplaneModePreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/network/AirplaneModePreferenceControllerTest.java
@@ -102,8 +102,8 @@
         mController.displayPreference(mScreen);
 
         // This should not crash
-        mController.onResume();
-        mController.onPause();
+        mController.onStart();
+        mController.onStop();
     }
 
     @Test
@@ -115,8 +115,8 @@
         mController.displayPreference(mScreen);
 
         // This should not crash
-        mController.onResume();
-        mController.onPause();
+        mController.onStart();
+        mController.onStop();
     }
 
     @Test
@@ -147,7 +147,7 @@
         Settings.Global.putInt(mResolver, Settings.Global.AIRPLANE_MODE_ON, ON);
 
         mController.displayPreference(mScreen);
-        mController.onResume();
+        mController.onStart();
 
         assertThat(mController.isChecked()).isTrue();
 
@@ -161,7 +161,7 @@
         Settings.Global.putInt(mResolver, Settings.Global.AIRPLANE_MODE_ON, OFF);
 
         mController.displayPreference(mScreen);
-        mController.onResume();
+        mController.onStop();
 
         assertThat(mPreference.isChecked()).isFalse();