OSDN Git Service

Add a method in TIS to relayout SurfaceView
authorYoungsang Cho <youngsang@google.com>
Wed, 2 Jul 2014 08:08:23 +0000 (17:08 +0900)
committerYoungsang Cho <youngsang@google.com>
Wed, 6 Aug 2014 05:53:28 +0000 (14:53 +0900)
Bug: 15389458
Change-Id: I7f740141e7cf59fea5d321099652e65bc9e5f7d1

media/java/android/media/tv/ITvInputClient.aidl
media/java/android/media/tv/ITvInputSessionCallback.aidl
media/java/android/media/tv/TvInputManager.java
media/java/android/media/tv/TvInputService.java
media/java/android/media/tv/TvView.java
services/core/java/com/android/server/tv/TvInputManagerService.java

index 37c7553..7a023d6 100644 (file)
@@ -39,4 +39,5 @@ oneway interface ITvInputClient {
     void onVideoUnavailable(int reason, int seq);
     void onContentAllowed(int seq);
     void onContentBlocked(in String rating, int seq);
+    void onLayoutSurface(int left, int top, int right, int bottom, int seq);
 }
index 8a918e1..063d10d 100644 (file)
@@ -36,4 +36,5 @@ oneway interface ITvInputSessionCallback {
     void onVideoUnavailable(int reason);
     void onContentAllowed();
     void onContentBlocked(in String rating);
+    void onLayoutSurface(int left, int top, int right, int bottom);
 }
index fdf0d9c..d556369 100644 (file)
@@ -235,6 +235,21 @@ public final class TvInputManager {
         }
 
         /**
+         * This is called when {@link TvInputService.Session#layoutSurface} is called to
+         * change the layout of surface.
+         *
+         * @param session A {@link TvInputManager.Session} associated with this callback
+         * @param l Left position.
+         * @param t Top position.
+         * @param r Right position.
+         * @param b Bottom position.
+         * @hide
+         */
+        @SystemApi
+        public void onLayoutSurface(Session session, int left, int top, int right, int bottom) {
+        }
+
+        /**
          * This is called when a custom event has been sent from this session.
          *
          * @param session A {@link TvInputManager.Session} associated with this callback
@@ -364,6 +379,16 @@ public final class TvInputManager {
             });
         }
 
+        public void postLayoutSurface(final int left, final int top, final int right,
+                final int bottom) {
+            mHandler.post(new Runnable() {
+                @Override
+                public void run() {
+                    mSessionCallback.onLayoutSurface(mSession, left, top, right, bottom);
+                }
+            });
+        }
+
         public void postSessionEvent(final String eventType, final Bundle eventArgs) {
             mHandler.post(new Runnable() {
                 @Override
@@ -574,6 +599,18 @@ public final class TvInputManager {
             }
 
             @Override
+            public void onLayoutSurface(int left, int top, int right, int bottom, int seq) {
+                synchronized (mSessionCallbackRecordMap) {
+                    SessionCallbackRecord record = mSessionCallbackRecordMap.get(seq);
+                    if (record == null) {
+                        Log.e(TAG, "Callback not found for seq " + seq);
+                        return;
+                    }
+                    record.postLayoutSurface(left, top, right, bottom);
+                }
+            }
+
+            @Override
             public void onSessionEvent(String eventType, Bundle eventArgs, int seq) {
                 synchronized (mSessionCallbackRecordMap) {
                     SessionCallbackRecord record = mSessionCallbackRecordMap.get(seq);
index 642993a..3a188ab 100644 (file)
@@ -42,6 +42,7 @@ import android.view.InputEventReceiver;
 import android.view.KeyEvent;
 import android.view.MotionEvent;
 import android.view.Surface;
+import android.view.SurfaceView;
 import android.view.View;
 import android.view.WindowManager;
 import android.view.accessibility.CaptioningManager;
@@ -504,6 +505,35 @@ public abstract class TvInputService extends Service {
         }
 
         /**
+         * Assigns a position of the {@link Surface} passed by {@link #onSetSurface}. The position
+         * is relative to an overlay view. {@see #onOverlayViewSizeChanged}.
+         *
+         * @param left Left position in pixels, relative to the overlay view.
+         * @param top Top position in pixels, relative to the overlay view.
+         * @param right Right position in pixels, relative to the overlay view.
+         * @param bottm Bottom position in pixels, relative to the overlay view.
+         * @hide
+         */
+        @SystemApi
+        public void layoutSurface(final int left, final int top, final int right, final int bottm) {
+            if (left > right || top > bottm) {
+                throw new IllegalArgumentException("Invalid parameter");
+            }
+            mHandler.post(new Runnable() {
+                @Override
+                public void run() {
+                    try {
+                        if (DEBUG) Log.d(TAG, "layoutSurface (l=" + left + ", t=" + top + ", r="
+                                + right + ", b=" + bottm + ",)");
+                        mSessionCallback.onLayoutSurface(left, top, right, bottm);
+                    } catch (RemoteException e) {
+                        Log.w(TAG, "error in layoutSurface");
+                    }
+                }
+            });
+        }
+
+        /**
          * Called when the session is released.
          */
         public abstract void onRelease();
@@ -556,6 +586,20 @@ public abstract class TvInputService extends Service {
         }
 
         /**
+         * Called when a size of an overlay view is changed by an application. Even when the overlay
+         * view is disabled by {@link #setOverlayViewEnabled}, this is called. The size is same as
+         * the size of {@link Surface} in general. Once {@link #layoutSurface} is called, the sizes
+         * of {@link Surface} and the overlay view can be different.
+         *
+         * @param width The width of the overlay view.
+         * @param height The height of the overlay view.
+         * @hide
+         */
+        @SystemApi
+        public void onOverlayViewSizeChanged(int width, int height) {
+        }
+
+        /**
          * Sets the relative stream volume of the current TV input session to handle the change of
          * audio focus by setting.
          *
@@ -873,6 +917,7 @@ public abstract class TvInputService extends Service {
             if (DEBUG) Log.d(TAG, "create overlay view(" + frame + ")");
             mWindowToken = windowToken;
             mOverlayFrame = frame;
+            onOverlayViewSizeChanged(frame.right - frame.left, frame.bottom - frame.top);
             if (!mOverlayViewEnabled) {
                 return;
             }
@@ -887,7 +932,7 @@ public abstract class TvInputService extends Service {
             // the application that owns the window token can decide whether to consume or
             // dispatch the input events.
             int flag = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
-                    | WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN
+                    | WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS
                     | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
             mWindowParams = new WindowManager.LayoutParams(
                     frame.right - frame.left, frame.bottom - frame.top,
@@ -906,6 +951,12 @@ public abstract class TvInputService extends Service {
          */
         void relayoutOverlayView(Rect frame) {
             if (DEBUG) Log.d(TAG, "relayoutOverlayView(" + frame + ")");
+            if (mOverlayFrame == null || mOverlayFrame.width() != frame.width()
+                    || mOverlayFrame.height() != frame.height()) {
+                // Note: relayoutOverlayView is called whenever TvView's layout is changed
+                // regardless of setOverlayViewEnabled.
+                onOverlayViewSizeChanged(frame.right - frame.left, frame.bottom - frame.top);
+            }
             mOverlayFrame = frame;
             if (!mOverlayViewEnabled || mOverlayView == null) {
                 return;
index 82761ec..ad2a502 100644 (file)
@@ -91,6 +91,11 @@ public class TvView extends ViewGroup {
     private final AttributeSet mAttrs;
     private final int mDefStyleAttr;
     private int mWindowZOrder;
+    private boolean mUseRequestedSurfaceLayout;
+    private int mSurfaceViewLeft;
+    private int mSurfaceViewRight;
+    private int mSurfaceViewTop;
+    private int mSurfaceViewBottom;
 
     private final SurfaceHolder.Callback mSurfaceHolderCallback = new SurfaceHolder.Callback() {
         @Override
@@ -535,7 +540,16 @@ public class TvView extends ViewGroup {
 
     @Override
     protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
-        mSurfaceView.layout(0, 0, right - left, bottom - top);
+        if (DEBUG) {
+            Log.d(TAG, "onLayout (left=" + left + ", top=" + top + ", right=" + right
+                    + ", bottom=" + bottom + ",)");
+        }
+        if (mUseRequestedSurfaceLayout) {
+            mSurfaceView.layout(mSurfaceViewLeft, mSurfaceViewTop, mSurfaceViewRight,
+                    mSurfaceViewBottom);
+        } else {
+            mSurfaceView.layout(0, 0, right - left, bottom - top);
+        }
     }
 
     @Override
@@ -583,6 +597,7 @@ public class TvView extends ViewGroup {
     private void release() {
         setSessionSurface(null);
         removeSessionOverlayView();
+        mUseRequestedSurfaceLayout = false;
         mSession.release();
         mSession = null;
         mSessionCallback = null;
@@ -919,6 +934,20 @@ public class TvView extends ViewGroup {
         }
 
         @Override
+        public void onLayoutSurface(Session session, int left, int top, int right, int bottom) {
+            if (DEBUG) {
+                Log.d(TAG, "onLayoutSurface (left=" + left + ", top=" + top + ", right="
+                        + right + ", bottom=" + bottom + ",)");
+            }
+            mSurfaceViewLeft = left;
+            mSurfaceViewTop = top;
+            mSurfaceViewRight = right;
+            mSurfaceViewBottom = bottom;
+            mUseRequestedSurfaceLayout = true;
+            requestLayout();
+        }
+
+        @Override
         public void onSessionEvent(Session session, String eventType, Bundle eventArgs) {
             if (this != mSessionCallback) {
                 return;
index 18446ae..594e9d0 100644 (file)
@@ -52,7 +52,6 @@ import android.media.tv.TvContentRating;
 import android.media.tv.TvContract;
 import android.media.tv.TvInputHardwareInfo;
 import android.media.tv.TvInputInfo;
-import android.media.tv.TvInputManager;
 import android.media.tv.TvInputService;
 import android.media.tv.TvStreamConfig;
 import android.media.tv.TvTrackInfo;
@@ -636,6 +635,25 @@ public final class TvInputManagerService extends SystemService {
             }
 
             @Override
+            public void onLayoutSurface(int left, int top, int right, int bottom) {
+                synchronized (mLock) {
+                    if (DEBUG) {
+                        Slog.d(TAG, "onLayoutSurface (left=" + left + ", top=" + top
+                                + ", right=" + right + ", bottom=" + bottom + ",)");
+                    }
+                    if (sessionState.mSession == null || sessionState.mClient == null) {
+                        return;
+                    }
+                    try {
+                        sessionState.mClient.onLayoutSurface(left, top, right, bottom,
+                                sessionState.mSeq);
+                    } catch (RemoteException e) {
+                        Slog.e(TAG, "error in onLayoutSurface");
+                    }
+                }
+            }
+
+            @Override
             public void onSessionEvent(String eventType, Bundle eventArgs) {
                 synchronized (mLock) {
                     if (DEBUG) {