OSDN Git Service

TIF: Add a way to enable/disable caption
authorJae Seo <jaeseo@google.com>
Thu, 10 Jul 2014 21:57:01 +0000 (14:57 -0700)
committerJae Seo <jaeseo@google.com>
Sun, 13 Jul 2014 03:43:11 +0000 (20:43 -0700)
This is required to handle the case that an application wants to turn
on/off the caption explicitly (e.g. TvView in PIP). TV input service
implementation must respond to the request immediately to avoid any
legal implication since the captioning is imposed by the law in many
countries.

Bug: 14121898
Change-Id: I9600debae709fdc99065d7a0138ae69d1dffc9ba

api/current.txt
media/java/android/media/tv/ITvInputManager.aidl
media/java/android/media/tv/ITvInputSession.aidl
media/java/android/media/tv/ITvInputSessionWrapper.java
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 a2c4597..5beee72 100644 (file)
@@ -16171,6 +16171,7 @@ package android.media.tv {
     method public boolean onKeyUp(int, android.view.KeyEvent);
     method public abstract void onRelease();
     method public boolean onSelectTrack(android.media.tv.TvTrackInfo);
+    method public abstract void onSetCaptionEnabled(boolean);
     method public abstract void onSetStreamVolume(float);
     method public abstract boolean onSetSurface(android.view.Surface);
     method public boolean onTouchEvent(android.view.MotionEvent);
@@ -16220,6 +16221,7 @@ package android.media.tv {
     method public boolean onUnhandledInputEvent(android.view.InputEvent);
     method public void reset();
     method public void selectTrack(android.media.tv.TvTrackInfo);
+    method public void setCaptionEnabled(boolean);
     method public void setOnUnhandledInputEventListener(android.media.tv.TvView.OnUnhandledInputEventListener);
     method public void setStreamVolume(float);
     method public void setTvInputListener(android.media.tv.TvView.TvInputListener);
index bdebd7c..9a6a648 100644 (file)
@@ -45,6 +45,7 @@ interface ITvInputManager {
     void setSurface(in IBinder sessionToken, in Surface surface, int userId);
     void setVolume(in IBinder sessionToken, float volume, int userId);
     void tune(in IBinder sessionToken, in Uri channelUri, int userId);
+    void setCaptionEnabled(in IBinder sessionToken, boolean enabled, int userId);
     void selectTrack(in IBinder sessionToken, in TvTrackInfo track, int userId);
     void unselectTrack(in IBinder sessionToken, in TvTrackInfo track, int userId);
 
index f8590f1..875fa34 100644 (file)
@@ -33,6 +33,7 @@ oneway interface ITvInputSession {
     // is to introduce some new concepts that will solve a number of problems in audio policy today.
     void setVolume(float volume);
     void tune(in Uri channelUri);
+    void setCaptionEnabled(boolean enabled);
     void selectTrack(in TvTrackInfo track);
     void unselectTrack(in TvTrackInfo track);
 
index 06ee4b5..0c08590 100644 (file)
@@ -44,11 +44,12 @@ public class ITvInputSessionWrapper extends ITvInputSession.Stub implements Hand
     private static final int DO_SET_SURFACE = 2;
     private static final int DO_SET_VOLUME = 3;
     private static final int DO_TUNE = 4;
-    private static final int DO_SELECT_TRACK = 5;
-    private static final int DO_UNSELECT_TRACK = 6;
-    private static final int DO_CREATE_OVERLAY_VIEW = 7;
-    private static final int DO_RELAYOUT_OVERLAY_VIEW = 8;
-    private static final int DO_REMOVE_OVERLAY_VIEW = 9;
+    private static final int DO_SET_CAPTION_ENABLED = 5;
+    private static final int DO_SELECT_TRACK = 6;
+    private static final int DO_UNSELECT_TRACK = 7;
+    private static final int DO_CREATE_OVERLAY_VIEW = 8;
+    private static final int DO_RELAYOUT_OVERLAY_VIEW = 9;
+    private static final int DO_REMOVE_OVERLAY_VIEW = 10;
 
     private final HandlerCaller mCaller;
 
@@ -98,6 +99,10 @@ public class ITvInputSessionWrapper extends ITvInputSession.Stub implements Hand
                 mTvInputSessionImpl.tune((Uri) msg.obj);
                 return;
             }
+            case DO_SET_CAPTION_ENABLED: {
+                mTvInputSessionImpl.setCaptionEnabled((Boolean) msg.obj);
+                return;
+            }
             case DO_SELECT_TRACK: {
                 mTvInputSessionImpl.selectTrack((TvTrackInfo) msg.obj);
                 return;
@@ -148,6 +153,11 @@ public class ITvInputSessionWrapper extends ITvInputSession.Stub implements Hand
     }
 
     @Override
+    public void setCaptionEnabled(boolean enabled) {
+        mCaller.executeOrSendMessage(mCaller.obtainMessageO(DO_SET_CAPTION_ENABLED, enabled));
+    }
+
+    @Override
     public void selectTrack(TvTrackInfo track) {
         mCaller.executeOrSendMessage(mCaller.obtainMessageO(DO_SELECT_TRACK, track));
     }
index 521c809..f1a63ad 100644 (file)
@@ -35,7 +35,6 @@ import android.view.Surface;
 import android.view.View;
 
 import java.util.ArrayList;
-import java.util.Arrays;
 import java.util.HashMap;
 import java.util.Iterator;
 import java.util.List;
@@ -575,6 +574,23 @@ public final class TvInputManager {
         }
 
         /**
+         * Enables or disables the caption for this session.
+         *
+         * @param enabled {@code true} to enable, {@code false} to disable.
+         */
+        public void setCaptionEnabled(boolean enabled) {
+            if (mToken == null) {
+                Log.w(TAG, "The session has been already released");
+                return;
+            }
+            try {
+                mService.setCaptionEnabled(mToken, enabled, mUserId);
+            } catch (RemoteException e) {
+                throw new RuntimeException(e);
+            }
+        }
+
+        /**
          * Select a track.
          *
          * @param track the track to be selected.
index 4614bda..ba12e2e 100644 (file)
@@ -16,6 +16,7 @@
 
 package android.media.tv;
 
+import android.annotation.SuppressLint;
 import android.app.Service;
 import android.content.ComponentName;
 import android.content.Context;
@@ -40,6 +41,7 @@ import android.view.MotionEvent;
 import android.view.Surface;
 import android.view.View;
 import android.view.WindowManager;
+import android.view.accessibility.CaptioningManager;
 
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.os.SomeArgs;
@@ -295,6 +297,17 @@ public abstract class TvInputService extends Service {
         public abstract boolean onTune(Uri channelUri);
 
         /**
+         * Enables or disables the caption.
+         * <p>
+         * The locale for the user's preferred captioning language can be obtained by calling
+         * {@link CaptioningManager#getLocale CaptioningManager.getLocale()}.
+         *
+         * @param enabled {@code true} to enable, {@code false} to disable.
+         * @see CaptioningManager
+         */
+        public abstract void onSetCaptionEnabled(boolean enabled);
+
+        /**
          * Selects a given track.
          * <p>
          * If it is called multiple times on the same type of track (ie. Video, Audio, Text), the
@@ -302,9 +315,10 @@ public abstract class TvInputService extends Service {
          * Also, if the select operation was successful, the implementation should call
          * {@link #dispatchTrackInfoChanged(List)} to report the updated track information.
          * </p>
+         *
          * @param track The track to be selected.
          * @return {@code true} if the select operation was successful, {@code false} otherwise.
-         * @see #dispatchTrackInfoChanged(TvTrackInfo[])
+         * @see #dispatchTrackInfoChanged
          * @see TvTrackInfo#KEY_IS_SELECTED
          */
         public boolean onSelectTrack(TvTrackInfo track) {
@@ -317,9 +331,10 @@ public abstract class TvInputService extends Service {
          * If the unselect operation was successful, the implementation should call
          * {@link #dispatchTrackInfoChanged(List)} to report the updated track information.
          * </p>
+         *
          * @param track The track to be unselected.
          * @return {@code true} if the unselect operation was successful, {@code false} otherwise.
-         * @see #dispatchTrackInfoChanged(TvTrackInfo[])
+         * @see #dispatchTrackInfoChanged
          * @see TvTrackInfo#KEY_IS_SELECTED
          */
         public boolean onUnselectTrack(TvTrackInfo track) {
@@ -492,6 +507,13 @@ public abstract class TvInputService extends Service {
         }
 
         /**
+         * Calls {@link #onSetCaptionEnabled}.
+         */
+        void setCaptionEnabled(boolean enabled) {
+            onSetCaptionEnabled(enabled);
+        }
+
+        /**
          * Calls {@link #onSelectTrack}.
          */
         void selectTrack(TvTrackInfo track) {
@@ -656,6 +678,7 @@ public abstract class TvInputService extends Service {
         return false;
     }
 
+    @SuppressLint("HandlerLeak")
     private final class ServiceHandler extends Handler {
         private static final int DO_CREATE_SESSION = 1;
         private static final int DO_BROADCAST_AVAILABILITY_CHANGE = 2;
index 10f0c6b..7eb27b6 100644 (file)
@@ -18,7 +18,6 @@ package android.media.tv;
 
 import android.content.Context;
 import android.graphics.Rect;
-import android.media.MediaPlayer.TrackInfo;
 import android.media.tv.TvInputManager.Session;
 import android.media.tv.TvInputManager.Session.FinishedInputEventCallback;
 import android.media.tv.TvInputManager.SessionCallback;
@@ -216,11 +215,26 @@ public class TvView extends ViewGroup {
     }
 
     /**
+     * Enables or disables the caption in this TvView.
+     * <p>
+     * Note that this method does not take any effect unless the current TvView is tuned.
+     *
+     * @param enabled {@code true} to enable, {@code false} to disable.
+     */
+    public void setCaptionEnabled(boolean enabled) {
+        if (mSession != null) {
+            mSession.setCaptionEnabled(enabled);
+        }
+    }
+
+    /**
      * Select a track.
      * <p>
      * If it is called multiple times on the same type of track (ie. Video, Audio, Text), the track
-     * selected in previous will be unselected.
+     * selected in previous will be unselected. Note that this method does not take any effect
+     * unless the current TvView is tuned.
      * </p>
+     *
      * @param track the track to be selected.
      * @see #getTracks()
      */
@@ -232,6 +246,8 @@ public class TvView extends ViewGroup {
 
     /**
      * Unselect a track.
+     * <p>
+     * Note that this method does not take any effect unless the current TvView is tuned.
      *
      * @param track the track to be unselected.
      * @see #getTracks()
index feb2efc..fac78a9 100644 (file)
@@ -861,6 +861,26 @@ public final class TvInputManagerService extends SystemService {
         }
 
         @Override
+        public void setCaptionEnabled(IBinder sessionToken, boolean enabled, int userId) {
+            final int callingUid = Binder.getCallingUid();
+            final int resolvedUserId = resolveCallingUserId(Binder.getCallingPid(), callingUid,
+                    userId, "setCaptionEnabled");
+            final long identity = Binder.clearCallingIdentity();
+            try {
+                synchronized (mLock) {
+                    try {
+                        getSessionLocked(sessionToken, callingUid, resolvedUserId)
+                                .setCaptionEnabled(enabled);
+                    } catch (RemoteException e) {
+                        Slog.e(TAG, "error in setCaptionEnabled", e);
+                    }
+                }
+            } finally {
+                Binder.restoreCallingIdentity(identity);
+            }
+        }
+
+        @Override
         public void selectTrack(IBinder sessionToken, TvTrackInfo track, int userId) {
             final int callingUid = Binder.getCallingUid();
             final int resolvedUserId = resolveCallingUserId(Binder.getCallingPid(), callingUid,