Merge "Refactor callbacks to avoid extra binder calls" into qt-dev

This commit is contained in:
Beth Thibodeau
2019-05-31 22:23:34 +00:00
committed by Android (Google) Code Review
2 changed files with 56 additions and 42 deletions

View File

@@ -18,6 +18,7 @@ package com.android.systemui.statusbar.notification.row.wrapper;
import static com.android.systemui.Dependency.MAIN_HANDLER; import static com.android.systemui.Dependency.MAIN_HANDLER;
import android.annotation.Nullable;
import android.app.Notification; import android.app.Notification;
import android.content.Context; import android.content.Context;
import android.content.res.ColorStateList; import android.content.res.ColorStateList;
@@ -28,7 +29,6 @@ import android.media.session.PlaybackState;
import android.metrics.LogMaker; import android.metrics.LogMaker;
import android.os.Handler; import android.os.Handler;
import android.text.format.DateUtils; import android.text.format.DateUtils;
import android.util.Log;
import android.view.LayoutInflater; import android.view.LayoutInflater;
import android.view.View; import android.view.View;
import android.view.ViewStub; import android.view.ViewStub;
@@ -52,7 +52,6 @@ import java.util.TimerTask;
*/ */
public class NotificationMediaTemplateViewWrapper extends NotificationTemplateViewWrapper { public class NotificationMediaTemplateViewWrapper extends NotificationTemplateViewWrapper {
private static final String TAG = "NotificationMediaTVW";
private static final long PROGRESS_UPDATE_INTERVAL = 1000; // 1s private static final long PROGRESS_UPDATE_INTERVAL = 1000; // 1s
private static final String COMPACT_MEDIA_TAG = "media"; private static final String COMPACT_MEDIA_TAG = "media";
private final Handler mHandler = Dependency.get(MAIN_HANDLER); private final Handler mHandler = Dependency.get(MAIN_HANDLER);
@@ -63,6 +62,7 @@ public class NotificationMediaTemplateViewWrapper extends NotificationTemplateVi
private TextView mSeekBarTotalTime; private TextView mSeekBarTotalTime;
private long mDuration = 0; private long mDuration = 0;
private MediaController mMediaController; private MediaController mMediaController;
private MediaMetadata mMediaMetadata;
private NotificationMediaManager mMediaManager; private NotificationMediaManager mMediaManager;
private View mSeekBarView; private View mSeekBarView;
private Context mContext; private Context mContext;
@@ -81,7 +81,7 @@ public class NotificationMediaTemplateViewWrapper extends NotificationTemplateVi
@Override @Override
public void onStopTrackingTouch(SeekBar seekBar) { public void onStopTrackingTouch(SeekBar seekBar) {
if (mMediaController != null && canSeekMedia()) { if (mMediaController != null) {
mMediaController.getTransportControls().seekTo(mSeekBar.getProgress()); mMediaController.getTransportControls().seekTo(mSeekBar.getProgress());
mMetricsLogger.write(newLog(MetricsEvent.TYPE_UPDATE)); mMetricsLogger.write(newLog(MetricsEvent.TYPE_UPDATE));
} }
@@ -96,16 +96,28 @@ public class NotificationMediaTemplateViewWrapper extends NotificationTemplateVi
} }
@Override @Override
public void onPlaybackStateChanged(PlaybackState state) { public void onPlaybackStateChanged(@Nullable PlaybackState state) {
if (state == null) {
return;
}
if (state.getState() != PlaybackState.STATE_PLAYING) { if (state.getState() != PlaybackState.STATE_PLAYING) {
// Update the UI once, in case playback info changed while we were paused // Update the UI once, in case playback info changed while we were paused
mUpdatePlaybackUi.run(); updatePlaybackUi(state);
clearTimer(); clearTimer();
} else if (mSeekBarTimer == null && mSeekBarView != null } else if (mSeekBarTimer == null && mSeekBarView != null
&& mSeekBarView.getVisibility() != View.GONE) { && mSeekBarView.getVisibility() != View.GONE) {
startTimer(); startTimer();
} }
} }
@Override
public void onMetadataChanged(@Nullable MediaMetadata metadata) {
if (mMediaMetadata == null || !mMediaMetadata.equals(metadata)) {
mMediaMetadata = metadata;
updateDuration();
}
}
}; };
protected NotificationMediaTemplateViewWrapper(Context ctx, View view, protected NotificationMediaTemplateViewWrapper(Context ctx, View view,
@@ -140,12 +152,11 @@ public class NotificationMediaTemplateViewWrapper extends NotificationTemplateVi
controllerUpdated = true; controllerUpdated = true;
} }
if (mMediaController.getMetadata() != null) { mMediaMetadata = mMediaController.getMetadata();
long duration = mMediaController.getMetadata().getLong( if (mMediaMetadata != null) {
MediaMetadata.METADATA_KEY_DURATION); long duration = mMediaMetadata.getLong(MediaMetadata.METADATA_KEY_DURATION);
if (duration <= 0) { if (duration <= 0) {
// Don't include the seekbar if this is a livestream // Don't include the seekbar if this is a livestream
Log.d(TAG, "removing seekbar");
if (mSeekBarView != null && mSeekBarView.getVisibility() != View.GONE) { if (mSeekBarView != null && mSeekBarView.getVisibility() != View.GONE) {
mSeekBarView.setVisibility(View.GONE); mSeekBarView.setVisibility(View.GONE);
mMetricsLogger.write(newLog(MetricsEvent.TYPE_CLOSE)); mMetricsLogger.write(newLog(MetricsEvent.TYPE_CLOSE));
@@ -156,12 +167,12 @@ public class NotificationMediaTemplateViewWrapper extends NotificationTemplateVi
mMetricsLogger.write(newLog(MetricsEvent.TYPE_CLOSE)); mMetricsLogger.write(newLog(MetricsEvent.TYPE_CLOSE));
} }
return; return;
} else { } else if (mSeekBarView != null && mSeekBarView.getVisibility() == View.GONE) {
// Otherwise, make sure the seekbar is visible // Otherwise, make sure the seekbar is visible
if (mSeekBarView != null && mSeekBarView.getVisibility() == View.GONE) { mSeekBarView.setVisibility(View.VISIBLE);
mSeekBarView.setVisibility(View.VISIBLE); mMetricsLogger.write(newLog(MetricsEvent.TYPE_OPEN));
mMetricsLogger.write(newLog(MetricsEvent.TYPE_OPEN)); updateDuration();
} startTimer();
} }
} }
@@ -181,13 +192,13 @@ public class NotificationMediaTemplateViewWrapper extends NotificationTemplateVi
mSeekBarTotalTime = mSeekBarView.findViewById(R.id.notification_media_total_time); mSeekBarTotalTime = mSeekBarView.findViewById(R.id.notification_media_total_time);
if (mSeekBarTimer == null) { if (mSeekBarTimer == null) {
if (canSeekMedia()) { if (mMediaController != null && canSeekMedia(mMediaController.getPlaybackState())) {
// Log initial state, since it will not be updated // Log initial state, since it will not be updated
mMetricsLogger.write(newLog(MetricsEvent.TYPE_DETAIL, 1)); mMetricsLogger.write(newLog(MetricsEvent.TYPE_DETAIL, 1));
} else { } else {
setScrubberVisible(false); setScrubberVisible(false);
} }
updateDuration();
startTimer(); startTimer();
mMediaController.registerCallback(mMediaCallback); mMediaController.registerCallback(mMediaCallback);
} }
@@ -201,7 +212,7 @@ public class NotificationMediaTemplateViewWrapper extends NotificationTemplateVi
mSeekBarTimer.schedule(new TimerTask() { mSeekBarTimer.schedule(new TimerTask() {
@Override @Override
public void run() { public void run() {
mHandler.post(mUpdatePlaybackUi); mHandler.post(mOnUpdateTimerTick);
} }
}, 0, PROGRESS_UPDATE_INTERVAL); }, 0, PROGRESS_UPDATE_INTERVAL);
} }
@@ -215,14 +226,12 @@ public class NotificationMediaTemplateViewWrapper extends NotificationTemplateVi
} }
} }
private boolean canSeekMedia() { private boolean canSeekMedia(@Nullable PlaybackState state) {
if (mMediaController == null || mMediaController.getPlaybackState() == null) { if (state == null) {
Log.d(TAG, "Cannot seek media because the controller is invalid");
return false; return false;
} }
long actions = mMediaController.getPlaybackState().getActions(); long actions = state.getActions();
Log.d(TAG, "Playback state actions are " + actions);
return ((actions & PlaybackState.ACTION_SEEK_TO) != 0); return ((actions & PlaybackState.ACTION_SEEK_TO) != 0);
} }
@@ -236,39 +245,44 @@ public class NotificationMediaTemplateViewWrapper extends NotificationTemplateVi
mMetricsLogger.write(newLog(MetricsEvent.TYPE_DETAIL, isVisible ? 1 : 0)); mMetricsLogger.write(newLog(MetricsEvent.TYPE_DETAIL, isVisible ? 1 : 0));
} }
protected final Runnable mUpdatePlaybackUi = new Runnable() { private void updateDuration() {
if (mMediaMetadata != null && mSeekBar != null) {
long duration = mMediaMetadata.getLong(MediaMetadata.METADATA_KEY_DURATION);
if (mDuration != duration) {
mDuration = duration;
mSeekBar.setMax((int) mDuration);
mSeekBarTotalTime.setText(millisecondsToTimeString(duration));
}
}
}
protected final Runnable mOnUpdateTimerTick = new Runnable() {
@Override @Override
public void run() { public void run() {
if (mMediaController != null && mSeekBar != null) { if (mMediaController != null && mSeekBar != null) {
MediaMetadata metadata = mMediaController.getMetadata();
PlaybackState playbackState = mMediaController.getPlaybackState(); PlaybackState playbackState = mMediaController.getPlaybackState();
if (metadata != null && playbackState != null) { if (playbackState != null) {
long position = playbackState.getPosition(); updatePlaybackUi(playbackState);
long duration = metadata.getLong(MediaMetadata.METADATA_KEY_DURATION);
if (mDuration != duration) {
mDuration = duration;
mSeekBar.setMax((int) mDuration);
mSeekBarTotalTime.setText(millisecondsToTimeString(duration));
}
mSeekBar.setProgress((int) position);
mSeekBarElapsedTime.setText(millisecondsToTimeString(position));
// Update scrubber in case available actions have changed
setScrubberVisible(canSeekMedia());
} else { } else {
Log.d(TAG, "Controller missing data " + metadata + " " + playbackState);
clearTimer(); clearTimer();
} }
} else { } else {
Log.d(TAG, "No longer have a valid media controller");
clearTimer(); clearTimer();
} }
} }
}; };
private void updatePlaybackUi(PlaybackState state) {
long position = state.getPosition();
mSeekBar.setProgress((int) position);
mSeekBarElapsedTime.setText(millisecondsToTimeString(position));
// Update scrubber in case available actions have changed
setScrubberVisible(canSeekMedia(state));
}
private String millisecondsToTimeString(long milliseconds) { private String millisecondsToTimeString(long milliseconds) {
long seconds = milliseconds / 1000; long seconds = milliseconds / 1000;
String text = DateUtils.formatElapsedTime(seconds); String text = DateUtils.formatElapsedTime(seconds);

View File

@@ -131,7 +131,7 @@ public class NotificationMediaTemplateViewWrapperTest extends SysuiTestCase {
)); ));
// Ensure the callback runs at least once // Ensure the callback runs at least once
mWrapper.mUpdatePlaybackUi.run(); mWrapper.mOnUpdateTimerTick.run();
verify(mMetricsLogger).write(argThat(logMaker -> verify(mMetricsLogger).write(argThat(logMaker ->
logMaker.getCategory() == MetricsEvent.MEDIA_NOTIFICATION_SEEKBAR logMaker.getCategory() == MetricsEvent.MEDIA_NOTIFICATION_SEEKBAR