19066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/* 29066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Copyright (C) 2006 The Android Open Source Project 39066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 49066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License"); 59066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * you may not use this file except in compliance with the License. 69066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * You may obtain a copy of the License at 79066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 89066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * http://www.apache.org/licenses/LICENSE-2.0 99066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Unless required by applicable law or agreed to in writing, software 119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS, 129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * See the License for the specific language governing permissions and 149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * limitations under the License. 159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectpackage android.widget; 189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.content.Context; 209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.graphics.PixelFormat; 219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.media.AudioManager; 229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.os.Handler; 239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.os.Message; 249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.util.AttributeSet; 259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.util.Log; 269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.view.Gravity; 279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.view.KeyEvent; 289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.view.LayoutInflater; 299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.view.MotionEvent; 309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.view.View; 319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.view.ViewGroup; 329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.view.Window; 339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.view.WindowManager; 348a78fd4d9572dff95432fcc4ba0e87563415b728Svetoslav Ganovimport android.view.accessibility.AccessibilityEvent; 358a78fd4d9572dff95432fcc4ba0e87563415b728Svetoslav Ganovimport android.view.accessibility.AccessibilityNodeInfo; 369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.widget.SeekBar.OnSeekBarChangeListener; 379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport com.android.internal.policy.PolicyManager; 399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.util.Formatter; 419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.util.Locale; 429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/** 449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * A view containing controls for a MediaPlayer. Typically contains the 459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * buttons like "Play/Pause", "Rewind", "Fast Forward" and a progress 469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * slider. It takes care of synchronizing the controls with the state 479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * of the MediaPlayer. 489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p> 499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * The way to use this class is to instantiate it programatically. 509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * The MediaController will create a default set of controls 519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * and put them in a window floating above your application. Specifically, 529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * the controls will float above the view specified with setAnchorView(). 539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * The window will disappear if left idle for three seconds and reappear 549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * when the user touches the anchor view. 559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p> 569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Functions like show() and hide() have no effect when MediaController 579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * is created in an xml layout. 589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * MediaController will hide and 609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * show the buttons according to these rules: 619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <ul> 629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <li> The "previous" and "next" buttons are hidden until setPrevNextListeners() 639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * has been called 649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <li> The "previous" and "next" buttons are visible but disabled if 659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * setPrevNextListeners() was called with null listeners 669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <li> The "rewind" and "fastforward" buttons are shown unless requested 679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * otherwise by using the MediaController(Context, boolean) constructor 689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * with the boolean set to false 699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * </ul> 709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectpublic class MediaController extends FrameLayout { 729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private MediaPlayerControl mPlayer; 749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private Context mContext; 759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private View mAnchor; 769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private View mRoot; 779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private WindowManager mWindowManager; 789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private Window mWindow; 799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private View mDecor; 8085d4ea6fe49e97c8b569768ba63a849653adb5b1Chih-Chung Chang private WindowManager.LayoutParams mDecorLayoutParams; 819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private ProgressBar mProgress; 829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private TextView mEndTime, mCurrentTime; 839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private boolean mShowing; 849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private boolean mDragging; 859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final int sDefaultTimeout = 3000; 869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final int FADE_OUT = 1; 879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final int SHOW_PROGRESS = 2; 889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private boolean mUseFastForward; 899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private boolean mFromXml; 909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private boolean mListenersSet; 919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private View.OnClickListener mNextListener, mPrevListener; 929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project StringBuilder mFormatBuilder; 939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Formatter mFormatter; 949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private ImageButton mPauseButton; 959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private ImageButton mFfwdButton; 969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private ImageButton mRewButton; 979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private ImageButton mNextButton; 989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private ImageButton mPrevButton; 999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public MediaController(Context context, AttributeSet attrs) { 1019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project super(context, attrs); 1029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mRoot = this; 1039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mContext = context; 1049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mUseFastForward = true; 1059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mFromXml = true; 1069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 1099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void onFinishInflate() { 1109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mRoot != null) 1119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project initControllerView(mRoot); 1129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public MediaController(Context context, boolean useFastForward) { 1159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project super(context); 1169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mContext = context; 1179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mUseFastForward = useFastForward; 11802dd17da3685652b5235ca48bd6882e65997434aChih-Chung Chang initFloatingWindowLayout(); 1199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project initFloatingWindow(); 1209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public MediaController(Context context) { 12302dd17da3685652b5235ca48bd6882e65997434aChih-Chung Chang this(context, true); 1249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private void initFloatingWindow() { 127ef367529f9c7a538d74599b37b49ac309d0a8d8cChristian Mehlmauer mWindowManager = (WindowManager)mContext.getSystemService(Context.WINDOW_SERVICE); 1289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mWindow = PolicyManager.makeNewWindow(mContext); 1299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mWindow.setWindowManager(mWindowManager, null, null); 1309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mWindow.requestFeature(Window.FEATURE_NO_TITLE); 1319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mDecor = mWindow.getDecorView(); 1329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mDecor.setOnTouchListener(mTouchListener); 1339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mWindow.setContentView(this); 1349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mWindow.setBackgroundDrawableResource(android.R.color.transparent); 1359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // While the media controller is up, the volume control keys should 1379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // affect the media stream type 1389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mWindow.setVolumeControlStream(AudioManager.STREAM_MUSIC); 1399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project setFocusable(true); 1419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project setFocusableInTouchMode(true); 1429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project setDescendantFocusability(ViewGroup.FOCUS_AFTER_DESCENDANTS); 1439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project requestFocus(); 1449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 14685d4ea6fe49e97c8b569768ba63a849653adb5b1Chih-Chung Chang // Allocate and initialize the static parts of mDecorLayoutParams. Must 14785d4ea6fe49e97c8b569768ba63a849653adb5b1Chih-Chung Chang // also call updateFloatingWindowLayout() to fill in the dynamic parts 14885d4ea6fe49e97c8b569768ba63a849653adb5b1Chih-Chung Chang // (y and width) before mDecorLayoutParams can be used. 14985d4ea6fe49e97c8b569768ba63a849653adb5b1Chih-Chung Chang private void initFloatingWindowLayout() { 15085d4ea6fe49e97c8b569768ba63a849653adb5b1Chih-Chung Chang mDecorLayoutParams = new WindowManager.LayoutParams(); 15185d4ea6fe49e97c8b569768ba63a849653adb5b1Chih-Chung Chang WindowManager.LayoutParams p = mDecorLayoutParams; 1520b2d87237ed53b94dc2216a42942d35788d3307bMarco Nelissen p.gravity = Gravity.TOP | Gravity.LEFT; 15385d4ea6fe49e97c8b569768ba63a849653adb5b1Chih-Chung Chang p.height = LayoutParams.WRAP_CONTENT; 15485d4ea6fe49e97c8b569768ba63a849653adb5b1Chih-Chung Chang p.x = 0; 15585d4ea6fe49e97c8b569768ba63a849653adb5b1Chih-Chung Chang p.format = PixelFormat.TRANSLUCENT; 15685d4ea6fe49e97c8b569768ba63a849653adb5b1Chih-Chung Chang p.type = WindowManager.LayoutParams.TYPE_APPLICATION_PANEL; 15785d4ea6fe49e97c8b569768ba63a849653adb5b1Chih-Chung Chang p.flags |= WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM 15885d4ea6fe49e97c8b569768ba63a849653adb5b1Chih-Chung Chang | WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL 15985d4ea6fe49e97c8b569768ba63a849653adb5b1Chih-Chung Chang | WindowManager.LayoutParams.FLAG_SPLIT_TOUCH; 16085d4ea6fe49e97c8b569768ba63a849653adb5b1Chih-Chung Chang p.token = null; 16185d4ea6fe49e97c8b569768ba63a849653adb5b1Chih-Chung Chang p.windowAnimations = 0; // android.R.style.DropDownAnimationDown; 16285d4ea6fe49e97c8b569768ba63a849653adb5b1Chih-Chung Chang } 16385d4ea6fe49e97c8b569768ba63a849653adb5b1Chih-Chung Chang 16485d4ea6fe49e97c8b569768ba63a849653adb5b1Chih-Chung Chang // Update the dynamic parts of mDecorLayoutParams 16585d4ea6fe49e97c8b569768ba63a849653adb5b1Chih-Chung Chang // Must be called with mAnchor != NULL. 16685d4ea6fe49e97c8b569768ba63a849653adb5b1Chih-Chung Chang private void updateFloatingWindowLayout() { 16785d4ea6fe49e97c8b569768ba63a849653adb5b1Chih-Chung Chang int [] anchorPos = new int[2]; 16885d4ea6fe49e97c8b569768ba63a849653adb5b1Chih-Chung Chang mAnchor.getLocationOnScreen(anchorPos); 16985d4ea6fe49e97c8b569768ba63a849653adb5b1Chih-Chung Chang 1700b2d87237ed53b94dc2216a42942d35788d3307bMarco Nelissen // we need to know the size of the controller so we can properly position it 1710b2d87237ed53b94dc2216a42942d35788d3307bMarco Nelissen // within its space 1720b2d87237ed53b94dc2216a42942d35788d3307bMarco Nelissen mDecor.measure(MeasureSpec.makeMeasureSpec(mAnchor.getWidth(), MeasureSpec.AT_MOST), 1730b2d87237ed53b94dc2216a42942d35788d3307bMarco Nelissen MeasureSpec.makeMeasureSpec(mAnchor.getHeight(), MeasureSpec.AT_MOST)); 1740b2d87237ed53b94dc2216a42942d35788d3307bMarco Nelissen 17585d4ea6fe49e97c8b569768ba63a849653adb5b1Chih-Chung Chang WindowManager.LayoutParams p = mDecorLayoutParams; 17685d4ea6fe49e97c8b569768ba63a849653adb5b1Chih-Chung Chang p.width = mAnchor.getWidth(); 1770b2d87237ed53b94dc2216a42942d35788d3307bMarco Nelissen p.x = anchorPos[0] + (mAnchor.getWidth() - p.width) / 2; 1780b2d87237ed53b94dc2216a42942d35788d3307bMarco Nelissen p.y = anchorPos[1] + mAnchor.getHeight() - mDecor.getMeasuredHeight(); 17985d4ea6fe49e97c8b569768ba63a849653adb5b1Chih-Chung Chang } 18085d4ea6fe49e97c8b569768ba63a849653adb5b1Chih-Chung Chang 18185d4ea6fe49e97c8b569768ba63a849653adb5b1Chih-Chung Chang // This is called whenever mAnchor's layout bound changes 18285d4ea6fe49e97c8b569768ba63a849653adb5b1Chih-Chung Chang private OnLayoutChangeListener mLayoutChangeListener = 18385d4ea6fe49e97c8b569768ba63a849653adb5b1Chih-Chung Chang new OnLayoutChangeListener() { 18485d4ea6fe49e97c8b569768ba63a849653adb5b1Chih-Chung Chang public void onLayoutChange(View v, int left, int top, int right, 18585d4ea6fe49e97c8b569768ba63a849653adb5b1Chih-Chung Chang int bottom, int oldLeft, int oldTop, int oldRight, 18685d4ea6fe49e97c8b569768ba63a849653adb5b1Chih-Chung Chang int oldBottom) { 18785d4ea6fe49e97c8b569768ba63a849653adb5b1Chih-Chung Chang updateFloatingWindowLayout(); 18885d4ea6fe49e97c8b569768ba63a849653adb5b1Chih-Chung Chang if (mShowing) { 18985d4ea6fe49e97c8b569768ba63a849653adb5b1Chih-Chung Chang mWindowManager.updateViewLayout(mDecor, mDecorLayoutParams); 19085d4ea6fe49e97c8b569768ba63a849653adb5b1Chih-Chung Chang } 19185d4ea6fe49e97c8b569768ba63a849653adb5b1Chih-Chung Chang } 19285d4ea6fe49e97c8b569768ba63a849653adb5b1Chih-Chung Chang }; 19385d4ea6fe49e97c8b569768ba63a849653adb5b1Chih-Chung Chang 1949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private OnTouchListener mTouchListener = new OnTouchListener() { 1959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public boolean onTouch(View v, MotionEvent event) { 1969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (event.getAction() == MotionEvent.ACTION_DOWN) { 1979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mShowing) { 1989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project hide(); 1999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return false; 2029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project }; 2049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void setMediaPlayer(MediaPlayerControl player) { 2069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mPlayer = player; 2079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project updatePausePlay(); 2089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 2119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Set the view that acts as the anchor for the control view. 2129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * This can for example be a VideoView, or your Activity's main view. 2130b2d87237ed53b94dc2216a42942d35788d3307bMarco Nelissen * When VideoView calls this method, it will use the VideoView's parent 2140b2d87237ed53b94dc2216a42942d35788d3307bMarco Nelissen * as the anchor. 2159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param view The view to which to anchor the controller when it is visible. 2169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 2179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void setAnchorView(View view) { 21885d4ea6fe49e97c8b569768ba63a849653adb5b1Chih-Chung Chang if (mAnchor != null) { 21985d4ea6fe49e97c8b569768ba63a849653adb5b1Chih-Chung Chang mAnchor.removeOnLayoutChangeListener(mLayoutChangeListener); 22085d4ea6fe49e97c8b569768ba63a849653adb5b1Chih-Chung Chang } 2219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mAnchor = view; 22285d4ea6fe49e97c8b569768ba63a849653adb5b1Chih-Chung Chang if (mAnchor != null) { 22385d4ea6fe49e97c8b569768ba63a849653adb5b1Chih-Chung Chang mAnchor.addOnLayoutChangeListener(mLayoutChangeListener); 22485d4ea6fe49e97c8b569768ba63a849653adb5b1Chih-Chung Chang } 2259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project FrameLayout.LayoutParams frameParams = new FrameLayout.LayoutParams( 227980a938c1c9a6a5791a8240e5a1e6638ab28dc77Romain Guy ViewGroup.LayoutParams.MATCH_PARENT, 228980a938c1c9a6a5791a8240e5a1e6638ab28dc77Romain Guy ViewGroup.LayoutParams.MATCH_PARENT 2299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ); 2309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project removeAllViews(); 2329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project View v = makeControllerView(); 2339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project addView(v, frameParams); 2349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 2379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Create the view that holds the widgets that control playback. 2389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Derived classes can override this to create their own. 2399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return The controller view. 2409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @hide This doesn't work as advertised 2419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 2429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project protected View makeControllerView() { 2439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project LayoutInflater inflate = (LayoutInflater) mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE); 2449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mRoot = inflate.inflate(com.android.internal.R.layout.media_controller, null); 2459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project initControllerView(mRoot); 2479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mRoot; 2499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private void initControllerView(View v) { 2529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mPauseButton = (ImageButton) v.findViewById(com.android.internal.R.id.pause); 2539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mPauseButton != null) { 2549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mPauseButton.requestFocus(); 2559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mPauseButton.setOnClickListener(mPauseListener); 2569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mFfwdButton = (ImageButton) v.findViewById(com.android.internal.R.id.ffwd); 2599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mFfwdButton != null) { 2609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mFfwdButton.setOnClickListener(mFfwdListener); 2619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!mFromXml) { 2629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mFfwdButton.setVisibility(mUseFastForward ? View.VISIBLE : View.GONE); 2639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mRewButton = (ImageButton) v.findViewById(com.android.internal.R.id.rew); 2679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mRewButton != null) { 2689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mRewButton.setOnClickListener(mRewListener); 2699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!mFromXml) { 2709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mRewButton.setVisibility(mUseFastForward ? View.VISIBLE : View.GONE); 2719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // By default these are hidden. They will be enabled when setPrevNextListeners() is called 2759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mNextButton = (ImageButton) v.findViewById(com.android.internal.R.id.next); 2769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mNextButton != null && !mFromXml && !mListenersSet) { 2779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mNextButton.setVisibility(View.GONE); 2789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mPrevButton = (ImageButton) v.findViewById(com.android.internal.R.id.prev); 2809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mPrevButton != null && !mFromXml && !mListenersSet) { 2819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mPrevButton.setVisibility(View.GONE); 2829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mProgress = (ProgressBar) v.findViewById(com.android.internal.R.id.mediacontroller_progress); 2859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mProgress != null) { 2869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mProgress instanceof SeekBar) { 2879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project SeekBar seeker = (SeekBar) mProgress; 2889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project seeker.setOnSeekBarChangeListener(mSeekListener); 2899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mProgress.setMax(1000); 2919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mEndTime = (TextView) v.findViewById(com.android.internal.R.id.time); 2949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mCurrentTime = (TextView) v.findViewById(com.android.internal.R.id.time_current); 2959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mFormatBuilder = new StringBuilder(); 2969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mFormatter = new Formatter(mFormatBuilder, Locale.getDefault()); 2979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project installPrevNextListeners(); 2999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 3029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Show the controller on screen. It will go away 3039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * automatically after 3 seconds of inactivity. 3049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 3059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void show() { 3069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project show(sDefaultTimeout); 3079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 310c818b141ee97a7a26fe069456d4b662d06c9eaeaMarco Nelissen * Disable pause or seek buttons if the stream cannot be paused or seeked. 311c818b141ee97a7a26fe069456d4b662d06c9eaeaMarco Nelissen * This requires the control interface to be a MediaPlayerControlExt 312c818b141ee97a7a26fe069456d4b662d06c9eaeaMarco Nelissen */ 313c818b141ee97a7a26fe069456d4b662d06c9eaeaMarco Nelissen private void disableUnsupportedButtons() { 314c818b141ee97a7a26fe069456d4b662d06c9eaeaMarco Nelissen try { 315c818b141ee97a7a26fe069456d4b662d06c9eaeaMarco Nelissen if (mPauseButton != null && !mPlayer.canPause()) { 316c818b141ee97a7a26fe069456d4b662d06c9eaeaMarco Nelissen mPauseButton.setEnabled(false); 317c818b141ee97a7a26fe069456d4b662d06c9eaeaMarco Nelissen } 318c818b141ee97a7a26fe069456d4b662d06c9eaeaMarco Nelissen if (mRewButton != null && !mPlayer.canSeekBackward()) { 319c818b141ee97a7a26fe069456d4b662d06c9eaeaMarco Nelissen mRewButton.setEnabled(false); 320c818b141ee97a7a26fe069456d4b662d06c9eaeaMarco Nelissen } 321c818b141ee97a7a26fe069456d4b662d06c9eaeaMarco Nelissen if (mFfwdButton != null && !mPlayer.canSeekForward()) { 322c818b141ee97a7a26fe069456d4b662d06c9eaeaMarco Nelissen mFfwdButton.setEnabled(false); 323c818b141ee97a7a26fe069456d4b662d06c9eaeaMarco Nelissen } 324c818b141ee97a7a26fe069456d4b662d06c9eaeaMarco Nelissen } catch (IncompatibleClassChangeError ex) { 325c818b141ee97a7a26fe069456d4b662d06c9eaeaMarco Nelissen // We were given an old version of the interface, that doesn't have 326c818b141ee97a7a26fe069456d4b662d06c9eaeaMarco Nelissen // the canPause/canSeekXYZ methods. This is OK, it just means we 327c818b141ee97a7a26fe069456d4b662d06c9eaeaMarco Nelissen // assume the media can be paused and seeked, and so we don't disable 328c818b141ee97a7a26fe069456d4b662d06c9eaeaMarco Nelissen // the buttons. 329c818b141ee97a7a26fe069456d4b662d06c9eaeaMarco Nelissen } 330c818b141ee97a7a26fe069456d4b662d06c9eaeaMarco Nelissen } 331c818b141ee97a7a26fe069456d4b662d06c9eaeaMarco Nelissen 332c818b141ee97a7a26fe069456d4b662d06c9eaeaMarco Nelissen /** 3339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Show the controller on screen. It will go away 3349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * automatically after 'timeout' milliseconds of inactivity. 3359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param timeout The timeout in milliseconds. Use 0 to show 3369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * the controller until hide() is called. 3379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 3389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void show(int timeout) { 3399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!mShowing && mAnchor != null) { 3409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project setProgress(); 341d701e020769b7cc6dd492eadcb09083578074ee0Marco Nelissen if (mPauseButton != null) { 342d701e020769b7cc6dd492eadcb09083578074ee0Marco Nelissen mPauseButton.requestFocus(); 343d701e020769b7cc6dd492eadcb09083578074ee0Marco Nelissen } 344c818b141ee97a7a26fe069456d4b662d06c9eaeaMarco Nelissen disableUnsupportedButtons(); 34585d4ea6fe49e97c8b569768ba63a849653adb5b1Chih-Chung Chang updateFloatingWindowLayout(); 34685d4ea6fe49e97c8b569768ba63a849653adb5b1Chih-Chung Chang mWindowManager.addView(mDecor, mDecorLayoutParams); 3479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mShowing = true; 3489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project updatePausePlay(); 3509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // cause the progress bar to be updated even if mShowing 3529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // was already true. This happens, for example, if we're 3539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // paused with the progress bar showing the user hits play. 3549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mHandler.sendEmptyMessage(SHOW_PROGRESS); 3559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Message msg = mHandler.obtainMessage(FADE_OUT); 3579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (timeout != 0) { 3589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mHandler.removeMessages(FADE_OUT); 3599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mHandler.sendMessageDelayed(msg, timeout); 3609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public boolean isShowing() { 3649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mShowing; 3659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 3689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Remove the controller from the screen. 3699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 3709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void hide() { 3719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mAnchor == null) 3729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return; 3739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mShowing) { 3759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 3769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mHandler.removeMessages(SHOW_PROGRESS); 3779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mWindowManager.removeView(mDecor); 3789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (IllegalArgumentException ex) { 3799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Log.w("MediaController", "already removed"); 3809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mShowing = false; 3829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private Handler mHandler = new Handler() { 3869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 3879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void handleMessage(Message msg) { 3889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int pos; 3899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project switch (msg.what) { 3909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case FADE_OUT: 3919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project hide(); 3929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project break; 3939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case SHOW_PROGRESS: 3949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project pos = setProgress(); 3959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!mDragging && mShowing && mPlayer.isPlaying()) { 3969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project msg = obtainMessage(SHOW_PROGRESS); 3979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project sendMessageDelayed(msg, 1000 - (pos % 1000)); 3989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project break; 4009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project }; 4039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private String stringForTime(int timeMs) { 4059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int totalSeconds = timeMs / 1000; 4069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int seconds = totalSeconds % 60; 4089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int minutes = (totalSeconds / 60) % 60; 4099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int hours = totalSeconds / 3600; 4109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mFormatBuilder.setLength(0); 4129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (hours > 0) { 4139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mFormatter.format("%d:%02d:%02d", hours, minutes, seconds).toString(); 4149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 4159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mFormatter.format("%02d:%02d", minutes, seconds).toString(); 4169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private int setProgress() { 4209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mPlayer == null || mDragging) { 4219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return 0; 4229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int position = mPlayer.getCurrentPosition(); 4249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int duration = mPlayer.getDuration(); 4259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mProgress != null) { 4269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (duration > 0) { 4279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // use long to avoid overflow 4289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project long pos = 1000L * position / duration; 4299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mProgress.setProgress( (int) pos); 4309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int percent = mPlayer.getBufferPercentage(); 4329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mProgress.setSecondaryProgress(percent * 10); 4339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mEndTime != null) 4369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mEndTime.setText(stringForTime(duration)); 4379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mCurrentTime != null) 4389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mCurrentTime.setText(stringForTime(position)); 4399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return position; 4419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 4449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public boolean onTouchEvent(MotionEvent event) { 4459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project show(sDefaultTimeout); 4469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return true; 4479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 4509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public boolean onTrackballEvent(MotionEvent ev) { 4519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project show(sDefaultTimeout); 4529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return false; 4539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 4569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public boolean dispatchKeyEvent(KeyEvent event) { 4579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int keyCode = event.getKeyCode(); 4584d396052deb54399cbadbeb8abd873df6f3af342Jeff Brown final boolean uniqueDown = event.getRepeatCount() == 0 4594d396052deb54399cbadbeb8abd873df6f3af342Jeff Brown && event.getAction() == KeyEvent.ACTION_DOWN; 4604d396052deb54399cbadbeb8abd873df6f3af342Jeff Brown if (keyCode == KeyEvent.KEYCODE_HEADSETHOOK 4614d396052deb54399cbadbeb8abd873df6f3af342Jeff Brown || keyCode == KeyEvent.KEYCODE_MEDIA_PLAY_PAUSE 4624d396052deb54399cbadbeb8abd873df6f3af342Jeff Brown || keyCode == KeyEvent.KEYCODE_SPACE) { 4634d396052deb54399cbadbeb8abd873df6f3af342Jeff Brown if (uniqueDown) { 4644d396052deb54399cbadbeb8abd873df6f3af342Jeff Brown doPauseResume(); 4654d396052deb54399cbadbeb8abd873df6f3af342Jeff Brown show(sDefaultTimeout); 4664d396052deb54399cbadbeb8abd873df6f3af342Jeff Brown if (mPauseButton != null) { 4674d396052deb54399cbadbeb8abd873df6f3af342Jeff Brown mPauseButton.requestFocus(); 4684d396052deb54399cbadbeb8abd873df6f3af342Jeff Brown } 4694d396052deb54399cbadbeb8abd873df6f3af342Jeff Brown } 4704d396052deb54399cbadbeb8abd873df6f3af342Jeff Brown return true; 4714d396052deb54399cbadbeb8abd873df6f3af342Jeff Brown } else if (keyCode == KeyEvent.KEYCODE_MEDIA_PLAY) { 4724d396052deb54399cbadbeb8abd873df6f3af342Jeff Brown if (uniqueDown && !mPlayer.isPlaying()) { 4734d396052deb54399cbadbeb8abd873df6f3af342Jeff Brown mPlayer.start(); 4744d396052deb54399cbadbeb8abd873df6f3af342Jeff Brown updatePausePlay(); 4754d396052deb54399cbadbeb8abd873df6f3af342Jeff Brown show(sDefaultTimeout); 476d701e020769b7cc6dd492eadcb09083578074ee0Marco Nelissen } 4779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return true; 4784d396052deb54399cbadbeb8abd873df6f3af342Jeff Brown } else if (keyCode == KeyEvent.KEYCODE_MEDIA_STOP 4794d396052deb54399cbadbeb8abd873df6f3af342Jeff Brown || keyCode == KeyEvent.KEYCODE_MEDIA_PAUSE) { 4804d396052deb54399cbadbeb8abd873df6f3af342Jeff Brown if (uniqueDown && mPlayer.isPlaying()) { 4819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mPlayer.pause(); 4829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project updatePausePlay(); 4834d396052deb54399cbadbeb8abd873df6f3af342Jeff Brown show(sDefaultTimeout); 4849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return true; 4864d396052deb54399cbadbeb8abd873df6f3af342Jeff Brown } else if (keyCode == KeyEvent.KEYCODE_VOLUME_DOWN 487b0418da0e7594a8c2164a46985c5f1993632e010Jeff Brown || keyCode == KeyEvent.KEYCODE_VOLUME_UP 48896ac720117979ab0507d8760f49076a0a1e3bfb8bxu || keyCode == KeyEvent.KEYCODE_VOLUME_MUTE 48996ac720117979ab0507d8760f49076a0a1e3bfb8bxu || keyCode == KeyEvent.KEYCODE_CAMERA) { 4909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // don't show the controls for volume adjustment 4919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return super.dispatchKeyEvent(event); 4929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else if (keyCode == KeyEvent.KEYCODE_BACK || keyCode == KeyEvent.KEYCODE_MENU) { 4934d396052deb54399cbadbeb8abd873df6f3af342Jeff Brown if (uniqueDown) { 4944d396052deb54399cbadbeb8abd873df6f3af342Jeff Brown hide(); 4954d396052deb54399cbadbeb8abd873df6f3af342Jeff Brown } 496105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project return true; 4979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4984d396052deb54399cbadbeb8abd873df6f3af342Jeff Brown 4994d396052deb54399cbadbeb8abd873df6f3af342Jeff Brown show(sDefaultTimeout); 5009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return super.dispatchKeyEvent(event); 5019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private View.OnClickListener mPauseListener = new View.OnClickListener() { 5049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void onClick(View v) { 5059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project doPauseResume(); 5069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project show(sDefaultTimeout); 5079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project }; 5099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private void updatePausePlay() { 511c818b141ee97a7a26fe069456d4b662d06c9eaeaMarco Nelissen if (mRoot == null || mPauseButton == null) 5129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return; 5139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mPlayer.isPlaying()) { 515c818b141ee97a7a26fe069456d4b662d06c9eaeaMarco Nelissen mPauseButton.setImageResource(com.android.internal.R.drawable.ic_media_pause); 5169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 517c818b141ee97a7a26fe069456d4b662d06c9eaeaMarco Nelissen mPauseButton.setImageResource(com.android.internal.R.drawable.ic_media_play); 5189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private void doPauseResume() { 5229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mPlayer.isPlaying()) { 5239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mPlayer.pause(); 5249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 5259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mPlayer.start(); 5269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project updatePausePlay(); 5289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5300de7dcd126175a1bef77f2039b39df1eed4b4164Andreas Huber // There are two scenarios that can trigger the seekbar listener to trigger: 5310de7dcd126175a1bef77f2039b39df1eed4b4164Andreas Huber // 5320de7dcd126175a1bef77f2039b39df1eed4b4164Andreas Huber // The first is the user using the touchpad to adjust the posititon of the 5330de7dcd126175a1bef77f2039b39df1eed4b4164Andreas Huber // seekbar's thumb. In this case onStartTrackingTouch is called followed by 5340de7dcd126175a1bef77f2039b39df1eed4b4164Andreas Huber // a number of onProgressChanged notifications, concluded by onStopTrackingTouch. 5350de7dcd126175a1bef77f2039b39df1eed4b4164Andreas Huber // We're setting the field "mDragging" to true for the duration of the dragging 5360de7dcd126175a1bef77f2039b39df1eed4b4164Andreas Huber // session to avoid jumps in the position in case of ongoing playback. 5370de7dcd126175a1bef77f2039b39df1eed4b4164Andreas Huber // 5380de7dcd126175a1bef77f2039b39df1eed4b4164Andreas Huber // The second scenario involves the user operating the scroll ball, in this 5390de7dcd126175a1bef77f2039b39df1eed4b4164Andreas Huber // case there WON'T BE onStartTrackingTouch/onStopTrackingTouch notifications, 5400de7dcd126175a1bef77f2039b39df1eed4b4164Andreas Huber // we will simply apply the updated position without suspending regular updates. 5419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private OnSeekBarChangeListener mSeekListener = new OnSeekBarChangeListener() { 5429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void onStartTrackingTouch(SeekBar bar) { 5439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project show(3600000); 5440de7dcd126175a1bef77f2039b39df1eed4b4164Andreas Huber 5450de7dcd126175a1bef77f2039b39df1eed4b4164Andreas Huber mDragging = true; 5460de7dcd126175a1bef77f2039b39df1eed4b4164Andreas Huber 5470de7dcd126175a1bef77f2039b39df1eed4b4164Andreas Huber // By removing these pending progress messages we make sure 5480de7dcd126175a1bef77f2039b39df1eed4b4164Andreas Huber // that a) we won't update the progress while the user adjusts 5490de7dcd126175a1bef77f2039b39df1eed4b4164Andreas Huber // the seekbar and b) once the user is done dragging the thumb 5500de7dcd126175a1bef77f2039b39df1eed4b4164Andreas Huber // we will post one of these messages to the queue again and 5510de7dcd126175a1bef77f2039b39df1eed4b4164Andreas Huber // this ensures that there will be exactly one message queued up. 5520de7dcd126175a1bef77f2039b39df1eed4b4164Andreas Huber mHandler.removeMessages(SHOW_PROGRESS); 5539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5540de7dcd126175a1bef77f2039b39df1eed4b4164Andreas Huber 5550de7dcd126175a1bef77f2039b39df1eed4b4164Andreas Huber public void onProgressChanged(SeekBar bar, int progress, boolean fromuser) { 5560de7dcd126175a1bef77f2039b39df1eed4b4164Andreas Huber if (!fromuser) { 5570de7dcd126175a1bef77f2039b39df1eed4b4164Andreas Huber // We're not interested in programmatically generated changes to 5580de7dcd126175a1bef77f2039b39df1eed4b4164Andreas Huber // the progress bar's position. 5590de7dcd126175a1bef77f2039b39df1eed4b4164Andreas Huber return; 5609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5610de7dcd126175a1bef77f2039b39df1eed4b4164Andreas Huber 5620de7dcd126175a1bef77f2039b39df1eed4b4164Andreas Huber long duration = mPlayer.getDuration(); 5630de7dcd126175a1bef77f2039b39df1eed4b4164Andreas Huber long newposition = (duration * progress) / 1000L; 5640de7dcd126175a1bef77f2039b39df1eed4b4164Andreas Huber mPlayer.seekTo( (int) newposition); 5650de7dcd126175a1bef77f2039b39df1eed4b4164Andreas Huber if (mCurrentTime != null) 5660de7dcd126175a1bef77f2039b39df1eed4b4164Andreas Huber mCurrentTime.setText(stringForTime( (int) newposition)); 5679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5680de7dcd126175a1bef77f2039b39df1eed4b4164Andreas Huber 5699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void onStopTrackingTouch(SeekBar bar) { 5709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mDragging = false; 5719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project setProgress(); 5729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project updatePausePlay(); 5739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project show(sDefaultTimeout); 5740de7dcd126175a1bef77f2039b39df1eed4b4164Andreas Huber 5750de7dcd126175a1bef77f2039b39df1eed4b4164Andreas Huber // Ensure that progress is properly updated in the future, 5760de7dcd126175a1bef77f2039b39df1eed4b4164Andreas Huber // the call to show() does not guarantee this because it is a 5770de7dcd126175a1bef77f2039b39df1eed4b4164Andreas Huber // no-op if we are already showing. 5780de7dcd126175a1bef77f2039b39df1eed4b4164Andreas Huber mHandler.sendEmptyMessage(SHOW_PROGRESS); 5799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project }; 5819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 5839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void setEnabled(boolean enabled) { 5849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mPauseButton != null) { 5859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mPauseButton.setEnabled(enabled); 5869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mFfwdButton != null) { 5889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mFfwdButton.setEnabled(enabled); 5899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mRewButton != null) { 5919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mRewButton.setEnabled(enabled); 5929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mNextButton != null) { 5949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mNextButton.setEnabled(enabled && mNextListener != null); 5959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mPrevButton != null) { 5979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mPrevButton.setEnabled(enabled && mPrevListener != null); 5989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mProgress != null) { 6009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mProgress.setEnabled(enabled); 6019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 602c818b141ee97a7a26fe069456d4b662d06c9eaeaMarco Nelissen disableUnsupportedButtons(); 6039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project super.setEnabled(enabled); 6049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6068a78fd4d9572dff95432fcc4ba0e87563415b728Svetoslav Ganov @Override 6078a78fd4d9572dff95432fcc4ba0e87563415b728Svetoslav Ganov public void onInitializeAccessibilityEvent(AccessibilityEvent event) { 6088a78fd4d9572dff95432fcc4ba0e87563415b728Svetoslav Ganov super.onInitializeAccessibilityEvent(event); 6098a78fd4d9572dff95432fcc4ba0e87563415b728Svetoslav Ganov event.setClassName(MediaController.class.getName()); 6108a78fd4d9572dff95432fcc4ba0e87563415b728Svetoslav Ganov } 6118a78fd4d9572dff95432fcc4ba0e87563415b728Svetoslav Ganov 6128a78fd4d9572dff95432fcc4ba0e87563415b728Svetoslav Ganov @Override 6138a78fd4d9572dff95432fcc4ba0e87563415b728Svetoslav Ganov public void onInitializeAccessibilityNodeInfo(AccessibilityNodeInfo info) { 6148a78fd4d9572dff95432fcc4ba0e87563415b728Svetoslav Ganov super.onInitializeAccessibilityNodeInfo(info); 6158a78fd4d9572dff95432fcc4ba0e87563415b728Svetoslav Ganov info.setClassName(MediaController.class.getName()); 6168a78fd4d9572dff95432fcc4ba0e87563415b728Svetoslav Ganov } 6178a78fd4d9572dff95432fcc4ba0e87563415b728Svetoslav Ganov 6189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private View.OnClickListener mRewListener = new View.OnClickListener() { 6199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void onClick(View v) { 6209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int pos = mPlayer.getCurrentPosition(); 6219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project pos -= 5000; // milliseconds 6229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mPlayer.seekTo(pos); 6239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project setProgress(); 6249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project show(sDefaultTimeout); 6269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project }; 6289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private View.OnClickListener mFfwdListener = new View.OnClickListener() { 6309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void onClick(View v) { 6319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int pos = mPlayer.getCurrentPosition(); 6329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project pos += 15000; // milliseconds 6339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mPlayer.seekTo(pos); 6349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project setProgress(); 6359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project show(sDefaultTimeout); 6379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project }; 6399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private void installPrevNextListeners() { 6419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mNextButton != null) { 6429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mNextButton.setOnClickListener(mNextListener); 6439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mNextButton.setEnabled(mNextListener != null); 6449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mPrevButton != null) { 6479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mPrevButton.setOnClickListener(mPrevListener); 6489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mPrevButton.setEnabled(mPrevListener != null); 6499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void setPrevNextListeners(View.OnClickListener next, View.OnClickListener prev) { 6539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mNextListener = next; 6549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mPrevListener = prev; 6559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mListenersSet = true; 6569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mRoot != null) { 6589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project installPrevNextListeners(); 6599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mNextButton != null && !mFromXml) { 6619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mNextButton.setVisibility(View.VISIBLE); 6629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mPrevButton != null && !mFromXml) { 6649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mPrevButton.setVisibility(View.VISIBLE); 6659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public interface MediaPlayerControl { 6709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project void start(); 6719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project void pause(); 6729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int getDuration(); 6739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int getCurrentPosition(); 6749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project void seekTo(int pos); 6759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project boolean isPlaying(); 6769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int getBufferPercentage(); 677c818b141ee97a7a26fe069456d4b662d06c9eaeaMarco Nelissen boolean canPause(); 678c818b141ee97a7a26fe069456d4b662d06c9eaeaMarco Nelissen boolean canSeekBackward(); 679c818b141ee97a7a26fe069456d4b662d06c9eaeaMarco Nelissen boolean canSeekForward(); 68013bfebd6b70ebfd8ad0d1aa24a92178ebff3565bMarco Nelissen 68113bfebd6b70ebfd8ad0d1aa24a92178ebff3565bMarco Nelissen /** 68213bfebd6b70ebfd8ad0d1aa24a92178ebff3565bMarco Nelissen * Get the audio session id for the player used by this VideoView. This can be used to 68313bfebd6b70ebfd8ad0d1aa24a92178ebff3565bMarco Nelissen * apply audio effects to the audio track of a video. 68413bfebd6b70ebfd8ad0d1aa24a92178ebff3565bMarco Nelissen * @return The audio session, or 0 if there was an error. 68513bfebd6b70ebfd8ad0d1aa24a92178ebff3565bMarco Nelissen */ 68613bfebd6b70ebfd8ad0d1aa24a92178ebff3565bMarco Nelissen int getAudioSessionId(); 687c818b141ee97a7a26fe069456d4b662d06c9eaeaMarco Nelissen } 6889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 689