Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(45)

Side by Side Diff: third_party/android_media/java/src/org/chromium/third_party/android/media/MediaController.java

Issue 2888653002: [Cast,Android] Replace custom MediaController with android.widget.MediaController. (Closed)
Patch Set: Dedented the color in the xml file. Created 3 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « third_party/android_media/java/res/values/colors.xml ('k') | tools/android/eclipse/.classpath » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 /*
2 * Copyright (C) 2013 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 package org.chromium.third_party.android.media;
18
19 import android.content.Context;
20 import android.support.v4.media.TransportController;
21 import android.support.v4.media.TransportMediator;
22 import android.support.v4.media.TransportStateListener;
23 import android.util.AttributeSet;
24 import android.view.LayoutInflater;
25 import android.view.View;
26 import android.view.ViewGroup;
27 import android.view.accessibility.AccessibilityEvent;
28 import android.view.accessibility.AccessibilityNodeInfo;
29 import android.widget.FrameLayout;
30 import android.widget.ImageButton;
31 import android.widget.SeekBar;
32 import android.widget.TextView;
33
34 import org.chromium.third_party.android.media.R;
35
36 import java.util.Formatter;
37 import java.util.Locale;
38
39 /**
40 * Helper for implementing media controls in an application.
41 * We use this custom version instead of {@link android.widget.MediaController} so that we can
42 * customize the look as we want. This file is taken directly from the public An droid sample for
43 * supportv4, with tiny bug fixes.
44 */
45 public class MediaController extends FrameLayout {
46
47 private TransportController mController;
48 private Context mContext;
49 private ViewGroup mProgressGroup;
50 private SeekBar mProgressBar;
51 private TextView mEndTime, mCurrentTime;
52 private boolean mDragging;
53 private boolean mUseFastForward;
54 private boolean mListenersSet;
55 private boolean mShowNext, mShowPrev;
56 private View.OnClickListener mNextListener, mPrevListener;
57 private StringBuilder mFormatBuilder;
58 private Formatter mFormatter;
59 private ImageButton mPauseButton;
60 private ImageButton mFfwdButton;
61 private ImageButton mRewButton;
62 private ImageButton mNextButton;
63 private ImageButton mPrevButton;
64
65 private TransportStateListener mStateListener = new TransportStateListener() {
66 @Override
67 public void onPlayingChanged(TransportController controller) {
68 updatePausePlay();
69 }
70 @Override
71 public void onTransportControlsChanged(TransportController controller) {
72 updateButtons();
73 }
74 };
75
76 public MediaController(Context context, AttributeSet attrs) {
77 super(context, attrs);
78 mContext = context;
79 mUseFastForward = true;
80 LayoutInflater inflate = (LayoutInflater)
81 mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
82 inflate.inflate(R.layout.media_controller, this, true);
83 initControllerView();
84 }
85
86 public MediaController(Context context, boolean useFastForward) {
87 super(context);
88 mContext = context;
89 mUseFastForward = useFastForward;
90 }
91
92 public MediaController(Context context) {
93 this(context, true);
94 }
95
96 public void setMediaPlayer(TransportController controller) {
97 if (getWindowToken() != null) {
98 if (mController != null) {
99 mController.unregisterStateListener(mStateListener);
100 }
101 if (controller != null) {
102 controller.registerStateListener(mStateListener);
103 }
104 }
105 mController = controller;
106 updatePausePlay();
107 }
108
109 @Override
110 protected void onAttachedToWindow() {
111 super.onAttachedToWindow();
112 if (mController != null) {
113 mController.registerStateListener(mStateListener);
114 }
115 }
116
117 @Override
118 protected void onDetachedFromWindow() {
119 super.onDetachedFromWindow();
120 if (mController != null) {
121 mController.unregisterStateListener(mStateListener);
122 }
123 }
124
125 private void initControllerView() {
126 mPauseButton = (ImageButton) findViewById(R.id.pause);
127 if (mPauseButton != null) {
128 mPauseButton.requestFocus();
129 mPauseButton.setOnClickListener(mPauseListener);
130 }
131
132 mFfwdButton = (ImageButton) findViewById(R.id.ffwd);
133 if (mFfwdButton != null) {
134 mFfwdButton.setOnClickListener(mFfwdListener);
135 mFfwdButton.setVisibility(mUseFastForward ? View.VISIBLE : View.GONE );
136 }
137
138 mRewButton = (ImageButton) findViewById(R.id.rew);
139 if (mRewButton != null) {
140 mRewButton.setOnClickListener(mRewListener);
141 mRewButton.setVisibility(mUseFastForward ? View.VISIBLE : View.GONE) ;
142 }
143
144 // By default these are hidden. They will be enabled when setPrevNextLis teners() is called
145 mNextButton = (ImageButton) findViewById(R.id.next);
146 if (mNextButton != null && !mListenersSet) {
147 mNextButton.setVisibility(View.GONE);
148 }
149 mPrevButton = (ImageButton) findViewById(R.id.prev);
150 if (mPrevButton != null && !mListenersSet) {
151 mPrevButton.setVisibility(View.GONE);
152 }
153
154 mProgressGroup = (ViewGroup) findViewById(R.id.mediacontroller_progress_ container);
155
156 if (mProgressGroup != null) {
157 mProgressBar = (SeekBar) mProgressGroup.findViewById(R.id.mediacontr oller_progress_bar);
158 if (mProgressBar != null) {
159 mProgressBar.setOnSeekBarChangeListener(mSeekListener);
160 mProgressBar.setMax(1000);
161 }
162 }
163
164 mEndTime = (TextView) findViewById(R.id.time);
165 mCurrentTime = (TextView) findViewById(R.id.time_current);
166 mFormatBuilder = new StringBuilder();
167 mFormatter = new Formatter(mFormatBuilder, Locale.getDefault());
168
169 installPrevNextListeners();
170 }
171
172 /**
173 * Disable pause or seek buttons if the stream cannot be paused or seeked.
174 * This requires the control interface to be a MediaPlayerControlExt
175 */
176 void updateButtons() {
177 int flags = mController.getTransportControlFlags();
178 boolean enabled = isEnabled();
179 if (mPauseButton != null) {
180 boolean needPlayPauseButton = (flags & TransportMediator.FLAG_KEY_ME DIA_PAUSE) != 0 ||
181 (flags & TransportMediator.FLAG_KEY_ME DIA_PLAY) != 0;
182 mPauseButton.setEnabled(enabled && needPlayPauseButton);
183 }
184 if (mRewButton != null) {
185 mRewButton.setEnabled(enabled &&
186 (flags & TransportMediator.FLAG_KEY_MEDIA_REWI ND) != 0);
187 }
188 if (mFfwdButton != null) {
189 mFfwdButton.setEnabled(enabled &&
190 (flags & TransportMediator.FLAG_KEY_MEDIA_FAST_FORWARD) != 0 );
191 }
192 if (mPrevButton != null) {
193 mShowPrev = (flags & TransportMediator.FLAG_KEY_MEDIA_PREVIOUS) != 0
194 || mPrevListener != null;
195 mPrevButton.setEnabled(enabled && mShowPrev);
196 }
197 if (mNextButton != null) {
198 mShowNext = (flags & TransportMediator.FLAG_KEY_MEDIA_NEXT) != 0
199 || mNextListener != null;
200 mNextButton.setEnabled(enabled && mShowNext);
201 }
202 }
203
204 public void refresh() {
205 updateProgress();
206 updateButtons();
207 updatePausePlay();
208 }
209
210 private String stringForTime(int timeMs) {
211 int totalSeconds = timeMs / 1000;
212
213 int seconds = totalSeconds % 60;
214 int minutes = (totalSeconds / 60) % 60;
215 int hours = totalSeconds / 3600;
216
217 mFormatBuilder.setLength(0);
218 if (hours > 0) {
219 return mFormatter.format("%d:%02d:%02d", hours, minutes, seconds).to String();
220 } else {
221 return mFormatter.format("%02d:%02d", minutes, seconds).toString();
222 }
223 }
224
225 public long updateProgress() {
226 if (mController == null || mDragging) {
227 return 0;
228 }
229 long position = mController.getCurrentPosition();
230 long duration = mController.getDuration();
231 if (duration <= 0) {
232 // If there is no valid duration, hide the progress bar and time ind icators.
233 if (mProgressGroup != null) mProgressGroup.setVisibility(View.INVISI BLE);
234 } else if (mProgressBar != null) {
235 if (mProgressGroup != null) mProgressGroup.setVisibility(View.VISIBL E);
236 // use long to avoid overflow
237 long pos = 1000L * position / duration;
238 mProgressBar.setProgress( (int) pos);
239
240 int percent = mController.getBufferPercentage();
241 mProgressBar.setSecondaryProgress(percent * 10);
242 }
243
244 if (mEndTime != null)
245 mEndTime.setText(stringForTime((int)duration));
246 if (mCurrentTime != null)
247 mCurrentTime.setText(stringForTime((int)position));
248
249 return position;
250 }
251
252 private View.OnClickListener mPauseListener = new View.OnClickListener() {
253 @Override
254 public void onClick(View v) {
255 doPauseResume();
256 }
257 };
258
259 private void updatePausePlay() {
260 if (mPauseButton == null)
261 return;
262
263 if (mController.isPlaying()) {
264 mPauseButton.setImageResource(android.R.drawable.ic_media_pause);
265 } else {
266 mPauseButton.setImageResource(android.R.drawable.ic_media_play);
267 }
268 }
269
270 private void doPauseResume() {
271 if (mController.isPlaying()) {
272 mController.pausePlaying();
273 } else {
274 mController.startPlaying();
275 }
276 updatePausePlay();
277 }
278
279 // There are two scenarios that can trigger the seekbar listener to trigger:
280 //
281 // The first is the user using the touchpad to adjust the posititon of the
282 // seekbar's thumb. In this case onStartTrackingTouch is called followed by
283 // a number of onProgressChanged notifications, concluded by onStopTrackingT ouch.
284 // We're setting the field "mDragging" to true for the duration of the dragg ing
285 // session to avoid jumps in the position in case of ongoing playback.
286 //
287 // The second scenario involves the user operating the scroll ball, in this
288 // case there WON'T BE onStartTrackingTouch/onStopTrackingTouch notification s,
289 // we will simply apply the updated position without suspending regular upda tes.
290 private SeekBar.OnSeekBarChangeListener mSeekListener = new SeekBar.OnSeekBa rChangeListener() {
291 @Override
292 public void onStartTrackingTouch(SeekBar bar) {
293 mDragging = true;
294 }
295
296 @Override
297 public void onProgressChanged(SeekBar bar, int progress, boolean fromuse r) {
298 if (!fromuser) {
299 // We're not interested in programmatically generated changes to
300 // the progress bar's position.
301 return;
302 }
303
304 long duration = mController.getDuration();
305 long newposition = (duration * progress) / 1000L;
306 mController.seekTo((int) newposition);
307 if (mCurrentTime != null)
308 mCurrentTime.setText(stringForTime( (int) newposition));
309 }
310
311 @Override
312 public void onStopTrackingTouch(SeekBar bar) {
313 mDragging = false;
314 updateProgress();
315 updatePausePlay();
316 }
317 };
318
319 @Override
320 public void setEnabled(boolean enabled) {
321 super.setEnabled(enabled);
322 updateButtons();
323 }
324
325 @Override
326 public void onInitializeAccessibilityEvent(AccessibilityEvent event) {
327 super.onInitializeAccessibilityEvent(event);
328 event.setClassName(MediaController.class.getName());
329 }
330
331 @Override
332 public void onInitializeAccessibilityNodeInfo(AccessibilityNodeInfo info) {
333 super.onInitializeAccessibilityNodeInfo(info);
334 info.setClassName(MediaController.class.getName());
335 }
336
337 private View.OnClickListener mRewListener = new View.OnClickListener() {
338 @Override
339 public void onClick(View v) {
340 long pos = mController.getCurrentPosition();
341 pos -= 5000; // milliseconds
342 mController.seekTo(pos);
343 updateProgress();
344 }
345 };
346
347 private View.OnClickListener mFfwdListener = new View.OnClickListener() {
348 @Override
349 public void onClick(View v) {
350 long pos = mController.getCurrentPosition();
351 pos += 15000; // milliseconds
352 mController.seekTo(pos);
353 updateProgress();
354 }
355 };
356
357 private void installPrevNextListeners() {
358 if (mNextButton != null) {
359 mNextButton.setOnClickListener(mNextListener);
360 mNextButton.setEnabled(mShowNext);
361 }
362
363 if (mPrevButton != null) {
364 mPrevButton.setOnClickListener(mPrevListener);
365 mPrevButton.setEnabled(mShowPrev);
366 }
367 }
368
369 public void setPrevNextListeners(View.OnClickListener next, View.OnClickList ener prev) {
370 mNextListener = next;
371 mPrevListener = prev;
372 mListenersSet = true;
373
374 installPrevNextListeners();
375
376 if (mNextButton != null) {
377 mNextButton.setVisibility(View.VISIBLE);
378 mShowNext = true;
379 }
380 if (mPrevButton != null) {
381 mPrevButton.setVisibility(View.VISIBLE);
382 mShowPrev = true;
383 }
384 }
385 }
386
OLDNEW
« no previous file with comments | « third_party/android_media/java/res/values/colors.xml ('k') | tools/android/eclipse/.classpath » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698