diff --git a/src/com/android/settings/media/MediaOutputIndicatorWorker.java b/src/com/android/settings/media/MediaOutputIndicatorWorker.java index 0c6c434c9dd..f094d47004f 100644 --- a/src/com/android/settings/media/MediaOutputIndicatorWorker.java +++ b/src/com/android/settings/media/MediaOutputIndicatorWorker.java @@ -38,6 +38,7 @@ import com.android.settingslib.bluetooth.BluetoothCallback; import com.android.settingslib.bluetooth.LocalBluetoothManager; import com.android.settingslib.media.LocalMediaManager; import com.android.settingslib.media.MediaDevice; +import com.android.settingslib.utils.ThreadUtils; import com.google.common.annotations.VisibleForTesting; @@ -81,25 +82,29 @@ public class MediaOutputIndicatorWorker extends SliceBackgroundWorker implements mContext.registerReceiver(mReceiver, intentFilter); mLocalBluetoothManager.getEventManager().registerCallback(this); - final MediaController controller = getActiveLocalMediaController(); - if (controller == null) { - mPackageName = null; - } else { - mPackageName = controller.getPackageName(); - } - if (mLocalMediaManager == null || !TextUtils.equals(mPackageName, - mLocalMediaManager.getPackageName())) { - mLocalMediaManager = new LocalMediaManager(mContext, mPackageName, - null /* notification */); - } - mLocalMediaManager.registerCallback(this); - mLocalMediaManager.startScan(); + ThreadUtils.postOnBackgroundThread(() -> { + final MediaController controller = getActiveLocalMediaController(); + if (controller == null) { + mPackageName = null; + } else { + mPackageName = controller.getPackageName(); + } + if (mLocalMediaManager == null || !TextUtils.equals(mPackageName, + mLocalMediaManager.getPackageName())) { + mLocalMediaManager = new LocalMediaManager(mContext, mPackageName, + null /* notification */); + } + mLocalMediaManager.registerCallback(this); + mLocalMediaManager.startScan(); + }); } @Override protected void onSliceUnpinned() { - mLocalMediaManager.unregisterCallback(this); - mLocalMediaManager.stopScan(); + if (mLocalMediaManager != null) { + mLocalMediaManager.unregisterCallback(this); + mLocalMediaManager.stopScan(); + } if (mLocalBluetoothManager == null) { Log.e(TAG, "Bluetooth is not supported on this device"); diff --git a/tests/robotests/src/com/android/settings/media/MediaOutputIndicatorWorkerTest.java b/tests/robotests/src/com/android/settings/media/MediaOutputIndicatorWorkerTest.java index dd3a2367780..0aec9529b3c 100644 --- a/tests/robotests/src/com/android/settings/media/MediaOutputIndicatorWorkerTest.java +++ b/tests/robotests/src/com/android/settings/media/MediaOutputIndicatorWorkerTest.java @@ -103,7 +103,13 @@ public class MediaOutputIndicatorWorkerTest { @Test public void onSlicePinned_registerCallback() { mMediaOutputIndicatorWorker.mLocalMediaManager = mLocalMediaManager; + initPlayback(); + when(mMediaController.getPlaybackInfo()).thenReturn(mPlaybackInfo); + when(mMediaController.getPlaybackState()).thenReturn(mPlaybackState); + when(mMediaController.getPackageName()).thenReturn(TEST_PACKAGE_NAME); + when(mLocalMediaManager.getPackageName()).thenReturn(TEST_PACKAGE_NAME); mMediaOutputIndicatorWorker.onSlicePinned(); + waitForLocalMediaManagerInit(); verify(mBluetoothEventManager).registerCallback(mMediaOutputIndicatorWorker); verify(mContext).registerReceiver(any(BroadcastReceiver.class), any(IntentFilter.class)); @@ -119,11 +125,14 @@ public class MediaOutputIndicatorWorkerTest { when(mMediaController.getPackageName()).thenReturn(TEST_PACKAGE_NAME); mMediaOutputIndicatorWorker.onSlicePinned(); + waitForLocalMediaManagerInit(); assertThat(mMediaOutputIndicatorWorker.mLocalMediaManager.getPackageName()).matches( TEST_PACKAGE_NAME); when(mMediaController.getPackageName()).thenReturn(TEST_PACKAGE_NAME2); + mMediaOutputIndicatorWorker.mLocalMediaManager = null; mMediaOutputIndicatorWorker.onSlicePinned(); + waitForLocalMediaManagerInit(); assertThat(mMediaOutputIndicatorWorker.mLocalMediaManager.getPackageName()).matches( TEST_PACKAGE_NAME2); @@ -134,14 +143,35 @@ public class MediaOutputIndicatorWorkerTest { mMediaControllers.clear(); mMediaOutputIndicatorWorker.onSlicePinned(); + waitForLocalMediaManagerInit(); assertThat(mMediaOutputIndicatorWorker.mLocalMediaManager.getPackageName()).isNull(); } + private void waitForLocalMediaManagerInit() { + for (int i = 0; i < 20; i++) { + if (mMediaOutputIndicatorWorker.mLocalMediaManager != null) { + return; + } + try { + Thread.sleep(50); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + } + @Test public void onSliceUnpinned_unRegisterCallback() { mMediaOutputIndicatorWorker.mLocalMediaManager = mLocalMediaManager; + initPlayback(); + when(mMediaController.getPlaybackInfo()).thenReturn(mPlaybackInfo); + when(mMediaController.getPlaybackState()).thenReturn(mPlaybackState); + when(mMediaController.getPackageName()).thenReturn(TEST_PACKAGE_NAME); + when(mLocalMediaManager.getPackageName()).thenReturn(TEST_PACKAGE_NAME); + mMediaOutputIndicatorWorker.onSlicePinned(); + waitForLocalMediaManagerInit(); mMediaOutputIndicatorWorker.onSliceUnpinned(); verify(mBluetoothEventManager).unregisterCallback(mMediaOutputIndicatorWorker); @@ -153,6 +183,7 @@ public class MediaOutputIndicatorWorkerTest { @Test public void onReceive_shouldNotifyChange() { mMediaOutputIndicatorWorker.onSlicePinned(); + waitForLocalMediaManagerInit(); // onSlicePinned will registerCallback() and get first callback. Callback triggers this at // the first time. verify(mResolver, times(1)).notifyChange(URI, null);