diff --git a/src/com/android/settings/panel/MediaOutputGroupPanel.java b/src/com/android/settings/panel/MediaOutputGroupPanel.java index 4a37c520824..d98c0b101e0 100644 --- a/src/com/android/settings/panel/MediaOutputGroupPanel.java +++ b/src/com/android/settings/panel/MediaOutputGroupPanel.java @@ -148,7 +148,7 @@ public class MediaOutputGroupPanel implements PanelContent, LocalMediaManager.De @Override public void onDeviceListUpdate(List devices) { if (mCallback != null) { - mCallback.onGroupChanged(); + mCallback.onHeaderChanged(); } } diff --git a/src/com/android/settings/panel/MediaOutputPanel.java b/src/com/android/settings/panel/MediaOutputPanel.java index 1145c428b2f..2a9669af93f 100644 --- a/src/com/android/settings/panel/MediaOutputPanel.java +++ b/src/com/android/settings/panel/MediaOutputPanel.java @@ -82,20 +82,6 @@ public class MediaOutputPanel implements PanelContent, LocalMediaManager.DeviceC private MediaOutputPanel(Context context, String packageName) { mContext = context.getApplicationContext(); mPackageName = TextUtils.isEmpty(packageName) ? "" : packageName; - - if (!TextUtils.isEmpty(mPackageName)) { - mMediaSessionManager = mContext.getSystemService(MediaSessionManager.class); - for (MediaController controller : mMediaSessionManager.getActiveSessions(null)) { - if (TextUtils.equals(controller.getPackageName(), mPackageName)) { - mMediaController = controller; - break; - } - } - } - - if (mMediaController == null) { - Log.e(TAG, "Unable to find " + mPackageName + " media controller"); - } } @Override @@ -228,6 +214,19 @@ public class MediaOutputPanel implements PanelContent, LocalMediaManager.DeviceC @OnLifecycleEvent(ON_START) public void onStart() { + if (!TextUtils.isEmpty(mPackageName)) { + mMediaSessionManager = mContext.getSystemService(MediaSessionManager.class); + for (MediaController controller : mMediaSessionManager.getActiveSessions(null)) { + if (TextUtils.equals(controller.getPackageName(), mPackageName)) { + mMediaController = controller; + mMediaController.registerCallback(mCb); + break; + } + } + } + if (mMediaController == null) { + Log.d(TAG, "No media controller for " + mPackageName); + } if (mLocalMediaManager == null) { mLocalMediaManager = new LocalMediaManager(mContext, mPackageName, null); } @@ -237,6 +236,9 @@ public class MediaOutputPanel implements PanelContent, LocalMediaManager.DeviceC @OnLifecycleEvent(ON_STOP) public void onStop() { + if (mMediaController != null) { + mMediaController.unregisterCallback(mCb); + } mLocalMediaManager.unregisterCallback(this); mLocalMediaManager.stopScan(); } @@ -245,4 +247,13 @@ public class MediaOutputPanel implements PanelContent, LocalMediaManager.DeviceC public int getViewType() { return PanelContent.VIEW_TYPE_SLIDER; } + + private final MediaController.Callback mCb = new MediaController.Callback() { + @Override + public void onMetadataChanged(MediaMetadata metadata) { + if (mCallback != null) { + mCallback.onHeaderChanged(); + } + } + }; } diff --git a/src/com/android/settings/panel/PanelContentCallback.java b/src/com/android/settings/panel/PanelContentCallback.java index ce8ea223379..989082f9c56 100644 --- a/src/com/android/settings/panel/PanelContentCallback.java +++ b/src/com/android/settings/panel/PanelContentCallback.java @@ -28,8 +28,8 @@ public interface PanelContentCallback { void onCustomizedButtonStateChanged(); /** - * It will be called when group content is changed. For example, to add/remove a device into + * It will be called when header content is changed. For example, to add/remove a device into * a group */ - void onGroupChanged(); + void onHeaderChanged(); } diff --git a/src/com/android/settings/panel/PanelFragment.java b/src/com/android/settings/panel/PanelFragment.java index 30cc2a8dd6a..ed5c7551171 100644 --- a/src/com/android/settings/panel/PanelFragment.java +++ b/src/com/android/settings/panel/PanelFragment.java @@ -426,8 +426,10 @@ public class PanelFragment extends Fragment { } @Override - public void onGroupChanged() { + public void onHeaderChanged() { ThreadUtils.postOnMainThread(() -> { + mTitleIcon.setImageIcon(mPanel.getIcon().toIcon(getContext())); + mHeaderTitle.setText(mPanel.getTitle()); mHeaderSubtitle.setText(mPanel.getSubTitle()); }); } diff --git a/tests/robotests/src/com/android/settings/panel/FakePanelContent.java b/tests/robotests/src/com/android/settings/panel/FakePanelContent.java index 4d91f52444d..bf2ac0dcb8f 100644 --- a/tests/robotests/src/com/android/settings/panel/FakePanelContent.java +++ b/tests/robotests/src/com/android/settings/panel/FakePanelContent.java @@ -42,6 +42,7 @@ public class FakePanelContent implements PanelContent { public static final Intent INTENT = new Intent(); + private CharSequence mTitle = TITLE; private CharSequence mSubTitle; private IconCompat mIcon; private int mViewType; @@ -51,22 +52,26 @@ public class FakePanelContent implements PanelContent { return mIcon; } + public void setIcon(IconCompat icon) { + mIcon = icon; + } + @Override public CharSequence getSubTitle() { return mSubTitle; } - public void setIcon(IconCompat icon) { - mIcon = icon; - } - public void setSubTitle(CharSequence subTitle) { mSubTitle = subTitle; } @Override public CharSequence getTitle() { - return TITLE; + return mTitle; + } + + public void setTitle(CharSequence title) { + mTitle = title; } @Override diff --git a/tests/robotests/src/com/android/settings/panel/MediaOutputPanelTest.java b/tests/robotests/src/com/android/settings/panel/MediaOutputPanelTest.java index b95c9d0701c..07f01fce1b1 100644 --- a/tests/robotests/src/com/android/settings/panel/MediaOutputPanelTest.java +++ b/tests/robotests/src/com/android/settings/panel/MediaOutputPanelTest.java @@ -41,6 +41,7 @@ import com.android.settingslib.media.PhoneMediaDevice; 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; @@ -62,7 +63,6 @@ public class MediaOutputPanelTest { private MediaController mMediaController; @Mock private MediaMetadata mMediaMetadata; - @Mock private LocalMediaManager mLocalMediaManager; @Mock @@ -71,6 +71,8 @@ public class MediaOutputPanelTest { private MediaOutputPanel mPanel; private Context mContext; private List mMediaControllers = new ArrayList<>(); + private ArgumentCaptor mControllerCbs = + ArgumentCaptor.forClass(MediaController.Callback.class); @Before public void setUp() { @@ -112,6 +114,7 @@ public class MediaOutputPanelTest { public void onStart_shouldRegisterCallback() { mPanel.onStart(); + verify(mMediaController).registerCallback(any()); verify(mLocalMediaManager).registerCallback(any()); verify(mLocalMediaManager).startScan(); } @@ -167,6 +170,7 @@ public class MediaOutputPanelTest { @Test public void getTitle_withMetadata_returnArtistName() { + mPanel.onStart(); when(mMediaMetadata.getString(MediaMetadata.METADATA_KEY_ARTIST)).thenReturn(TEST_ARTIST); when(mMediaController.getMetadata()).thenReturn(mMediaMetadata); @@ -201,6 +205,7 @@ public class MediaOutputPanelTest { @Test public void getSubTitle_withMetadata_returnAlbumName() { + mPanel.onStart(); when(mMediaMetadata.getString(MediaMetadata.METADATA_KEY_ALBUM)).thenReturn(TEST_ALBUM); when(mMediaController.getMetadata()).thenReturn(mMediaMetadata); @@ -243,4 +248,15 @@ public class MediaOutputPanelTest { verify(mLocalMediaManager).releaseSession(); } + + @Test + public void onMetadataChanged_verifyCallOnHeaderChanged() { + mPanel.onStart(); + verify(mMediaController).registerCallback(mControllerCbs.capture()); + final MediaController.Callback controllerCallbacks = mControllerCbs.getValue(); + + controllerCallbacks.onMetadataChanged(mMediaMetadata); + + verify(mCallback).onHeaderChanged(); + } } diff --git a/tests/robotests/src/com/android/settings/panel/PanelFragmentTest.java b/tests/robotests/src/com/android/settings/panel/PanelFragmentTest.java index 1976557c0a4..07ca48b93ca 100644 --- a/tests/robotests/src/com/android/settings/panel/PanelFragmentTest.java +++ b/tests/robotests/src/com/android/settings/panel/PanelFragmentTest.java @@ -41,6 +41,7 @@ import com.android.settings.testutils.FakeFeatureFactory; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; +import org.mockito.ArgumentCaptor; import org.robolectric.Robolectric; import org.robolectric.RobolectricTestRunner; import org.robolectric.RuntimeEnvironment; @@ -51,7 +52,10 @@ import java.util.Objects; @RunWith(RobolectricTestRunner.class) public class PanelFragmentTest { + private static final String TITLE = "title"; + private static final String TITLE2 = "title2"; private static final String SUBTITLE = "subtitle"; + private static final String SUBTITLE2 = "subtitle2"; private Context mContext; private PanelFragment mPanelFragment; @@ -59,6 +63,8 @@ public class PanelFragmentTest { private FakeFeatureFactory mFakeFeatureFactory; private PanelFeatureProvider mPanelFeatureProvider; private FakePanelContent mFakePanelContent; + private ArgumentCaptor mPanelContentCbs = ArgumentCaptor.forClass( + PanelContentCallback.class); private final String FAKE_EXTRA = "fake_extra"; @@ -69,9 +75,11 @@ public class PanelFragmentTest { mPanelFeatureProvider = spy(new PanelFeatureProviderImpl()); mFakeFeatureFactory = FakeFeatureFactory.setupForTest(); mFakeFeatureFactory.panelFeatureProvider = mPanelFeatureProvider; - mFakePanelContent = new FakePanelContent(); + mFakePanelContent = spy(new FakePanelContent()); doReturn(mFakePanelContent).when(mPanelFeatureProvider).getPanel(any(), any()); + } + private void initFakeActivity() { mActivity = spy(Robolectric.buildActivity(FakeSettingsPanelActivity.class).setup().get()); mPanelFragment = @@ -86,6 +94,7 @@ public class PanelFragmentTest { @Test public void onCreateView_countdownLatch_setup() { + initFakeActivity(); mPanelFragment.onCreateView(LayoutInflater.from(mContext), new LinearLayout(mContext), null); PanelSlicesLoaderCountdownLatch countdownLatch = @@ -99,6 +108,7 @@ public class PanelFragmentTest { @Test public void onCreate_logsOpenEvent() { + initFakeActivity(); verify(mFakeFeatureFactory.metricsFeatureProvider).action( 0, SettingsEnums.PAGE_VISIBLE, @@ -109,6 +119,7 @@ public class PanelFragmentTest { @Test public void onDestroy_logCloseEvent() { + initFakeActivity(); mPanelFragment.onDestroyView(); verify(mFakeFeatureFactory.metricsFeatureProvider).action( 0, @@ -120,6 +131,7 @@ public class PanelFragmentTest { @Test public void panelSeeMoreClick_logsCloseEvent() { + initFakeActivity(); final View.OnClickListener listener = mPanelFragment.getSeeMoreListener(); listener.onClick(null); verify(mActivity).finish(); @@ -136,6 +148,7 @@ public class PanelFragmentTest { @Test public void panelDoneClick_logsCloseEvent() { + initFakeActivity(); final View.OnClickListener listener = mPanelFragment.getCloseListener(); listener.onClick(null); verify(mActivity).finish(); @@ -178,10 +191,49 @@ public class PanelFragmentTest { @Test public void notSupportIcon_displayDefaultHeaderLayout() { - final View titleView = mPanelFragment.mLayoutView.findViewById(R.id.panel_title); - final View panelHeader = mPanelFragment.mLayoutView.findViewById(R.id.panel_header); + final ActivityController activityController = + Robolectric.buildActivity(FakeSettingsPanelActivity.class); + activityController.setup(); + final PanelFragment panelFragment = (PanelFragment) + Objects.requireNonNull(activityController + .get() + .getSupportFragmentManager() + .findFragmentById(R.id.main_content)); + + final View titleView = panelFragment.mLayoutView.findViewById(R.id.panel_title); + final View panelHeader = panelFragment.mLayoutView.findViewById(R.id.panel_header); assertThat(panelHeader.getVisibility()).isEqualTo(View.GONE); assertThat(titleView.getVisibility()).isEqualTo(View.VISIBLE); } + + @Test + public void onHeaderChanged_updateHeader_verifyTitle() { + mFakePanelContent.setIcon(IconCompat.createWithResource(mContext, R.drawable.ic_android)); + mFakePanelContent.setTitle(TITLE); + mFakePanelContent.setSubTitle(SUBTITLE); + final ActivityController activityController = + Robolectric.buildActivity(FakeSettingsPanelActivity.class); + activityController.setup(); + final PanelFragment panelFragment = (PanelFragment) + Objects.requireNonNull(activityController + .get() + .getSupportFragmentManager() + .findFragmentById(R.id.main_content)); + final TextView headerTitle = panelFragment.mLayoutView.findViewById(R.id.header_title); + final TextView headerSubtitle = panelFragment.mLayoutView.findViewById( + R.id.header_subtitle); + + assertThat(headerTitle.getText()).isEqualTo(TITLE); + assertThat(headerSubtitle.getText()).isEqualTo(SUBTITLE); + + mFakePanelContent.setTitle(TITLE2); + mFakePanelContent.setSubTitle(SUBTITLE2); + verify(mFakePanelContent).registerCallback(mPanelContentCbs.capture()); + final PanelContentCallback panelContentCallbacks = mPanelContentCbs.getValue(); + panelContentCallbacks.onHeaderChanged(); + + assertThat(headerTitle.getText()).isEqualTo(TITLE2); + assertThat(headerSubtitle.getText()).isEqualTo(SUBTITLE2); + } } \ No newline at end of file