TIF: Address the feedback from the API review - 1/3
This change addresses the following comments from the council:
- Change TvView.setVolume() --> setStreamVolume()
- Surface only TvInputInfo.getServiceInfo() instead of the separate
getPackage/getService/getComponent calls. However, keep loadLabel()
at the top level.
- @hide register/unregisterListener() for the preview, since it binds
out to each service.
- TvInputService should document which permission it should protect
itself with.
- Remove TvInputService.setAvailable() for third-party developers.
- Change class name TvInputSessionImpl --> Session
- Change callback name to onSetStreamVolume() to match earlier change
Bug: 15345342
Change-Id: I3ce5cba7dad2622b78d16c408f81c4b0eba837a4
diff --git a/api/current.txt b/api/current.txt
index 3f3d026..2fe6cee 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -15941,12 +15941,10 @@
public final class TvInputInfo implements android.os.Parcelable {
method public int describeContents();
- method public android.content.ComponentName getComponent();
method public java.lang.String getId();
method public android.content.Intent getIntentForSettingsActivity();
method public android.content.Intent getIntentForSetupActivity();
- method public java.lang.String getPackageName();
- method public java.lang.String getServiceName();
+ method public android.content.pm.ServiceInfo getServiceInfo();
method public java.lang.CharSequence loadLabel(android.content.pm.PackageManager);
method public void writeToParcel(android.os.Parcel, int);
field public static final java.lang.String EXTRA_SERVICE_NAME = "serviceName";
@@ -15956,13 +15954,11 @@
method public void createSession(java.lang.String, android.media.tv.TvInputManager.SessionCallback, android.os.Handler);
method public boolean getAvailability(java.lang.String);
method public java.util.List<android.media.tv.TvInputInfo> getTvInputList();
- method public void registerListener(java.lang.String, android.media.tv.TvInputManager.TvInputListener, android.os.Handler);
- method public void unregisterListener(java.lang.String, android.media.tv.TvInputManager.TvInputListener);
}
public static final class TvInputManager.Session {
method public void release();
- method public void setVolume(float);
+ method public void setStreamVolume(float);
method public void tune(android.net.Uri);
}
@@ -15980,14 +15976,13 @@
public abstract class TvInputService extends android.app.Service {
ctor public TvInputService();
method public final android.os.IBinder onBind(android.content.Intent);
- method public abstract android.media.tv.TvInputService.TvInputSessionImpl onCreateSession();
- method public final void setAvailable(boolean);
+ method public abstract android.media.tv.TvInputService.Session onCreateSession();
field public static final java.lang.String SERVICE_INTERFACE = "android.media.tv.TvInputService";
field public static final java.lang.String SERVICE_META_DATA = "android.media.tv.input";
}
- public abstract class TvInputService.TvInputSessionImpl implements android.view.KeyEvent.Callback {
- ctor public TvInputService.TvInputSessionImpl();
+ public abstract class TvInputService.Session implements android.view.KeyEvent.Callback {
+ ctor public TvInputService.Session();
method public android.view.View onCreateOverlayView();
method public boolean onGenericMotionEvent(android.view.MotionEvent);
method public boolean onKeyDown(int, android.view.KeyEvent);
@@ -15995,8 +15990,8 @@
method public boolean onKeyMultiple(int, int, android.view.KeyEvent);
method public boolean onKeyUp(int, android.view.KeyEvent);
method public abstract void onRelease();
+ method public abstract void onSetStreamVolume(float);
method public abstract boolean onSetSurface(android.view.Surface);
- method public abstract void onSetVolume(float);
method public boolean onTouchEvent(android.view.MotionEvent);
method public boolean onTrackballEvent(android.view.MotionEvent);
method public abstract boolean onTune(android.net.Uri);
@@ -16011,6 +16006,7 @@
method public boolean dispatchUnhandledInputEvent(android.view.InputEvent);
method public boolean onUnhandledInputEvent(android.view.InputEvent);
method public void setOnUnhandledInputEventListener(android.media.tv.TvView.OnUnhandledInputEventListener);
+ method public void setStreamVolume(float);
method public void unbindTvInput();
}
diff --git a/media/java/android/media/tv/ITvInputSessionWrapper.java b/media/java/android/media/tv/ITvInputSessionWrapper.java
index 975e391..d20ee0e 100644
--- a/media/java/android/media/tv/ITvInputSessionWrapper.java
+++ b/media/java/android/media/tv/ITvInputSessionWrapper.java
@@ -18,8 +18,6 @@
import android.content.Context;
import android.graphics.Rect;
-import android.media.tv.TvInputManager.Session;
-import android.media.tv.TvInputService.TvInputSessionImpl;
import android.net.Uri;
import android.os.IBinder;
import android.os.Looper;
@@ -52,11 +50,11 @@
private final HandlerCaller mCaller;
- private TvInputSessionImpl mTvInputSessionImpl;
+ private TvInputService.Session mTvInputSessionImpl;
private InputChannel mChannel;
private TvInputEventReceiver mReceiver;
- public ITvInputSessionWrapper(Context context, TvInputSessionImpl sessionImpl,
+ public ITvInputSessionWrapper(Context context, TvInputService.Session sessionImpl,
InputChannel channel) {
mCaller = new HandlerCaller(context, null, this, true /* asyncHandler */);
mTvInputSessionImpl = sessionImpl;
@@ -169,8 +167,8 @@
}
int handled = mTvInputSessionImpl.dispatchInputEvent(event, this);
- if (handled != Session.DISPATCH_IN_PROGRESS) {
- finishInputEvent(event, handled == Session.DISPATCH_HANDLED);
+ if (handled != TvInputManager.Session.DISPATCH_IN_PROGRESS) {
+ finishInputEvent(event, handled == TvInputManager.Session.DISPATCH_HANDLED);
}
}
}
diff --git a/media/java/android/media/tv/TvInputInfo.java b/media/java/android/media/tv/TvInputInfo.java
index ed599ed..9525c08 100644
--- a/media/java/android/media/tv/TvInputInfo.java
+++ b/media/java/android/media/tv/TvInputInfo.java
@@ -138,21 +138,15 @@
}
/**
- * Returns the .apk package that implements this TV input service.
+ * Returns the information of the service that implements this TV input.
*/
- public String getPackageName() {
- return mService.serviceInfo.packageName;
- }
-
- /**
- * Returns the class name of the service component that implements this TV input service.
- */
- public String getServiceName() {
- return mService.serviceInfo.name;
+ public ServiceInfo getServiceInfo() {
+ return mService.serviceInfo;
}
/**
* Returns the component of the service that implements this TV input.
+ * @hide
*/
public ComponentName getComponent() {
return new ComponentName(mService.serviceInfo.packageName, mService.serviceInfo.name);
@@ -164,8 +158,8 @@
public Intent getIntentForSetupActivity() {
if (!TextUtils.isEmpty(mSetupActivity)) {
Intent intent = new Intent(Intent.ACTION_MAIN);
- intent.setClassName(getPackageName(), mSetupActivity);
- intent.putExtra(EXTRA_SERVICE_NAME, getServiceName());
+ intent.setClassName(mService.serviceInfo.packageName, mSetupActivity);
+ intent.putExtra(EXTRA_SERVICE_NAME, mService.serviceInfo.name);
return intent;
}
return null;
@@ -177,8 +171,8 @@
public Intent getIntentForSettingsActivity() {
if (!TextUtils.isEmpty(mSettingsActivity)) {
Intent intent = new Intent(Intent.ACTION_MAIN);
- intent.setClassName(getPackageName(), mSettingsActivity);
- intent.putExtra(EXTRA_SERVICE_NAME, getServiceName());
+ intent.setClassName(mService.serviceInfo.packageName, mSettingsActivity);
+ intent.putExtra(EXTRA_SERVICE_NAME, mService.serviceInfo.name);
return intent;
}
return null;
diff --git a/media/java/android/media/tv/TvInputManager.java b/media/java/android/media/tv/TvInputManager.java
index 698a861..38d7c41 100644
--- a/media/java/android/media/tv/TvInputManager.java
+++ b/media/java/android/media/tv/TvInputManager.java
@@ -390,6 +390,7 @@
* @param listener a listener used to monitor status of the given TV input.
* @param handler a {@link Handler} that the status change will be delivered to.
* @throws IllegalArgumentException if any of the arguments is {@code null}.
+ * @hide
*/
public void registerListener(String inputId, TvInputListener listener, Handler handler) {
if (inputId == null) {
@@ -422,6 +423,7 @@
* @param inputId the id of the TV input.
* @param listener the existing listener to remove for the given TV input.
* @throws IllegalArgumentException if any of the arguments is {@code null}.
+ * @hide
*/
public void unregisterListener(String inputId, final TvInputListener listener) {
if (inputId == null) {
@@ -562,13 +564,13 @@
}
/**
- * Sets the relative volume of this session to handle a change of audio focus.
+ * Sets the relative stream volume of this session to handle a change of audio focus.
*
* @param volume A volume value between 0.0f to 1.0f.
* @throws IllegalArgumentException if the volume value is out of range.
* @throws IllegalStateException if the session has been already released.
*/
- public void setVolume(float volume) {
+ public void setStreamVolume(float volume) {
if (mToken == null) {
throw new IllegalStateException("the session has been already released");
}
diff --git a/media/java/android/media/tv/TvInputService.java b/media/java/android/media/tv/TvInputService.java
index 8ba0e20..0601195 100644
--- a/media/java/android/media/tv/TvInputService.java
+++ b/media/java/android/media/tv/TvInputService.java
@@ -22,8 +22,6 @@
import android.content.Intent;
import android.graphics.PixelFormat;
import android.graphics.Rect;
-import android.media.tv.ITvInputService;
-import android.media.tv.TvInputManager.Session;
import android.net.Uri;
import android.os.Bundle;
import android.os.Handler;
@@ -47,7 +45,17 @@
import com.android.internal.os.SomeArgs;
/**
- * A base class for implementing television input service.
+ * The TvInputService class represents a TV input or source such as HDMI or built-in tuner which
+ * provides pass-through video or broadcast TV programs.
+ * <p>
+ * Applications will not normally use this service themselves, instead relying on the standard
+ * interaction provided by {@link TvView}. Those implementing TV input services should normally do
+ * so by deriving from this class and providing their own session implementation based on
+ * {@link TvInputService.Session}. All TV input services must require that clients hold the
+ * {@link android.Manifest.permission#BIND_TV_INPUT} in order to interact with the service; if this
+ * permission is not specified in the manifest, the system will refuse to bind to that TV input
+ * service.
+ * </p>
*/
public abstract class TvInputService extends Service {
// STOPSHIP: Turn debugging off.
@@ -74,7 +82,9 @@
private final Handler mHandler = new ServiceHandler();
private final RemoteCallbackList<ITvInputServiceCallback> mCallbacks =
new RemoteCallbackList<ITvInputServiceCallback>();
- private boolean mAvailable;
+ // STOPSHIP: Redesign the API around the availability change. For now, the service will be
+ // always available.
+ private final boolean mAvailable = true;
@Override
public void onCreate() {
@@ -124,19 +134,6 @@
}
/**
- * Convenience method to notify an availability change of this TV input service.
- *
- * @param available {@code true} if the input service is available to show TV programs.
- */
- public final void setAvailable(boolean available) {
- if (available != mAvailable) {
- mAvailable = available;
- mHandler.obtainMessage(ServiceHandler.DO_BROADCAST_AVAILABILITY_CHANGE, available)
- .sendToTarget();
- }
- }
-
- /**
* Get the number of callbacks that are registered.
*
* @hide
@@ -147,17 +144,17 @@
}
/**
- * Returns a concrete implementation of {@link TvInputSessionImpl}.
+ * Returns a concrete implementation of {@link Session}.
* <p>
* May return {@code null} if this TV input service fails to create a session for some reason.
* </p>
*/
- public abstract TvInputSessionImpl onCreateSession();
+ public abstract Session onCreateSession();
/**
* Base class for derived classes to implement to provide {@link TvInputManager.Session}.
*/
- public abstract class TvInputSessionImpl implements KeyEvent.Callback {
+ public abstract class Session implements KeyEvent.Callback {
private final KeyEvent.DispatcherState mDispatcherState = new KeyEvent.DispatcherState();
private final WindowManager mWindowManager;
private WindowManager.LayoutParams mWindowParams;
@@ -168,7 +165,7 @@
private Rect mOverlayFrame;
private ITvInputSessionCallback mSessionCallback;
- public TvInputSessionImpl() {
+ public Session() {
mWindowManager = (WindowManager) getSystemService(Context.WINDOW_SERVICE);
}
@@ -303,12 +300,12 @@
public abstract boolean onSetSurface(Surface surface);
/**
- * Sets the relative volume of the current TV input session to handle the change of audio
- * focus by setting.
+ * Sets the relative stream volume of the current TV input session to handle the change of
+ * audio focus by setting.
*
* @param volume Volume scale from 0.0 to 1.0.
*/
- public abstract void onSetVolume(float volume);
+ public abstract void onSetStreamVolume(float volume);
/**
* Tunes to a given channel.
@@ -469,10 +466,10 @@
}
/**
- * Calls {@link #onSetVolume}.
+ * Calls {@link #onSetStreamVolume}.
*/
void setVolume(float volume) {
- onSetVolume(volume);
+ onSetStreamVolume(volume);
}
/**
@@ -565,33 +562,33 @@
if (DEBUG) Log.d(TAG, "dispatchInputEvent(" + event + ")");
if (event instanceof KeyEvent) {
if (((KeyEvent) event).dispatch(this, mDispatcherState, this)) {
- return Session.DISPATCH_HANDLED;
+ return TvInputManager.Session.DISPATCH_HANDLED;
}
} else if (event instanceof MotionEvent) {
MotionEvent motionEvent = (MotionEvent) event;
final int source = motionEvent.getSource();
if (motionEvent.isTouchEvent()) {
if (onTouchEvent(motionEvent)) {
- return Session.DISPATCH_HANDLED;
+ return TvInputManager.Session.DISPATCH_HANDLED;
}
} else if ((source & InputDevice.SOURCE_CLASS_TRACKBALL) != 0) {
if (onTrackballEvent(motionEvent)) {
- return Session.DISPATCH_HANDLED;
+ return TvInputManager.Session.DISPATCH_HANDLED;
}
} else {
if (onGenericMotionEvent(motionEvent)) {
- return Session.DISPATCH_HANDLED;
+ return TvInputManager.Session.DISPATCH_HANDLED;
}
}
}
if (mOverlayView == null || !mOverlayView.isAttachedToWindow()) {
- return Session.DISPATCH_NOT_HANDLED;
+ return TvInputManager.Session.DISPATCH_NOT_HANDLED;
}
if (!mOverlayView.hasWindowFocus()) {
mOverlayView.getViewRootImpl().windowFocusChanged(true, true);
}
mOverlayView.getViewRootImpl().dispatchInputEvent(event, receiver);
- return Session.DISPATCH_IN_PROGRESS;
+ return TvInputManager.Session.DISPATCH_IN_PROGRESS;
}
private void setSessionCallback(ITvInputSessionCallback callback) {
@@ -611,7 +608,7 @@
InputChannel channel = (InputChannel) args.arg1;
ITvInputSessionCallback cb = (ITvInputSessionCallback) args.arg2;
try {
- TvInputSessionImpl sessionImpl = onCreateSession();
+ Session sessionImpl = onCreateSession();
if (sessionImpl == null) {
// Failed to create a session.
cb.onSessionCreated(null);
diff --git a/media/java/android/media/tv/TvView.java b/media/java/android/media/tv/TvView.java
index d8b362d..6c7abc5 100644
--- a/media/java/android/media/tv/TvView.java
+++ b/media/java/android/media/tv/TvView.java
@@ -154,6 +154,19 @@
}
/**
+ * Sets the relative stream volume of this session to handle a change of audio focus.
+ *
+ * @param volume A volume value between 0.0f to 1.0f.
+ */
+ public void setStreamVolume(float volume) {
+ if (DEBUG) Log.d(TAG, "setStreamVolume(" + volume + ")");
+ if (mSession == null) {
+ return;
+ }
+ mSession.setStreamVolume(volume);
+ }
+
+ /**
* Dispatches an unhandled input event to the next receiver.
* <p>
* Except system keys, TvView always consumes input events in the normal flow. This is called