diff options
author | Jaewan Kim <jaewan@google.com> | 2018-09-19 10:37:13 +0000 |
---|---|---|
committer | Gerrit Code Review <noreply-gerritcodereview@google.com> | 2018-09-19 10:37:13 +0000 |
commit | bffb87a61df97a7d837205b9ce54ff60b11d309a (patch) | |
tree | b4196865d0d4c7ee8a61291488f8619856796e40 /mediarouter | |
parent | 7b8790804b485d42b9a96708c33f2f2e7a5c664e (diff) | |
parent | 96460493f3953cfcd75cf0ee173c46cc0adc51d6 (diff) | |
download | support-bffb87a61df97a7d837205b9ce54ff60b11d309a.tar.gz |
Merge "MediaRouteCastDialog: Revisit UI update logic" into androidx-master-dev
Diffstat (limited to 'mediarouter')
-rw-r--r-- | mediarouter/src/main/java/androidx/mediarouter/app/MediaRouteCastDialog.java | 200 |
1 files changed, 117 insertions, 83 deletions
diff --git a/mediarouter/src/main/java/androidx/mediarouter/app/MediaRouteCastDialog.java b/mediarouter/src/main/java/androidx/mediarouter/app/MediaRouteCastDialog.java index d2a1ade4332..3ff6d2b9fa1 100644 --- a/mediarouter/src/main/java/androidx/mediarouter/app/MediaRouteCastDialog.java +++ b/mediarouter/src/main/java/androidx/mediarouter/app/MediaRouteCastDialog.java @@ -101,12 +101,12 @@ public class MediaRouteCastDialog extends AppCompatDialog { static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG); // Do not update the route list immediately to avoid unnatural dialog change. - private static final int UPDATE_ROUTES_DELAY_MS = 300; + private static final int UPDATE_ROUTES_VIEW_DELAY_MS = 300; private static final int CONNECTION_TIMEOUT_MS = 30000; private static final int UPDATE_VOLUME_DELAY_MS = 500; private static final int PROGRESS_BAR_DISPLAY_MS = 400; - static final int MSG_UPDATE_ROUTES = 1; + static final int MSG_UPDATE_ROUTES_VIEW = 1; static final int MSG_UPDATE_ROUTE_VOLUME_BY_USER = 2; // TODO (b/111731099): Remove this once dark theme is implemented inside MediaRouterThemeHelper. @@ -132,22 +132,23 @@ public class MediaRouteCastDialog extends AppCompatDialog { @Override public void handleMessage(Message message) { switch (message.what) { - case MSG_UPDATE_ROUTES: - updateRoutes((List<MediaRouter.RouteInfo>) message.obj); + case MSG_UPDATE_ROUTES_VIEW: + updateRoutesView(); break; case MSG_UPDATE_ROUTE_VOLUME_BY_USER: if (mRouteForVolumeUpdatingByUser != null) { mRouteForVolumeUpdatingByUser = null; - if (mHasPendingUpdate) { - update(); - } + // Since updates of views are deferred when the volume is being updated, + // call updateViewsIfNeeded to ensure that views are updated properly. + updateViewsIfNeeded(); } break; } } }; private RecyclerView mRecyclerView; - private RecyclerAdapter mAdapter; + @SuppressWarnings("WeakerAccess") /* synthetic access */ + RecyclerAdapter mAdapter; VolumeChangeListener mVolumeChangeListener; int mVolumeSliderColor; @@ -158,9 +159,11 @@ public class MediaRouteCastDialog extends AppCompatDialog { @SuppressWarnings("WeakerAccess") /* synthetic access */ MediaRouter.RouteInfo mRouteForVolumeUpdatingByUser; @SuppressWarnings("WeakerAccess") /* synthetic access */ - boolean mHasPendingUpdate; boolean mIsSelectingRoute; + private boolean mUpdateRoutesViewDeferred; + private boolean mUpdateMetadataViewsDeferred; + private ImageButton mCloseButton; private Button mStopCastingButton; @@ -228,7 +231,7 @@ public class MediaRouteCastDialog extends AppCompatDialog { : mMediaController.getMetadata(); mDescription = metadata == null ? null : metadata.getDescription(); updateArtIconIfNeeded(); - update(); + updateMetadataViews(); } /** @@ -267,8 +270,8 @@ public class MediaRouteCastDialog extends AppCompatDialog { mRouter.removeCallback(mCallback); mRouter.addCallback(selector, mCallback, MediaRouter.CALLBACK_FLAG_PERFORM_ACTIVE_SCAN); + updateRoutes(); } - refreshRoutes(); } } @@ -365,7 +368,8 @@ public class MediaRouteCastDialog extends AppCompatDialog { mArtIconBitmap = null; mArtIconUri = null; updateArtIconIfNeeded(); - update(); + updateMetadataViews(); + updateRoutesView(); } @Override @@ -374,7 +378,7 @@ public class MediaRouteCastDialog extends AppCompatDialog { mAttachedToWindow = true; mRouter.addCallback(mSelector, mCallback, MediaRouter.CALLBACK_FLAG_PERFORM_ACTIVE_SCAN); - refreshRoutes(); + updateRoutes(); setMediaSession(mRouter.getMediaSessionToken()); } @@ -384,56 +388,10 @@ public class MediaRouteCastDialog extends AppCompatDialog { mAttachedToWindow = false; mRouter.removeCallback(mCallback); - mHandler.removeMessages(MSG_UPDATE_ROUTES); + mHandler.removeCallbacksAndMessages(null); setMediaSession(null); } - void update() { - // Defer dialog updates when user is adjusting volume or selecting route. - // Since onRouteUnselected is triggered before onRouteSelected when transferring to another - // route, pending update if mIsSelectingRoute is true to prevent dialog from being dismissed - // in the process of selecting route. - if (mRouteForVolumeUpdatingByUser != null || mIsSelectingRoute) { - mHasPendingUpdate = true; - return; - } - mHasPendingUpdate = false; - if (!mSelectedRoute.isSelected() || mSelectedRoute.isDefaultOrBluetooth()) { - dismiss(); - return; - } - if (!mCreated) { - return; - } - - if (mArtIconIsLoaded && !isBitmapRecycled(mArtIconLoadedBitmap) - && mArtIconLoadedBitmap != null) { - mArtView.setVisibility(View.VISIBLE); - mArtView.setImageBitmap(mArtIconLoadedBitmap); - mArtView.setBackgroundColor(mArtIconBackgroundColor); - - // Blur will not be supported for SDK < 17 devices to avoid unnecessarily bloating - // the size of this package (approximately two-fold). Instead, only the black scrim - // will be placed on top of the metadata background. - mMetadataBlackScrim.setVisibility(View.VISIBLE); - if (Build.VERSION.SDK_INT >= 17) { - Bitmap blurredBitmap = blurBitmap(mArtIconLoadedBitmap, BLUR_RADIUS, mContext); - mMetadataBackground.setImageBitmap(blurredBitmap); - } else { - mMetadataBackground.setImageBitmap(Bitmap.createBitmap(mArtIconLoadedBitmap)); - } - } else { - if (isBitmapRecycled(mArtIconLoadedBitmap)) { - Log.w(TAG, "Can't set artwork image with recycled bitmap: " + mArtIconLoadedBitmap); - } - mArtView.setVisibility(View.GONE); - mMetadataBlackScrim.setVisibility(View.GONE); - mMetadataBackground.setImageBitmap(null); - } - clearLoadedBitmap(); - updateMetadataLayout(); - } - @SuppressWarnings("WeakerAccess") /* synthetic access */ static boolean isBitmapRecycled(Bitmap bitmap) { return bitmap != null && bitmap.isRecycled(); @@ -483,7 +441,73 @@ public class MediaRouteCastDialog extends AppCompatDialog { return false; } - private void updateMetadataLayout() { + /** + * Returns whether updateMetadataViews and updateRoutesView should defer updating views. + */ + private boolean shouldDeferUpdateViews() { + // Defer updating views when user is adjusting volume or selecting route. + // Since onRouteUnselected is triggered before onRouteSelected when transferring to + // another route, pending update if mIsSelectingRoute is true to prevent dialog from + // being dismissed in the process of selecting route. + if (mRouteForVolumeUpdatingByUser != null || mIsSelectingRoute) { + return true; + } + // Defer updating views if corresponding views aren't created yet. + if (!mCreated) { + return true; + } + return false; + } + + @SuppressWarnings("WeakerAccess") /* synthetic access */ + void updateViewsIfNeeded() { + // Call updateRoutesView if update of routes view is deferred. + if (mUpdateRoutesViewDeferred) { + updateRoutesView(); + } + // Call updateMetadataViews if update of metadata views are deferred. + if (mUpdateMetadataViewsDeferred) { + updateMetadataViews(); + } + } + + @SuppressWarnings("WeakerAccess") /* synthetic access */ + void updateMetadataViews() { + if (shouldDeferUpdateViews()) { + mUpdateMetadataViewsDeferred = true; + return; + } + mUpdateMetadataViewsDeferred = false; + // Dismiss dialog if there's no non-default selected route. + if (!mSelectedRoute.isSelected() || mSelectedRoute.isDefaultOrBluetooth()) { + dismiss(); + } + if (mArtIconIsLoaded && !isBitmapRecycled(mArtIconLoadedBitmap) + && mArtIconLoadedBitmap != null) { + mArtView.setVisibility(View.VISIBLE); + mArtView.setImageBitmap(mArtIconLoadedBitmap); + mArtView.setBackgroundColor(mArtIconBackgroundColor); + + // Blur will not be supported for SDK < 17 devices to avoid unnecessarily bloating + // the size of this package (approximately two-fold). Instead, only the black scrim + // will be placed on top of the metadata background. + mMetadataBlackScrim.setVisibility(View.VISIBLE); + if (Build.VERSION.SDK_INT >= 17) { + Bitmap blurredBitmap = blurBitmap(mArtIconLoadedBitmap, BLUR_RADIUS, mContext); + mMetadataBackground.setImageBitmap(blurredBitmap); + } else { + mMetadataBackground.setImageBitmap(Bitmap.createBitmap(mArtIconLoadedBitmap)); + } + } else { + if (isBitmapRecycled(mArtIconLoadedBitmap)) { + Log.w(TAG, "Can't set artwork image with recycled bitmap: " + mArtIconLoadedBitmap); + } + mArtView.setVisibility(View.GONE); + mMetadataBlackScrim.setVisibility(View.GONE); + mMetadataBackground.setImageBitmap(null); + } + clearLoadedBitmap(); + CharSequence title = mDescription == null ? null : mDescription.getTitle(); boolean hasTitle = !TextUtils.isEmpty(title); @@ -545,25 +569,35 @@ public class MediaRouteCastDialog extends AppCompatDialog { } /** - * Refreshes the list of routes that are shown in the chooser dialog. + * Updates the routes view that are shown in the cast dialog. */ - public void refreshRoutes() { + @SuppressWarnings("WeakerAccess") /* synthetic access */ + void updateRoutesView() { if (mAttachedToWindow) { - ArrayList<MediaRouter.RouteInfo> routes = new ArrayList<>(mRouter.getRoutes()); - onFilterRoutes(routes); - Collections.sort(routes, MediaRouteChooserDialog.RouteComparator.sInstance); - if (SystemClock.uptimeMillis() - mLastUpdateTime >= UPDATE_ROUTES_DELAY_MS) { - updateRoutes(routes); + if (SystemClock.uptimeMillis() - mLastUpdateTime >= UPDATE_ROUTES_VIEW_DELAY_MS) { + if (shouldDeferUpdateViews()) { + mUpdateRoutesViewDeferred = true; + return; + } + mUpdateRoutesViewDeferred = false; + // Dismiss dialog if there's no non-default selected route. + if (!mSelectedRoute.isSelected() || mSelectedRoute.isDefaultOrBluetooth()) { + dismiss(); + } + mLastUpdateTime = SystemClock.uptimeMillis(); + mAdapter.notifyDataSetChanged(); } else { - mHandler.removeMessages(MSG_UPDATE_ROUTES); - mHandler.sendMessageAtTime(mHandler.obtainMessage(MSG_UPDATE_ROUTES, routes), - mLastUpdateTime + UPDATE_ROUTES_DELAY_MS); + mHandler.removeMessages(MSG_UPDATE_ROUTES_VIEW); + mHandler.sendEmptyMessageAtTime(MSG_UPDATE_ROUTES_VIEW, + mLastUpdateTime + UPDATE_ROUTES_VIEW_DELAY_MS); } } } - void updateRoutes(List<MediaRouter.RouteInfo> routes) { - mLastUpdateTime = SystemClock.uptimeMillis(); + void updateRoutes() { + ArrayList<MediaRouter.RouteInfo> routes = new ArrayList<>(mRouter.getRoutes()); + onFilterRoutes(routes); + Collections.sort(routes, MediaRouteChooserDialog.RouteComparator.sInstance); mRoutes.clear(); mRoutes.addAll(routes); mAdapter.setItems(); @@ -1063,32 +1097,32 @@ public class MediaRouteCastDialog extends AppCompatDialog { @Override public void onRouteAdded(MediaRouter router, MediaRouter.RouteInfo info) { - refreshRoutes(); + updateRoutesView(); } @Override public void onRouteRemoved(MediaRouter router, MediaRouter.RouteInfo info) { - refreshRoutes(); + updateRoutesView(); } @Override public void onRouteSelected(MediaRouter router, MediaRouter.RouteInfo route) { mSelectedRoute = route; mIsSelectingRoute = false; - update(); + // Since updates of views are deferred when selecting the route, + // call updateViewsIfNeeded to ensure that views are updated properly. + updateViewsIfNeeded(); + updateRoutes(); } @Override public void onRouteUnselected(MediaRouter router, MediaRouter.RouteInfo route) { - update(); + updateRoutesView(); } @Override public void onRouteChanged(MediaRouter router, MediaRouter.RouteInfo route) { - // Call refreshRoutes only when there's no route for volume updating by user. - if (mRouteForVolumeUpdatingByUser == null) { - refreshRoutes(); - } + updateRoutesView(); } @Override @@ -1122,7 +1156,7 @@ public class MediaRouteCastDialog extends AppCompatDialog { public void onMetadataChanged(MediaMetadataCompat metadata) { mDescription = metadata == null ? null : metadata.getDescription(); updateArtIconIfNeeded(); - update(); + updateMetadataViews(); } } @@ -1228,7 +1262,7 @@ public class MediaRouteCastDialog extends AppCompatDialog { mArtIconBackgroundColor = mBackgroundColor; mArtIconIsLoaded = true; // Loaded bitmap will be applied on the next update - update(); + updateMetadataViews(); } } |