am 9299c6cd: Ensure sample runs on Gingerbread. (DO NOT MERGE)
* commit '9299c6cdd8e5d084ef4c10e5b7f044e0ea590641': Ensure sample runs on Gingerbread. (DO NOT MERGE)
This commit is contained in:
@@ -16,16 +16,14 @@
|
|||||||
|
|
||||||
package com.example.android.supportv7.media;
|
package com.example.android.supportv7.media;
|
||||||
|
|
||||||
import com.example.android.supportv7.R;
|
|
||||||
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.net.Uri;
|
import android.net.Uri;
|
||||||
|
import android.os.Build;
|
||||||
import android.os.Handler;
|
import android.os.Handler;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
import android.media.MediaPlayer;
|
import android.media.MediaPlayer;
|
||||||
import android.view.Surface;
|
import android.view.Surface;
|
||||||
import android.view.Gravity;
|
import android.view.SurfaceHolder;
|
||||||
import android.graphics.SurfaceTexture;
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -37,7 +35,6 @@ public class MediaPlayerWrapper implements
|
|||||||
MediaPlayer.OnCompletionListener,
|
MediaPlayer.OnCompletionListener,
|
||||||
MediaPlayer.OnErrorListener,
|
MediaPlayer.OnErrorListener,
|
||||||
MediaPlayer.OnSeekCompleteListener,
|
MediaPlayer.OnSeekCompleteListener,
|
||||||
OverlayDisplayWindow.OverlayWindowListener,
|
|
||||||
MediaSessionManager.Callback {
|
MediaSessionManager.Callback {
|
||||||
private static final String TAG = "MediaPlayerWrapper";
|
private static final String TAG = "MediaPlayerWrapper";
|
||||||
private static final boolean DEBUG = false;
|
private static final boolean DEBUG = false;
|
||||||
@@ -54,6 +51,7 @@ public class MediaPlayerWrapper implements
|
|||||||
private int mState = STATE_IDLE;
|
private int mState = STATE_IDLE;
|
||||||
private Callback mCallback;
|
private Callback mCallback;
|
||||||
private Surface mSurface;
|
private Surface mSurface;
|
||||||
|
private SurfaceHolder mSurfaceHolder;
|
||||||
private int mSeekToPos;
|
private int mSeekToPos;
|
||||||
|
|
||||||
public MediaPlayerWrapper(Context context) {
|
public MediaPlayerWrapper(Context context) {
|
||||||
@@ -140,21 +138,16 @@ public class MediaPlayerWrapper implements
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//OverlayDisplayWindow listeners
|
public void setSurface(Surface surface) {
|
||||||
@Override
|
|
||||||
public void onWindowCreated(Surface surface) {
|
|
||||||
if (DEBUG) {
|
|
||||||
Log.d(TAG, "onWindowCreated");
|
|
||||||
}
|
|
||||||
mSurface = surface;
|
mSurface = surface;
|
||||||
mMediaPlayer.setSurface(surface);
|
mSurfaceHolder = null;
|
||||||
|
updateSurface();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
public void setSurface(SurfaceHolder surfaceHolder) {
|
||||||
public void onWindowDestroyed() {
|
mSurface = null;
|
||||||
if (DEBUG) {
|
mSurfaceHolder = surfaceHolder;
|
||||||
Log.d(TAG, "onWindowDestroyed");
|
updateSurface();
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//MediaPlayer Listeners
|
//MediaPlayer Listeners
|
||||||
@@ -244,9 +237,7 @@ public class MediaPlayerWrapper implements
|
|||||||
mMediaPlayer.setOnCompletionListener(this);
|
mMediaPlayer.setOnCompletionListener(this);
|
||||||
mMediaPlayer.setOnErrorListener(this);
|
mMediaPlayer.setOnErrorListener(this);
|
||||||
mMediaPlayer.setOnSeekCompleteListener(this);
|
mMediaPlayer.setOnSeekCompleteListener(this);
|
||||||
if (mSurface != null) {
|
updateSurface();
|
||||||
mMediaPlayer.setSurface(mSurface);
|
|
||||||
}
|
|
||||||
mState = STATE_IDLE;
|
mState = STATE_IDLE;
|
||||||
mSeekToPos = 0;
|
mSeekToPos = 0;
|
||||||
}
|
}
|
||||||
@@ -265,10 +256,32 @@ public class MediaPlayerWrapper implements
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void updateSurface() {
|
||||||
|
if (mSurface != null) {
|
||||||
|
// The setSurface API does not exist until V14+.
|
||||||
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH) {
|
||||||
|
ICSMediaPlayer.setSurface(mMediaPlayer, mSurface);
|
||||||
|
} else {
|
||||||
|
throw new UnsupportedOperationException("MediaPlayer does not support "
|
||||||
|
+ "setSurface() on this version of the platform.");
|
||||||
|
}
|
||||||
|
} else if (mSurfaceHolder != null) {
|
||||||
|
mMediaPlayer.setDisplay(mSurfaceHolder);
|
||||||
|
} else {
|
||||||
|
mMediaPlayer.setDisplay(null);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public static abstract class Callback {
|
public static abstract class Callback {
|
||||||
public void onError() {}
|
public void onError() {}
|
||||||
public void onCompletion() {}
|
public void onCompletion() {}
|
||||||
public void onStatusChanged() {}
|
public void onStatusChanged() {}
|
||||||
public void onSizeChanged(int width, int height) {}
|
public void onSizeChanged(int width, int height) {}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static final class ICSMediaPlayer {
|
||||||
|
public static final void setSurface(MediaPlayer player, Surface surface) {
|
||||||
|
player.setSurface(surface);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,8 +18,10 @@ package com.example.android.supportv7.media;
|
|||||||
import com.example.android.supportv7.R;
|
import com.example.android.supportv7.R;
|
||||||
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
|
import android.graphics.Point;
|
||||||
import android.graphics.SurfaceTexture;
|
import android.graphics.SurfaceTexture;
|
||||||
import android.hardware.display.DisplayManager;
|
import android.hardware.display.DisplayManager;
|
||||||
|
import android.os.Build;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
import android.view.Display;
|
import android.view.Display;
|
||||||
import android.util.DisplayMetrics;
|
import android.util.DisplayMetrics;
|
||||||
@@ -28,6 +30,8 @@ import android.view.Gravity;
|
|||||||
import android.view.LayoutInflater;
|
import android.view.LayoutInflater;
|
||||||
import android.view.MotionEvent;
|
import android.view.MotionEvent;
|
||||||
import android.view.ScaleGestureDetector;
|
import android.view.ScaleGestureDetector;
|
||||||
|
import android.view.SurfaceHolder;
|
||||||
|
import android.view.SurfaceView;
|
||||||
import android.view.TextureView;
|
import android.view.TextureView;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.view.Surface;
|
import android.view.Surface;
|
||||||
@@ -38,68 +42,38 @@ import android.widget.TextView;
|
|||||||
/**
|
/**
|
||||||
* Manages an overlay display window, used for simulating remote playback.
|
* Manages an overlay display window, used for simulating remote playback.
|
||||||
*/
|
*/
|
||||||
public class OverlayDisplayWindow {
|
public abstract class OverlayDisplayWindow {
|
||||||
private static final String TAG = "OverlayDisplayWindow";
|
private static final String TAG = "OverlayDisplayWindow";
|
||||||
private static final boolean DEBUG = false;
|
private static final boolean DEBUG = false;
|
||||||
|
|
||||||
private final float INITIAL_SCALE = 0.5f;
|
private static final float WINDOW_ALPHA = 0.8f;
|
||||||
private final float MIN_SCALE = 0.3f;
|
private static final float INITIAL_SCALE = 0.5f;
|
||||||
private final float MAX_SCALE = 1.0f;
|
private static final float MIN_SCALE = 0.3f;
|
||||||
private final float WINDOW_ALPHA = 0.8f;
|
private static final float MAX_SCALE = 1.0f;
|
||||||
|
|
||||||
// When true, disables support for moving and resizing the overlay.
|
protected final Context mContext;
|
||||||
// The window is made non-touchable, which makes it possible to
|
protected final String mName;
|
||||||
// directly interact with the content underneath.
|
protected final int mWidth;
|
||||||
private final boolean DISABLE_MOVE_AND_RESIZE = false;
|
protected final int mHeight;
|
||||||
|
protected final int mGravity;
|
||||||
|
protected OverlayWindowListener mListener;
|
||||||
|
|
||||||
private final Context mContext;
|
protected OverlayDisplayWindow(Context context, String name,
|
||||||
private final int mWidth;
|
|
||||||
private final int mHeight;
|
|
||||||
private final int mGravity;
|
|
||||||
private OverlayWindowListener mListener;
|
|
||||||
private final String mTitle;
|
|
||||||
|
|
||||||
private final DisplayManager mDisplayManager;
|
|
||||||
private final WindowManager mWindowManager;
|
|
||||||
|
|
||||||
|
|
||||||
private final Display mDefaultDisplay;
|
|
||||||
private final DisplayMetrics mDefaultDisplayMetrics = new DisplayMetrics();
|
|
||||||
|
|
||||||
private View mWindowContent;
|
|
||||||
private WindowManager.LayoutParams mWindowParams;
|
|
||||||
private TextureView mTextureView;
|
|
||||||
private TextView mTitleTextView;
|
|
||||||
|
|
||||||
private GestureDetector mGestureDetector;
|
|
||||||
private ScaleGestureDetector mScaleGestureDetector;
|
|
||||||
|
|
||||||
private boolean mWindowVisible;
|
|
||||||
private int mWindowX;
|
|
||||||
private int mWindowY;
|
|
||||||
private float mWindowScale;
|
|
||||||
|
|
||||||
private float mLiveTranslationX;
|
|
||||||
private float mLiveTranslationY;
|
|
||||||
private float mLiveScale = 1.0f;
|
|
||||||
|
|
||||||
public OverlayDisplayWindow(Context context, String name,
|
|
||||||
int width, int height, int gravity) {
|
int width, int height, int gravity) {
|
||||||
mContext = context;
|
mContext = context;
|
||||||
|
mName = name;
|
||||||
mWidth = width;
|
mWidth = width;
|
||||||
mHeight = height;
|
mHeight = height;
|
||||||
mGravity = gravity;
|
mGravity = gravity;
|
||||||
mTitle = name;
|
}
|
||||||
|
|
||||||
mDisplayManager = (DisplayManager)context.getSystemService(
|
public static OverlayDisplayWindow create(Context context, String name,
|
||||||
Context.DISPLAY_SERVICE);
|
int width, int height, int gravity) {
|
||||||
mWindowManager = (WindowManager)context.getSystemService(
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
|
||||||
Context.WINDOW_SERVICE);
|
return new JellybeanMr1Impl(context, name, width, height, gravity);
|
||||||
|
} else {
|
||||||
mDefaultDisplay = mWindowManager.getDefaultDisplay();
|
return new LegacyImpl(context, name, width, height, gravity);
|
||||||
updateDefaultDisplayInfo();
|
}
|
||||||
|
|
||||||
createWindow();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setOverlayWindowListener(OverlayWindowListener listener) {
|
public void setOverlayWindowListener(OverlayWindowListener listener) {
|
||||||
@@ -110,253 +84,378 @@ public class OverlayDisplayWindow {
|
|||||||
return mContext;
|
return mContext;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void show() {
|
public abstract void show();
|
||||||
if (!mWindowVisible) {
|
|
||||||
mDisplayManager.registerDisplayListener(mDisplayListener, null);
|
|
||||||
if (!updateDefaultDisplayInfo()) {
|
|
||||||
mDisplayManager.unregisterDisplayListener(mDisplayListener);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
clearLiveState();
|
public abstract void dismiss();
|
||||||
updateWindowParams();
|
|
||||||
mWindowManager.addView(mWindowContent, mWindowParams);
|
|
||||||
mWindowVisible = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void dismiss() {
|
public abstract void updateAspectRatio(int width, int height);
|
||||||
if (mWindowVisible) {
|
|
||||||
mDisplayManager.unregisterDisplayListener(mDisplayListener);
|
|
||||||
mWindowManager.removeView(mWindowContent);
|
|
||||||
mWindowVisible = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void relayout() {
|
|
||||||
if (mWindowVisible) {
|
|
||||||
updateWindowParams();
|
|
||||||
mWindowManager.updateViewLayout(mWindowContent, mWindowParams);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void updateAspectRatio(int width, int height) {
|
|
||||||
if (mWidth * height < mHeight * width) {
|
|
||||||
mTextureView.getLayoutParams().width = mWidth;
|
|
||||||
mTextureView.getLayoutParams().height = mWidth * height / width;
|
|
||||||
} else {
|
|
||||||
mTextureView.getLayoutParams().width = mHeight * width / height;
|
|
||||||
mTextureView.getLayoutParams().height = mHeight;
|
|
||||||
}
|
|
||||||
relayout();
|
|
||||||
}
|
|
||||||
|
|
||||||
private boolean updateDefaultDisplayInfo() {
|
|
||||||
mDefaultDisplay.getMetrics(mDefaultDisplayMetrics);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void createWindow() {
|
|
||||||
LayoutInflater inflater = LayoutInflater.from(mContext);
|
|
||||||
|
|
||||||
mWindowContent = inflater.inflate(
|
|
||||||
R.layout.overlay_display_window, null);
|
|
||||||
mWindowContent.setOnTouchListener(mOnTouchListener);
|
|
||||||
|
|
||||||
mTextureView = (TextureView)mWindowContent.findViewById(
|
|
||||||
R.id.overlay_display_window_texture);
|
|
||||||
mTextureView.setPivotX(0);
|
|
||||||
mTextureView.setPivotY(0);
|
|
||||||
mTextureView.getLayoutParams().width = mWidth;
|
|
||||||
mTextureView.getLayoutParams().height = mHeight;
|
|
||||||
mTextureView.setOpaque(false);
|
|
||||||
mTextureView.setSurfaceTextureListener(mSurfaceTextureListener);
|
|
||||||
|
|
||||||
mTitleTextView = (TextView)mWindowContent.findViewById(
|
|
||||||
R.id.overlay_display_window_title);
|
|
||||||
mTitleTextView.setText(mTitle);
|
|
||||||
|
|
||||||
mWindowParams = new WindowManager.LayoutParams(
|
|
||||||
WindowManager.LayoutParams.TYPE_SYSTEM_ALERT);
|
|
||||||
mWindowParams.flags |= WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN
|
|
||||||
| WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS
|
|
||||||
| WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
|
|
||||||
| WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL
|
|
||||||
| WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED;
|
|
||||||
if (DISABLE_MOVE_AND_RESIZE) {
|
|
||||||
mWindowParams.flags |= WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
|
|
||||||
}
|
|
||||||
mWindowParams.alpha = WINDOW_ALPHA;
|
|
||||||
mWindowParams.gravity = Gravity.TOP | Gravity.LEFT;
|
|
||||||
mWindowParams.setTitle(mTitle);
|
|
||||||
|
|
||||||
mGestureDetector = new GestureDetector(mContext, mOnGestureListener);
|
|
||||||
mScaleGestureDetector = new ScaleGestureDetector(mContext, mOnScaleGestureListener);
|
|
||||||
|
|
||||||
// Set the initial position and scale.
|
|
||||||
// The position and scale will be clamped when the display is first shown.
|
|
||||||
mWindowX = (mGravity & Gravity.LEFT) == Gravity.LEFT ?
|
|
||||||
0 : mDefaultDisplayMetrics.widthPixels;
|
|
||||||
mWindowY = (mGravity & Gravity.TOP) == Gravity.TOP ?
|
|
||||||
0 : mDefaultDisplayMetrics.heightPixels;
|
|
||||||
Log.d(TAG, mDefaultDisplayMetrics.toString());
|
|
||||||
mWindowScale = INITIAL_SCALE;
|
|
||||||
|
|
||||||
// calculate and save initial settings
|
|
||||||
updateWindowParams();
|
|
||||||
saveWindowParams();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void updateWindowParams() {
|
|
||||||
float scale = mWindowScale * mLiveScale;
|
|
||||||
scale = Math.min(scale, (float)mDefaultDisplayMetrics.widthPixels / mWidth);
|
|
||||||
scale = Math.min(scale, (float)mDefaultDisplayMetrics.heightPixels / mHeight);
|
|
||||||
scale = Math.max(MIN_SCALE, Math.min(MAX_SCALE, scale));
|
|
||||||
|
|
||||||
float offsetScale = (scale / mWindowScale - 1.0f) * 0.5f;
|
|
||||||
int width = (int)(mWidth * scale);
|
|
||||||
int height = (int)(mHeight * scale);
|
|
||||||
int x = (int)(mWindowX + mLiveTranslationX - width * offsetScale);
|
|
||||||
int y = (int)(mWindowY + mLiveTranslationY - height * offsetScale);
|
|
||||||
x = Math.max(0, Math.min(x, mDefaultDisplayMetrics.widthPixels - width));
|
|
||||||
y = Math.max(0, Math.min(y, mDefaultDisplayMetrics.heightPixels - height));
|
|
||||||
|
|
||||||
if (DEBUG) {
|
|
||||||
Log.d(TAG, "updateWindowParams: scale=" + scale
|
|
||||||
+ ", offsetScale=" + offsetScale
|
|
||||||
+ ", x=" + x + ", y=" + y
|
|
||||||
+ ", width=" + width + ", height=" + height);
|
|
||||||
}
|
|
||||||
|
|
||||||
mTextureView.setScaleX(scale);
|
|
||||||
mTextureView.setScaleY(scale);
|
|
||||||
|
|
||||||
mTextureView.setTranslationX(
|
|
||||||
(mWidth - mTextureView.getLayoutParams().width) * scale / 2);
|
|
||||||
mTextureView.setTranslationY(
|
|
||||||
(mHeight - mTextureView.getLayoutParams().height) * scale / 2);
|
|
||||||
|
|
||||||
mWindowParams.x = x;
|
|
||||||
mWindowParams.y = y;
|
|
||||||
mWindowParams.width = width;
|
|
||||||
mWindowParams.height = height;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void saveWindowParams() {
|
|
||||||
mWindowX = mWindowParams.x;
|
|
||||||
mWindowY = mWindowParams.y;
|
|
||||||
mWindowScale = mTextureView.getScaleX();
|
|
||||||
clearLiveState();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void clearLiveState() {
|
|
||||||
mLiveTranslationX = 0f;
|
|
||||||
mLiveTranslationY = 0f;
|
|
||||||
mLiveScale = 1.0f;
|
|
||||||
}
|
|
||||||
|
|
||||||
private final DisplayManager.DisplayListener mDisplayListener =
|
|
||||||
new DisplayManager.DisplayListener() {
|
|
||||||
@Override
|
|
||||||
public void onDisplayAdded(int displayId) {
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onDisplayChanged(int displayId) {
|
|
||||||
if (displayId == mDefaultDisplay.getDisplayId()) {
|
|
||||||
if (updateDefaultDisplayInfo()) {
|
|
||||||
relayout();
|
|
||||||
} else {
|
|
||||||
dismiss();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onDisplayRemoved(int displayId) {
|
|
||||||
if (displayId == mDefaultDisplay.getDisplayId()) {
|
|
||||||
dismiss();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
private final SurfaceTextureListener mSurfaceTextureListener =
|
|
||||||
new SurfaceTextureListener() {
|
|
||||||
@Override
|
|
||||||
public void onSurfaceTextureAvailable(SurfaceTexture surfaceTexture,
|
|
||||||
int width, int height) {
|
|
||||||
if (mListener != null) {
|
|
||||||
mListener.onWindowCreated(new Surface(surfaceTexture));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean onSurfaceTextureDestroyed(SurfaceTexture surfaceTexture) {
|
|
||||||
if (mListener != null) {
|
|
||||||
mListener.onWindowDestroyed();
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onSurfaceTextureSizeChanged(SurfaceTexture surfaceTexture,
|
|
||||||
int width, int height) {
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onSurfaceTextureUpdated(SurfaceTexture surfaceTexture) {
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
private final View.OnTouchListener mOnTouchListener = new View.OnTouchListener() {
|
|
||||||
@Override
|
|
||||||
public boolean onTouch(View view, MotionEvent event) {
|
|
||||||
// Work in screen coordinates.
|
|
||||||
final float oldX = event.getX();
|
|
||||||
final float oldY = event.getY();
|
|
||||||
event.setLocation(event.getRawX(), event.getRawY());
|
|
||||||
|
|
||||||
mGestureDetector.onTouchEvent(event);
|
|
||||||
mScaleGestureDetector.onTouchEvent(event);
|
|
||||||
|
|
||||||
switch (event.getActionMasked()) {
|
|
||||||
case MotionEvent.ACTION_UP:
|
|
||||||
case MotionEvent.ACTION_CANCEL:
|
|
||||||
saveWindowParams();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Revert to window coordinates.
|
|
||||||
event.setLocation(oldX, oldY);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
private final GestureDetector.OnGestureListener mOnGestureListener =
|
|
||||||
new GestureDetector.SimpleOnGestureListener() {
|
|
||||||
@Override
|
|
||||||
public boolean onScroll(MotionEvent e1, MotionEvent e2,
|
|
||||||
float distanceX, float distanceY) {
|
|
||||||
mLiveTranslationX -= distanceX;
|
|
||||||
mLiveTranslationY -= distanceY;
|
|
||||||
relayout();
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
private final ScaleGestureDetector.OnScaleGestureListener mOnScaleGestureListener =
|
|
||||||
new ScaleGestureDetector.SimpleOnScaleGestureListener() {
|
|
||||||
@Override
|
|
||||||
public boolean onScale(ScaleGestureDetector detector) {
|
|
||||||
mLiveScale *= detector.getScaleFactor();
|
|
||||||
relayout();
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// Watches for significant changes in the overlay display window lifecycle.
|
// Watches for significant changes in the overlay display window lifecycle.
|
||||||
public interface OverlayWindowListener {
|
public interface OverlayWindowListener {
|
||||||
public void onWindowCreated(Surface surface);
|
public void onWindowCreated(Surface surface);
|
||||||
|
public void onWindowCreated(SurfaceHolder surfaceHolder);
|
||||||
public void onWindowDestroyed();
|
public void onWindowDestroyed();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Implementation for older versions.
|
||||||
|
*/
|
||||||
|
private static final class LegacyImpl extends OverlayDisplayWindow {
|
||||||
|
private final WindowManager mWindowManager;
|
||||||
|
|
||||||
|
private boolean mWindowVisible;
|
||||||
|
private SurfaceView mSurfaceView;
|
||||||
|
|
||||||
|
public LegacyImpl(Context context, String name,
|
||||||
|
int width, int height, int gravity) {
|
||||||
|
super(context, name, width, height, gravity);
|
||||||
|
|
||||||
|
mWindowManager = (WindowManager)context.getSystemService(
|
||||||
|
Context.WINDOW_SERVICE);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void show() {
|
||||||
|
if (!mWindowVisible) {
|
||||||
|
mSurfaceView = new SurfaceView(mContext);
|
||||||
|
|
||||||
|
Display display = mWindowManager.getDefaultDisplay();
|
||||||
|
|
||||||
|
WindowManager.LayoutParams params = new WindowManager.LayoutParams(
|
||||||
|
WindowManager.LayoutParams.TYPE_SYSTEM_ALERT);
|
||||||
|
params.flags |= WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN
|
||||||
|
| WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS
|
||||||
|
| WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
|
||||||
|
| WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL
|
||||||
|
| WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
|
||||||
|
params.alpha = WINDOW_ALPHA;
|
||||||
|
params.gravity = Gravity.LEFT | Gravity.BOTTOM;
|
||||||
|
params.setTitle(mName);
|
||||||
|
|
||||||
|
int width = (int)(display.getWidth() * INITIAL_SCALE);
|
||||||
|
int height = (int)(display.getHeight() * INITIAL_SCALE);
|
||||||
|
if (mWidth > mHeight) {
|
||||||
|
height = mHeight * width / mWidth;
|
||||||
|
} else {
|
||||||
|
width = mWidth * height / mHeight;
|
||||||
|
}
|
||||||
|
params.width = width;
|
||||||
|
params.height = height;
|
||||||
|
|
||||||
|
mWindowManager.addView(mSurfaceView, params);
|
||||||
|
mWindowVisible = true;
|
||||||
|
|
||||||
|
mListener.onWindowCreated(mSurfaceView.getHolder());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void dismiss() {
|
||||||
|
if (mWindowVisible) {
|
||||||
|
mListener.onWindowDestroyed();
|
||||||
|
|
||||||
|
mWindowManager.removeView(mSurfaceView);
|
||||||
|
mWindowVisible = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void updateAspectRatio(int width, int height) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Implementation for API version 17+.
|
||||||
|
*/
|
||||||
|
private static final class JellybeanMr1Impl extends OverlayDisplayWindow {
|
||||||
|
// When true, disables support for moving and resizing the overlay.
|
||||||
|
// The window is made non-touchable, which makes it possible to
|
||||||
|
// directly interact with the content underneath.
|
||||||
|
private static final boolean DISABLE_MOVE_AND_RESIZE = false;
|
||||||
|
|
||||||
|
private final DisplayManager mDisplayManager;
|
||||||
|
private final WindowManager mWindowManager;
|
||||||
|
|
||||||
|
private final Display mDefaultDisplay;
|
||||||
|
private final DisplayMetrics mDefaultDisplayMetrics = new DisplayMetrics();
|
||||||
|
|
||||||
|
private View mWindowContent;
|
||||||
|
private WindowManager.LayoutParams mWindowParams;
|
||||||
|
private TextureView mTextureView;
|
||||||
|
private TextView mNameTextView;
|
||||||
|
|
||||||
|
private GestureDetector mGestureDetector;
|
||||||
|
private ScaleGestureDetector mScaleGestureDetector;
|
||||||
|
|
||||||
|
private boolean mWindowVisible;
|
||||||
|
private int mWindowX;
|
||||||
|
private int mWindowY;
|
||||||
|
private float mWindowScale;
|
||||||
|
|
||||||
|
private float mLiveTranslationX;
|
||||||
|
private float mLiveTranslationY;
|
||||||
|
private float mLiveScale = 1.0f;
|
||||||
|
|
||||||
|
public JellybeanMr1Impl(Context context, String name,
|
||||||
|
int width, int height, int gravity) {
|
||||||
|
super(context, name, width, height, gravity);
|
||||||
|
|
||||||
|
mDisplayManager = (DisplayManager)context.getSystemService(
|
||||||
|
Context.DISPLAY_SERVICE);
|
||||||
|
mWindowManager = (WindowManager)context.getSystemService(
|
||||||
|
Context.WINDOW_SERVICE);
|
||||||
|
|
||||||
|
mDefaultDisplay = mWindowManager.getDefaultDisplay();
|
||||||
|
updateDefaultDisplayInfo();
|
||||||
|
|
||||||
|
createWindow();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void show() {
|
||||||
|
if (!mWindowVisible) {
|
||||||
|
mDisplayManager.registerDisplayListener(mDisplayListener, null);
|
||||||
|
if (!updateDefaultDisplayInfo()) {
|
||||||
|
mDisplayManager.unregisterDisplayListener(mDisplayListener);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
clearLiveState();
|
||||||
|
updateWindowParams();
|
||||||
|
mWindowManager.addView(mWindowContent, mWindowParams);
|
||||||
|
mWindowVisible = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void dismiss() {
|
||||||
|
if (mWindowVisible) {
|
||||||
|
mDisplayManager.unregisterDisplayListener(mDisplayListener);
|
||||||
|
mWindowManager.removeView(mWindowContent);
|
||||||
|
mWindowVisible = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void updateAspectRatio(int width, int height) {
|
||||||
|
if (mWidth * height < mHeight * width) {
|
||||||
|
mTextureView.getLayoutParams().width = mWidth;
|
||||||
|
mTextureView.getLayoutParams().height = mWidth * height / width;
|
||||||
|
} else {
|
||||||
|
mTextureView.getLayoutParams().width = mHeight * width / height;
|
||||||
|
mTextureView.getLayoutParams().height = mHeight;
|
||||||
|
}
|
||||||
|
relayout();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void relayout() {
|
||||||
|
if (mWindowVisible) {
|
||||||
|
updateWindowParams();
|
||||||
|
mWindowManager.updateViewLayout(mWindowContent, mWindowParams);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean updateDefaultDisplayInfo() {
|
||||||
|
mDefaultDisplay.getMetrics(mDefaultDisplayMetrics);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void createWindow() {
|
||||||
|
LayoutInflater inflater = LayoutInflater.from(mContext);
|
||||||
|
|
||||||
|
mWindowContent = inflater.inflate(
|
||||||
|
R.layout.overlay_display_window, null);
|
||||||
|
mWindowContent.setOnTouchListener(mOnTouchListener);
|
||||||
|
|
||||||
|
mTextureView = (TextureView)mWindowContent.findViewById(
|
||||||
|
R.id.overlay_display_window_texture);
|
||||||
|
mTextureView.setPivotX(0);
|
||||||
|
mTextureView.setPivotY(0);
|
||||||
|
mTextureView.getLayoutParams().width = mWidth;
|
||||||
|
mTextureView.getLayoutParams().height = mHeight;
|
||||||
|
mTextureView.setOpaque(false);
|
||||||
|
mTextureView.setSurfaceTextureListener(mSurfaceTextureListener);
|
||||||
|
|
||||||
|
mNameTextView = (TextView)mWindowContent.findViewById(
|
||||||
|
R.id.overlay_display_window_title);
|
||||||
|
mNameTextView.setText(mName);
|
||||||
|
|
||||||
|
mWindowParams = new WindowManager.LayoutParams(
|
||||||
|
WindowManager.LayoutParams.TYPE_SYSTEM_ALERT);
|
||||||
|
mWindowParams.flags |= WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN
|
||||||
|
| WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS
|
||||||
|
| WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
|
||||||
|
| WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL
|
||||||
|
| WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED;
|
||||||
|
if (DISABLE_MOVE_AND_RESIZE) {
|
||||||
|
mWindowParams.flags |= WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
|
||||||
|
}
|
||||||
|
mWindowParams.alpha = WINDOW_ALPHA;
|
||||||
|
mWindowParams.gravity = Gravity.TOP | Gravity.LEFT;
|
||||||
|
mWindowParams.setTitle(mName);
|
||||||
|
|
||||||
|
mGestureDetector = new GestureDetector(mContext, mOnGestureListener);
|
||||||
|
mScaleGestureDetector = new ScaleGestureDetector(mContext, mOnScaleGestureListener);
|
||||||
|
|
||||||
|
// Set the initial position and scale.
|
||||||
|
// The position and scale will be clamped when the display is first shown.
|
||||||
|
mWindowX = (mGravity & Gravity.LEFT) == Gravity.LEFT ?
|
||||||
|
0 : mDefaultDisplayMetrics.widthPixels;
|
||||||
|
mWindowY = (mGravity & Gravity.TOP) == Gravity.TOP ?
|
||||||
|
0 : mDefaultDisplayMetrics.heightPixels;
|
||||||
|
Log.d(TAG, mDefaultDisplayMetrics.toString());
|
||||||
|
mWindowScale = INITIAL_SCALE;
|
||||||
|
|
||||||
|
// calculate and save initial settings
|
||||||
|
updateWindowParams();
|
||||||
|
saveWindowParams();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void updateWindowParams() {
|
||||||
|
float scale = mWindowScale * mLiveScale;
|
||||||
|
scale = Math.min(scale, (float)mDefaultDisplayMetrics.widthPixels / mWidth);
|
||||||
|
scale = Math.min(scale, (float)mDefaultDisplayMetrics.heightPixels / mHeight);
|
||||||
|
scale = Math.max(MIN_SCALE, Math.min(MAX_SCALE, scale));
|
||||||
|
|
||||||
|
float offsetScale = (scale / mWindowScale - 1.0f) * 0.5f;
|
||||||
|
int width = (int)(mWidth * scale);
|
||||||
|
int height = (int)(mHeight * scale);
|
||||||
|
int x = (int)(mWindowX + mLiveTranslationX - width * offsetScale);
|
||||||
|
int y = (int)(mWindowY + mLiveTranslationY - height * offsetScale);
|
||||||
|
x = Math.max(0, Math.min(x, mDefaultDisplayMetrics.widthPixels - width));
|
||||||
|
y = Math.max(0, Math.min(y, mDefaultDisplayMetrics.heightPixels - height));
|
||||||
|
|
||||||
|
if (DEBUG) {
|
||||||
|
Log.d(TAG, "updateWindowParams: scale=" + scale
|
||||||
|
+ ", offsetScale=" + offsetScale
|
||||||
|
+ ", x=" + x + ", y=" + y
|
||||||
|
+ ", width=" + width + ", height=" + height);
|
||||||
|
}
|
||||||
|
|
||||||
|
mTextureView.setScaleX(scale);
|
||||||
|
mTextureView.setScaleY(scale);
|
||||||
|
|
||||||
|
mTextureView.setTranslationX(
|
||||||
|
(mWidth - mTextureView.getLayoutParams().width) * scale / 2);
|
||||||
|
mTextureView.setTranslationY(
|
||||||
|
(mHeight - mTextureView.getLayoutParams().height) * scale / 2);
|
||||||
|
|
||||||
|
mWindowParams.x = x;
|
||||||
|
mWindowParams.y = y;
|
||||||
|
mWindowParams.width = width;
|
||||||
|
mWindowParams.height = height;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void saveWindowParams() {
|
||||||
|
mWindowX = mWindowParams.x;
|
||||||
|
mWindowY = mWindowParams.y;
|
||||||
|
mWindowScale = mTextureView.getScaleX();
|
||||||
|
clearLiveState();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void clearLiveState() {
|
||||||
|
mLiveTranslationX = 0f;
|
||||||
|
mLiveTranslationY = 0f;
|
||||||
|
mLiveScale = 1.0f;
|
||||||
|
}
|
||||||
|
|
||||||
|
private final DisplayManager.DisplayListener mDisplayListener =
|
||||||
|
new DisplayManager.DisplayListener() {
|
||||||
|
@Override
|
||||||
|
public void onDisplayAdded(int displayId) {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onDisplayChanged(int displayId) {
|
||||||
|
if (displayId == mDefaultDisplay.getDisplayId()) {
|
||||||
|
if (updateDefaultDisplayInfo()) {
|
||||||
|
relayout();
|
||||||
|
} else {
|
||||||
|
dismiss();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onDisplayRemoved(int displayId) {
|
||||||
|
if (displayId == mDefaultDisplay.getDisplayId()) {
|
||||||
|
dismiss();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
private final SurfaceTextureListener mSurfaceTextureListener =
|
||||||
|
new SurfaceTextureListener() {
|
||||||
|
@Override
|
||||||
|
public void onSurfaceTextureAvailable(SurfaceTexture surfaceTexture,
|
||||||
|
int width, int height) {
|
||||||
|
if (mListener != null) {
|
||||||
|
mListener.onWindowCreated(new Surface(surfaceTexture));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean onSurfaceTextureDestroyed(SurfaceTexture surfaceTexture) {
|
||||||
|
if (mListener != null) {
|
||||||
|
mListener.onWindowDestroyed();
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onSurfaceTextureSizeChanged(SurfaceTexture surfaceTexture,
|
||||||
|
int width, int height) {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onSurfaceTextureUpdated(SurfaceTexture surfaceTexture) {
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
private final View.OnTouchListener mOnTouchListener = new View.OnTouchListener() {
|
||||||
|
@Override
|
||||||
|
public boolean onTouch(View view, MotionEvent event) {
|
||||||
|
// Work in screen coordinates.
|
||||||
|
final float oldX = event.getX();
|
||||||
|
final float oldY = event.getY();
|
||||||
|
event.setLocation(event.getRawX(), event.getRawY());
|
||||||
|
|
||||||
|
mGestureDetector.onTouchEvent(event);
|
||||||
|
mScaleGestureDetector.onTouchEvent(event);
|
||||||
|
|
||||||
|
switch (event.getActionMasked()) {
|
||||||
|
case MotionEvent.ACTION_UP:
|
||||||
|
case MotionEvent.ACTION_CANCEL:
|
||||||
|
saveWindowParams();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Revert to window coordinates.
|
||||||
|
event.setLocation(oldX, oldY);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
private final GestureDetector.OnGestureListener mOnGestureListener =
|
||||||
|
new GestureDetector.SimpleOnGestureListener() {
|
||||||
|
@Override
|
||||||
|
public boolean onScroll(MotionEvent e1, MotionEvent e2,
|
||||||
|
float distanceX, float distanceY) {
|
||||||
|
mLiveTranslationX -= distanceX;
|
||||||
|
mLiveTranslationY -= distanceY;
|
||||||
|
relayout();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
private final ScaleGestureDetector.OnScaleGestureListener mOnScaleGestureListener =
|
||||||
|
new ScaleGestureDetector.SimpleOnScaleGestureListener() {
|
||||||
|
@Override
|
||||||
|
public boolean onScale(ScaleGestureDetector detector) {
|
||||||
|
mLiveScale *= detector.getScaleFactor();
|
||||||
|
relayout();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -35,8 +35,10 @@ import android.support.v7.media.MediaRouter.ControlRequestCallback;
|
|||||||
import android.support.v7.media.MediaRouteProviderDescriptor;
|
import android.support.v7.media.MediaRouteProviderDescriptor;
|
||||||
import android.support.v7.media.MediaRouteDescriptor;
|
import android.support.v7.media.MediaRouteDescriptor;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
import android.widget.Toast;
|
|
||||||
import android.view.Gravity;
|
import android.view.Gravity;
|
||||||
|
import android.view.Surface;
|
||||||
|
import android.view.SurfaceHolder;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -188,26 +190,39 @@ final class SampleMediaRouteProvider extends MediaRouteProvider {
|
|||||||
setDescriptor(providerDescriptor);
|
setDescriptor(providerDescriptor);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void showToast(String msg) {
|
|
||||||
Toast toast = Toast.makeText(getContext(),
|
|
||||||
"[provider] " + msg, Toast.LENGTH_LONG);
|
|
||||||
toast.setGravity(Gravity.TOP, 0, 100);
|
|
||||||
toast.show();
|
|
||||||
}
|
|
||||||
|
|
||||||
private final class SampleRouteController extends MediaRouteProvider.RouteController {
|
private final class SampleRouteController extends MediaRouteProvider.RouteController {
|
||||||
private final String mRouteId;
|
private final String mRouteId;
|
||||||
// Create an overlay display window (used for simulating the remote playback only)
|
private final OverlayDisplayWindow mOverlay;
|
||||||
private final OverlayDisplayWindow mOverlay = new OverlayDisplayWindow(getContext(),
|
private final MediaPlayerWrapper mMediaPlayer;
|
||||||
getContext().getResources().getString(R.string.sample_media_route_provider_remote),
|
private final MediaSessionManager mSessionManager;
|
||||||
1024, 768, Gravity.CENTER);
|
|
||||||
private final MediaPlayerWrapper mMediaPlayer = new MediaPlayerWrapper(getContext());
|
|
||||||
private final MediaSessionManager mSessionManager = new MediaSessionManager();
|
|
||||||
|
|
||||||
public SampleRouteController(String routeId) {
|
public SampleRouteController(String routeId) {
|
||||||
mRouteId = routeId;
|
mRouteId = routeId;
|
||||||
|
mMediaPlayer = new MediaPlayerWrapper(getContext());
|
||||||
|
mSessionManager = new MediaSessionManager();
|
||||||
mSessionManager.setCallback(mMediaPlayer);
|
mSessionManager.setCallback(mMediaPlayer);
|
||||||
mOverlay.setOverlayWindowListener(mMediaPlayer);
|
|
||||||
|
// Create an overlay display window (used for simulating the remote playback only)
|
||||||
|
mOverlay = OverlayDisplayWindow.create(getContext(),
|
||||||
|
getContext().getResources().getString(
|
||||||
|
R.string.sample_media_route_provider_remote),
|
||||||
|
1024, 768, Gravity.CENTER);
|
||||||
|
mOverlay.setOverlayWindowListener(new OverlayDisplayWindow.OverlayWindowListener() {
|
||||||
|
@Override
|
||||||
|
public void onWindowCreated(Surface surface) {
|
||||||
|
mMediaPlayer.setSurface(surface);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onWindowCreated(SurfaceHolder surfaceHolder) {
|
||||||
|
mMediaPlayer.setSurface(surfaceHolder);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onWindowDestroyed() {
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
mMediaPlayer.setCallback(new MediaPlayerCallback());
|
mMediaPlayer.setCallback(new MediaPlayerCallback());
|
||||||
Log.d(TAG, mRouteId + ": Controller created");
|
Log.d(TAG, mRouteId + ": Controller created");
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -31,7 +31,6 @@ import android.media.AudioManager;
|
|||||||
import android.media.AudioManager.OnAudioFocusChangeListener;
|
import android.media.AudioManager.OnAudioFocusChangeListener;
|
||||||
import android.media.MediaMetadataRetriever;
|
import android.media.MediaMetadataRetriever;
|
||||||
import android.media.RemoteControlClient;
|
import android.media.RemoteControlClient;
|
||||||
import android.media.RemoteControlClient.MetadataEditor;
|
|
||||||
import android.net.Uri;
|
import android.net.Uri;
|
||||||
import android.os.Build;
|
import android.os.Build;
|
||||||
import android.os.Handler;
|
import android.os.Handler;
|
||||||
@@ -58,14 +57,12 @@ import android.view.View;
|
|||||||
import android.view.View.OnClickListener;
|
import android.view.View.OnClickListener;
|
||||||
import android.view.ViewGroup;
|
import android.view.ViewGroup;
|
||||||
import android.view.Display;
|
import android.view.Display;
|
||||||
import android.view.Surface;
|
|
||||||
import android.view.SurfaceView;
|
import android.view.SurfaceView;
|
||||||
import android.view.SurfaceHolder;
|
import android.view.SurfaceHolder;
|
||||||
import android.view.WindowManager;
|
import android.view.WindowManager;
|
||||||
import android.widget.AdapterView;
|
import android.widget.AdapterView;
|
||||||
import android.widget.AdapterView.OnItemClickListener;
|
import android.widget.AdapterView.OnItemClickListener;
|
||||||
import android.widget.ArrayAdapter;
|
import android.widget.ArrayAdapter;
|
||||||
import android.widget.Button;
|
|
||||||
import android.widget.ImageButton;
|
import android.widget.ImageButton;
|
||||||
import android.widget.ListView;
|
import android.widget.ListView;
|
||||||
import android.widget.TextView;
|
import android.widget.TextView;
|
||||||
@@ -78,8 +75,6 @@ import android.widget.SeekBar;
|
|||||||
import android.widget.SeekBar.OnSeekBarChangeListener;
|
import android.widget.SeekBar.OnSeekBarChangeListener;
|
||||||
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -898,7 +893,7 @@ public class SampleMediaRouterActivity extends ActionBarActivity {
|
|||||||
public void onFinish(boolean error) {
|
public void onFinish(boolean error) {
|
||||||
MediaQueueItem item = mSessionManager.finish(error);
|
MediaQueueItem item = mSessionManager.finish(error);
|
||||||
updateUi();
|
updateUi();
|
||||||
if (error) {
|
if (error && item != null) {
|
||||||
showToast("Failed to play item " + item.getUri());
|
showToast("Failed to play item " + item.getUri());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -908,13 +903,13 @@ public class SampleMediaRouterActivity extends ActionBarActivity {
|
|||||||
public void surfaceChanged(SurfaceHolder holder, int format,
|
public void surfaceChanged(SurfaceHolder holder, int format,
|
||||||
int width, int height) {
|
int width, int height) {
|
||||||
Log.d(TAG, "surfaceChanged "+width+"x"+height);
|
Log.d(TAG, "surfaceChanged "+width+"x"+height);
|
||||||
mMediaPlayer.onWindowCreated(holder.getSurface());
|
mMediaPlayer.setSurface(holder);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void surfaceCreated(SurfaceHolder holder) {
|
public void surfaceCreated(SurfaceHolder holder) {
|
||||||
Log.d(TAG, "surfaceCreated");
|
Log.d(TAG, "surfaceCreated");
|
||||||
mMediaPlayer.onWindowCreated(holder.getSurface());
|
mMediaPlayer.setSurface(holder);
|
||||||
mLocalPlayer.updateSize(mVideoWidth, mVideoHeight);
|
mLocalPlayer.updateSize(mVideoWidth, mVideoHeight);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1007,7 +1002,7 @@ public class SampleMediaRouterActivity extends ActionBarActivity {
|
|||||||
};
|
};
|
||||||
|
|
||||||
private final class DemoPresentation extends Presentation {
|
private final class DemoPresentation extends Presentation {
|
||||||
private SurfaceView mSurfaceView;
|
private SurfaceView mPresentationSurfaceView;
|
||||||
|
|
||||||
public DemoPresentation(Context context, Display display) {
|
public DemoPresentation(Context context, Display display) {
|
||||||
super(context, display);
|
super(context, display);
|
||||||
@@ -1026,16 +1021,16 @@ public class SampleMediaRouterActivity extends ActionBarActivity {
|
|||||||
// Inflate the layout.
|
// Inflate the layout.
|
||||||
setContentView(R.layout.sample_media_router_presentation);
|
setContentView(R.layout.sample_media_router_presentation);
|
||||||
|
|
||||||
// Set up the surface view for visual interest.
|
// Set up the surface view.
|
||||||
mSurfaceView = (SurfaceView)findViewById(R.id.surface_view);
|
mPresentationSurfaceView = (SurfaceView)findViewById(R.id.surface_view);
|
||||||
SurfaceHolder holder = mSurfaceView.getHolder();
|
SurfaceHolder holder = mPresentationSurfaceView.getHolder();
|
||||||
holder.addCallback(mLocalPlayer);
|
holder.addCallback(mLocalPlayer);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void updateSize(int width, int height) {
|
public void updateSize(int width, int height) {
|
||||||
int surfaceHeight=getWindow().getDecorView().getHeight();
|
int surfaceHeight = getWindow().getDecorView().getHeight();
|
||||||
int surfaceWidth=getWindow().getDecorView().getWidth();
|
int surfaceWidth = getWindow().getDecorView().getWidth();
|
||||||
ViewGroup.LayoutParams lp = mSurfaceView.getLayoutParams();
|
ViewGroup.LayoutParams lp = mPresentationSurfaceView.getLayoutParams();
|
||||||
if (surfaceWidth * height < surfaceHeight * width) {
|
if (surfaceWidth * height < surfaceHeight * width) {
|
||||||
lp.width = surfaceWidth;
|
lp.width = surfaceWidth;
|
||||||
lp.height = surfaceWidth * height / width;
|
lp.height = surfaceWidth * height / width;
|
||||||
@@ -1043,12 +1038,8 @@ public class SampleMediaRouterActivity extends ActionBarActivity {
|
|||||||
lp.width = surfaceHeight * width / height;
|
lp.width = surfaceHeight * width / height;
|
||||||
lp.height = surfaceHeight;
|
lp.height = surfaceHeight;
|
||||||
}
|
}
|
||||||
Log.d(TAG, "video rect is "+lp.width+"x"+lp.height);
|
Log.d(TAG, "video rect is " + lp.width + "x" + lp.height);
|
||||||
mSurfaceView.setLayoutParams(lp);
|
mPresentationSurfaceView.setLayoutParams(lp);
|
||||||
}
|
|
||||||
|
|
||||||
public void clearContent() {
|
|
||||||
//TO-DO: clear surface view
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user