diff --git a/api/current.txt b/api/current.txt index 36344a2ae138a..483d0e15c0cdb 100644 --- a/api/current.txt +++ b/api/current.txt @@ -16734,6 +16734,7 @@ package android.media.tv { public abstract class TvInputService.Session implements android.view.KeyEvent.Callback { ctor public TvInputService.Session(); method public void dispatchChannelRetuned(android.net.Uri); + method public void dispatchContentAllowed(); method public void dispatchContentBlocked(android.media.tv.TvContentRating); method public void dispatchTrackInfoChanged(java.util.List); method public void dispatchVideoAvailable(); @@ -16828,6 +16829,7 @@ package android.media.tv { public static abstract class TvView.TvInputListener { ctor public TvView.TvInputListener(); method public void onChannelRetuned(java.lang.String, android.net.Uri); + method public void onContentAllowed(java.lang.String); method public void onContentBlocked(java.lang.String, android.media.tv.TvContentRating); method public void onError(java.lang.String, int); method public void onTrackInfoChanged(java.lang.String, java.util.List); diff --git a/media/java/android/media/tv/ITvInputClient.aidl b/media/java/android/media/tv/ITvInputClient.aidl index 403b1ba4d9f06..c48ddf1995e4c 100644 --- a/media/java/android/media/tv/ITvInputClient.aidl +++ b/media/java/android/media/tv/ITvInputClient.aidl @@ -36,5 +36,6 @@ oneway interface ITvInputClient { void onTrackInfoChanged(in List tracks, int seq); void onVideoAvailable(int seq); void onVideoUnavailable(int reason, int seq); + void onContentAllowed(int seq); void onContentBlocked(in String rating, int seq); } diff --git a/media/java/android/media/tv/ITvInputSessionCallback.aidl b/media/java/android/media/tv/ITvInputSessionCallback.aidl index f52959517b62e..4186bb59b5624 100644 --- a/media/java/android/media/tv/ITvInputSessionCallback.aidl +++ b/media/java/android/media/tv/ITvInputSessionCallback.aidl @@ -33,5 +33,6 @@ oneway interface ITvInputSessionCallback { void onTrackInfoChanged(in List tracks); void onVideoAvailable(); void onVideoUnavailable(int reason); + void onContentAllowed(); void onContentBlocked(in String rating); } diff --git a/media/java/android/media/tv/TvInputManager.java b/media/java/android/media/tv/TvInputManager.java index 910b725f6321c..efab74f673125 100644 --- a/media/java/android/media/tv/TvInputManager.java +++ b/media/java/android/media/tv/TvInputManager.java @@ -187,7 +187,17 @@ public final class TvInputManager { } /** - * This is called when the current program content is blocked by parental controls. + * This is called when the current program content turns out to be allowed to watch since + * its content rating is not blocked by parental controls. + * + * @param session A {@link TvInputManager.Session} associated with this callback + */ + public void onContentAllowed(Session session) { + } + + /** + * This is called when the current program content turns out to be not allowed to watch + * since its content rating is blocked by parental controls. * * @param session A {@link TvInputManager.Session} associated with this callback * @param rating The content ration of the blocked program. @@ -274,6 +284,15 @@ public final class TvInputManager { }); } + public void postContentAllowed() { + mHandler.post(new Runnable() { + @Override + public void run() { + mSessionCallback.onContentAllowed(mSession); + } + }); + } + public void postContentBlocked(final TvContentRating rating) { mHandler.post(new Runnable() { @Override @@ -456,6 +475,18 @@ public final class TvInputManager { } } + @Override + public void onContentAllowed(int seq) { + synchronized (mSessionCallbackRecordMap) { + SessionCallbackRecord record = mSessionCallbackRecordMap.get(seq); + if (record == null) { + Log.e(TAG, "Callback not found for seq " + seq); + return; + } + record.postContentAllowed(); + } + } + @Override public void onContentBlocked(String rating, int seq) { synchronized (mSessionCallbackRecordMap) { diff --git a/media/java/android/media/tv/TvInputService.java b/media/java/android/media/tv/TvInputService.java index 4f1f98830a3b4..718e8756af63f 100644 --- a/media/java/android/media/tv/TvInputService.java +++ b/media/java/android/media/tv/TvInputService.java @@ -305,42 +305,6 @@ public abstract class TvInputService extends Service { }); } - /** - * Informs the application that the current program content is blocked by parent controls. - *

- * Each TV input service is required to query the system whether the user is allowed to - * watch the current program before showing it to the user if the parental control is turned - * on, which can be checked by calling {@link TvParentalControlManager#isEnabled}. Whether - * the TV input service should block the content or not is determined by invoking - * {@link TvParentalControlManager#isRatingBlocked} with the content rating for the current - * program. Then the TvParentalControlManager makes a judgment based on the user blocked - * ratings stored in the secure settings and returns the result. If the rating in question - * turns out to be blocked, the TV input service must immediately block the content and call - * this method with the content rating of the current program to prompt the PIN verification - * screen. - *

- * Each TV input service also needs to continuously listen to any changes made to the - * parental control settings by registering a - * {@link TvParentalControlManager.ParentalControlCallback} to the manager and immediately - * reevaluate the current program with the new parental control settings. - *

- * - * @param rating The content rating for the current TV program. - */ - public void dispatchContentBlocked(final TvContentRating rating) { - mHandler.post(new Runnable() { - @Override - public void run() { - try { - if (DEBUG) Log.d(TAG, "dispatchContentBlocked"); - mSessionCallback.onContentBlocked(rating.flattenToString()); - } catch (RemoteException e) { - Log.w(TAG, "error in dispatchContentBlocked"); - } - } - }); - } - /** * Informs the application that video is not available, so the TV input cannot continue * playing the TV stream. @@ -371,6 +335,84 @@ public abstract class TvInputService extends Service { }); } + /** + * Informs the application that the user is allowed to watch the current program content. + *

+ * Each TV input service is required to query the system whether the user is allowed to + * watch the current program before showing it to the user if the parental control is + * enabled (i.e. {@link TvParentalControlManager#isEnabled + * TvParentalControlManager.isEnabled()} returns {@code true}). Whether the TV input service + * should block the content or not is determined by invoking + * {@link TvParentalControlManager#isRatingBlocked + * TvParentalControlManager.isRatingBlocked(TvContentRating)} with the content rating for + * the current program. Then the {@link TvParentalControlManager} makes a judgment based on + * the user blocked ratings stored in the secure settings and returns the result. If the + * rating in question turns out to be allowed by the user, the TV input service must call + * this method to notify the application that is permitted to show the content. + *

+ * Each TV input service also needs to continuously listen to any changes made to the + * parental control settings by registering a + * {@link TvParentalControlManager.ParentalControlCallback} to the manager and immediately + * reevaluate the current program with the new parental control settings. + *

+ * + * @see #dispatchContentBlocked + * @see TvParentalControlManager + */ + public void dispatchContentAllowed() { + mHandler.post(new Runnable() { + @Override + public void run() { + try { + if (DEBUG) Log.d(TAG, "dispatchContentAllowed"); + mSessionCallback.onContentAllowed(); + } catch (RemoteException e) { + Log.w(TAG, "error in dispatchContentAllowed"); + } + } + }); + } + + /** + * Informs the application that the current program content is blocked by parent controls. + *

+ * Each TV input service is required to query the system whether the user is allowed to + * watch the current program before showing it to the user if the parental control is + * enabled (i.e. {@link TvParentalControlManager#isEnabled + * TvParentalControlManager.isEnabled()} returns {@code true}). Whether the TV input service + * should block the content or not is determined by invoking + * {@link TvParentalControlManager#isRatingBlocked + * TvParentalControlManager.isRatingBlocked(TvContentRating)} with the content rating for + * the current program. Then the {@link TvParentalControlManager} makes a judgment based on + * the user blocked ratings stored in the secure settings and returns the result. If the + * rating in question turns out to be blocked, the TV input service must immediately block + * the content and call this method with the content rating of the current program to prompt + * the PIN verification screen. + *

+ * Each TV input service also needs to continuously listen to any changes made to the + * parental control settings by registering a + * {@link TvParentalControlManager.ParentalControlCallback} to the manager and immediately + * reevaluate the current program with the new parental control settings. + *

+ * + * @param rating The content rating for the current TV program. + * @see #dispatchContentAllowed + * @see TvParentalControlManager + */ + public void dispatchContentBlocked(final TvContentRating rating) { + mHandler.post(new Runnable() { + @Override + public void run() { + try { + if (DEBUG) Log.d(TAG, "dispatchContentBlocked"); + mSessionCallback.onContentBlocked(rating.flattenToString()); + } catch (RemoteException e) { + Log.w(TAG, "error in dispatchContentBlocked"); + } + } + }); + } + /** * Called when the session is released. */ diff --git a/media/java/android/media/tv/TvView.java b/media/java/android/media/tv/TvView.java index 9fbb3b2bc2a3b..6b131f87a05c7 100644 --- a/media/java/android/media/tv/TvView.java +++ b/media/java/android/media/tv/TvView.java @@ -576,7 +576,17 @@ public class TvView extends ViewGroup { } /** - * This is called when the current program content is blocked by parental controls. + * This is called when the current program content turns out to be allowed to watch since + * its content rating is not blocked by parental controls. + * + * @param inputId The ID of the TV input bound to this view. + */ + public void onContentAllowed(String inputId) { + } + + /** + * This is called when the current program content turns out to be not allowed to watch + * since its content rating is blocked by parental controls. * * @param inputId The ID of the TV input bound to this view. * @param rating The content rating of the blocked program. @@ -718,6 +728,19 @@ public class TvView extends ViewGroup { } } + @Override + public void onContentAllowed(Session session) { + if (this != mSessionCallback) { + return; + } + if (DEBUG) { + Log.d(TAG, "onContentAllowed()"); + } + if (mListener != null) { + mListener.onContentAllowed(mInputId); + } + } + @Override public void onContentBlocked(Session session, TvContentRating rating) { if (DEBUG) { @@ -728,6 +751,7 @@ public class TvView extends ViewGroup { } } + @Override public void onSessionEvent(Session session, String eventType, Bundle eventArgs) { if (this != mSessionCallback) { return; diff --git a/services/core/java/com/android/server/tv/TvInputManagerService.java b/services/core/java/com/android/server/tv/TvInputManagerService.java index 69c693ac2e2c9..78b68835a5b27 100644 --- a/services/core/java/com/android/server/tv/TvInputManagerService.java +++ b/services/core/java/com/android/server/tv/TvInputManagerService.java @@ -564,6 +564,23 @@ public final class TvInputManagerService extends SystemService { } } + @Override + public void onContentAllowed() { + synchronized (mLock) { + if (DEBUG) { + Slog.d(TAG, "onContentAllowed()"); + } + if (sessionState.mSession == null || sessionState.mClient == null) { + return; + } + try { + sessionState.mClient.onContentAllowed(sessionState.mSeq); + } catch (RemoteException e) { + Slog.e(TAG, "error in onContentAllowed"); + } + } + } + @Override public void onContentBlocked(String rating) { synchronized (mLock) {