Merge "TIF: Notify of a change to TvInputInfo regardless of service connection"
diff --git a/api/current.txt b/api/current.txt
index 81dd965..cabaad4 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -22892,7 +22892,7 @@
method public void onInputAdded(java.lang.String);
method public void onInputRemoved(java.lang.String);
method public void onInputStateChanged(java.lang.String, int);
- method public void onTvInputInfoChanged(java.lang.String, android.media.tv.TvInputInfo);
+ method public void onTvInputInfoChanged(android.media.tv.TvInputInfo);
}
public abstract class TvInputService extends android.app.Service {
@@ -22900,7 +22900,7 @@
method public final android.os.IBinder onBind(android.content.Intent);
method public android.media.tv.TvInputService.RecordingSession onCreateRecordingSession(java.lang.String);
method public abstract android.media.tv.TvInputService.Session onCreateSession(java.lang.String);
- method public final void setTvInputInfo(java.lang.String, android.media.tv.TvInputInfo);
+ method public static final void setTvInputInfo(android.content.Context, android.media.tv.TvInputInfo);
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";
}
diff --git a/api/system-current.txt b/api/system-current.txt
index f992037..cfa3969 100644
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -24407,7 +24407,7 @@
method public void onInputRemoved(java.lang.String);
method public void onInputStateChanged(java.lang.String, int);
method public void onInputUpdated(java.lang.String);
- method public void onTvInputInfoChanged(java.lang.String, android.media.tv.TvInputInfo);
+ method public void onTvInputInfoChanged(android.media.tv.TvInputInfo);
}
public abstract class TvInputService extends android.app.Service {
@@ -24419,7 +24419,7 @@
method public java.lang.String onHardwareRemoved(android.media.tv.TvInputHardwareInfo);
method public android.media.tv.TvInputInfo onHdmiDeviceAdded(android.hardware.hdmi.HdmiDeviceInfo);
method public java.lang.String onHdmiDeviceRemoved(android.hardware.hdmi.HdmiDeviceInfo);
- method public final void setTvInputInfo(java.lang.String, android.media.tv.TvInputInfo);
+ method public static final void setTvInputInfo(android.content.Context, android.media.tv.TvInputInfo);
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";
}
diff --git a/api/test-current.txt b/api/test-current.txt
index 7522caa..8f534a3 100644
--- a/api/test-current.txt
+++ b/api/test-current.txt
@@ -22901,7 +22901,7 @@
method public void onInputAdded(java.lang.String);
method public void onInputRemoved(java.lang.String);
method public void onInputStateChanged(java.lang.String, int);
- method public void onTvInputInfoChanged(java.lang.String, android.media.tv.TvInputInfo);
+ method public void onTvInputInfoChanged(android.media.tv.TvInputInfo);
}
public abstract class TvInputService extends android.app.Service {
@@ -22909,7 +22909,7 @@
method public final android.os.IBinder onBind(android.content.Intent);
method public android.media.tv.TvInputService.RecordingSession onCreateRecordingSession(java.lang.String);
method public abstract android.media.tv.TvInputService.Session onCreateSession(java.lang.String);
- method public final void setTvInputInfo(java.lang.String, android.media.tv.TvInputInfo);
+ method public static final void setTvInputInfo(android.content.Context, android.media.tv.TvInputInfo);
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";
}
diff --git a/media/java/android/media/tv/ITvInputManager.aidl b/media/java/android/media/tv/ITvInputManager.aidl
index 0febc16..d189333 100644
--- a/media/java/android/media/tv/ITvInputManager.aidl
+++ b/media/java/android/media/tv/ITvInputManager.aidl
@@ -41,6 +41,7 @@
interface ITvInputManager {
List<TvInputInfo> getTvInputList(int userId);
TvInputInfo getTvInputInfo(in String inputId, int userId);
+ void setTvInputInfo(in TvInputInfo inputInfo, int userId);
int getTvInputState(in String inputId, int userId);
List<TvContentRatingSystemInfo> getTvContentRatingSystemList(int userId);
diff --git a/media/java/android/media/tv/ITvInputManagerCallback.aidl b/media/java/android/media/tv/ITvInputManagerCallback.aidl
index 3bf415b..395c9f3 100644
--- a/media/java/android/media/tv/ITvInputManagerCallback.aidl
+++ b/media/java/android/media/tv/ITvInputManagerCallback.aidl
@@ -29,5 +29,5 @@
void onInputStateChanged(in String inputId, int state);
- void onTvInputInfoChanged(in String inputId, in TvInputInfo TvInputInfo);
+ void onTvInputInfoChanged(in TvInputInfo TvInputInfo);
}
diff --git a/media/java/android/media/tv/ITvInputServiceCallback.aidl b/media/java/android/media/tv/ITvInputServiceCallback.aidl
index 9f13882..74ab562 100644
--- a/media/java/android/media/tv/ITvInputServiceCallback.aidl
+++ b/media/java/android/media/tv/ITvInputServiceCallback.aidl
@@ -27,6 +27,4 @@
void addHardwareTvInput(in int deviceId, in TvInputInfo inputInfo);
void addHdmiTvInput(in int id, in TvInputInfo inputInfo);
void removeTvInput(in String inputId);
-
- void setTvInputInfo(in String inputId, in TvInputInfo inputInfo);
}
diff --git a/media/java/android/media/tv/TvInputManager.java b/media/java/android/media/tv/TvInputManager.java
index f1de8fd..86bded9 100644
--- a/media/java/android/media/tv/TvInputManager.java
+++ b/media/java/android/media/tv/TvInputManager.java
@@ -726,12 +726,11 @@
}
/**
- * This is called when the information about a given TV input is changed.
+ * This is called when the information about a given TV input has been changed.
*
- * @param inputId The ID of the TV input.
* @param inputInfo TvInputInfo object that contains the information about the TV input.
*/
- public void onTvInputInfoChanged(String inputId, TvInputInfo inputInfo) {
+ public void onTvInputInfoChanged(TvInputInfo inputInfo) {
}
}
@@ -784,11 +783,11 @@
});
}
- public void postTvInputInfoChanged(final String inputId, final TvInputInfo inputInfo) {
+ public void postTvInputInfoChanged(final TvInputInfo inputInfo) {
mHandler.post(new Runnable() {
@Override
public void run() {
- mCallback.onTvInputInfoChanged(inputId, inputInfo);
+ mCallback.onTvInputInfoChanged(inputInfo);
}
});
}
@@ -1089,10 +1088,10 @@
}
@Override
- public void onTvInputInfoChanged(String inputId, TvInputInfo inputInfo) {
+ public void onTvInputInfoChanged(TvInputInfo inputInfo) {
synchronized (mLock) {
for (TvInputCallbackRecord record : mCallbackRecords) {
- record.postTvInputInfoChanged(inputId, inputInfo);
+ record.postTvInputInfoChanged(inputInfo);
}
}
}
@@ -1143,6 +1142,23 @@
}
/**
+ * Sets a new TvInputInfo object for a given input.
+ *
+ * <p>This is called internally only by {@link TvInputService}.
+ *
+ * @param inputInfo The TvInputInfo object to set.
+ * @throws IllegalArgumentException if the argument is {@code null}.
+ */
+ void setTvInputInfo(@NonNull TvInputInfo inputInfo) {
+ Preconditions.checkNotNull(inputInfo);
+ try {
+ mService.setTvInputInfo(inputInfo, mUserId);
+ } catch (RemoteException e) {
+ throw new RuntimeException("Error trying to set " + inputInfo, e);
+ }
+ }
+
+ /**
* Returns the state of a given TV input.
*
* <p>The state is one of the following:
diff --git a/media/java/android/media/tv/TvInputService.java b/media/java/android/media/tv/TvInputService.java
index f74ae66..a2b6346 100644
--- a/media/java/android/media/tv/TvInputService.java
+++ b/media/java/android/media/tv/TvInputService.java
@@ -262,16 +262,16 @@
* <p>The system service automatically creates the TvInputInfo for each TV input based on
* information collected from the AndroidManifest.xml, thus it is not necessary to call this
* method unless the TV input has additional information to pass such as ability to record and
- * tuner count.
+ * tuner count. Attempting to change information about a TV input that the calling package does
+ * not own does nothing.
*
- * @param inputId The ID of the TV input.
+ * @param context The application context.
* @param inputInfo The TvInputInfo object that contains that new information.
*/
- public final void setTvInputInfo(String inputId, TvInputInfo inputInfo) {
- SomeArgs args = SomeArgs.obtain();
- args.arg1 = inputId;
- args.arg2 = inputInfo;
- mServiceHandler.obtainMessage(ServiceHandler.DO_SET_TV_INPUT_INFO, args).sendToTarget();
+ public static final void setTvInputInfo(Context context, TvInputInfo inputInfo) {
+ TvInputManager manager = (TvInputManager) context.getSystemService(
+ Context.TV_INPUT_SERVICE);
+ manager.setTvInputInfo(inputInfo);
}
private boolean isPassthroughInput(String inputId) {
@@ -1938,7 +1938,6 @@
private static final int DO_REMOVE_HARDWARE_TV_INPUT = 5;
private static final int DO_ADD_HDMI_TV_INPUT = 6;
private static final int DO_REMOVE_HDMI_TV_INPUT = 7;
- private static final int DO_SET_TV_INPUT_INFO = 8;
private void broadcastAddHardwareTvInput(int deviceId, TvInputInfo inputInfo) {
int n = mCallbacks.beginBroadcast();
@@ -1976,18 +1975,6 @@
mCallbacks.finishBroadcast();
}
- private void broadcastSetTvInputInfo(String inputId, TvInputInfo inputInfo) {
- int n = mCallbacks.beginBroadcast();
- for (int i = 0; i < n; ++i) {
- try {
- mCallbacks.getBroadcastItem(i).setTvInputInfo(inputId, inputInfo);
- } catch (RemoteException e) {
- Log.e(TAG, "error in broadcastSetTvInputInfo", e);
- }
- }
- mCallbacks.finishBroadcast();
- }
-
@Override
public final void handleMessage(Message msg) {
switch (msg.what) {
@@ -2120,16 +2107,6 @@
}
return;
}
- case DO_SET_TV_INPUT_INFO: {
- SomeArgs args = (SomeArgs) msg.obj;
- String inputId = (String) args.arg1;
- TvInputInfo inputInfo = (TvInputInfo) args.arg2;
- if (inputInfo != null) {
- broadcastSetTvInputInfo(inputId, inputInfo);
- }
- args.recycle();
- return;
- }
default: {
Log.w(TAG, "Unhandled message code: " + msg.what);
return;
diff --git a/services/core/java/com/android/server/tv/TvInputManagerService.java b/services/core/java/com/android/server/tv/TvInputManagerService.java
index 62e7fb4..318f966 100644
--- a/services/core/java/com/android/server/tv/TvInputManagerService.java
+++ b/services/core/java/com/android/server/tv/TvInputManagerService.java
@@ -71,6 +71,7 @@
import android.os.Process;
import android.os.RemoteException;
import android.os.UserHandle;
+import android.text.TextUtils;
import android.util.Slog;
import android.util.SparseArray;
import android.view.InputChannel;
@@ -779,15 +780,14 @@
}
}
- private void notifyTvInputInfoChanged(UserState userState, String inputId,
- TvInputInfo inputInfo) {
+ private void setTvInputInfoLocked(UserState userState, TvInputInfo inputInfo) {
if (DEBUG) {
- Slog.d(TAG, "notifyTvInputInfoChanged(inputId=" + inputId + ", inputInfo=" + inputInfo
- + ")");
+ Slog.d(TAG, "setTvInputInfoLocked(inputInfo=" + inputInfo + ")");
}
+ // TODO: Also update the internal input list.
for (ITvInputManagerCallback callback : userState.callbackSet) {
try {
- callback.onTvInputInfoChanged(inputId, inputInfo);
+ callback.onTvInputInfoChanged(inputInfo);
} catch (RemoteException e) {
Slog.e(TAG, "failed to report changed input info to callback", e);
}
@@ -846,6 +846,36 @@
}
}
+ public void setTvInputInfo(TvInputInfo inputInfo, int userId) {
+ String inputInfoPackageName = inputInfo.getServiceInfo().packageName;
+ String callingPackageName = getCallingPackageName();
+ if (!TextUtils.equals(inputInfoPackageName, callingPackageName)) {
+ throw new IllegalArgumentException("calling package " + callingPackageName
+ + " is not allowed to change TvInputInfo for " + inputInfoPackageName);
+ }
+
+ final int resolvedUserId = resolveCallingUserId(Binder.getCallingPid(),
+ Binder.getCallingUid(), userId, "setTvInputInfoChanged");
+ final long identity = Binder.clearCallingIdentity();
+ try {
+ synchronized (mLock) {
+ UserState userState = getOrCreateUserStateLocked(resolvedUserId);
+ setTvInputInfoLocked(userState, inputInfo);
+ }
+ } finally {
+ Binder.restoreCallingIdentity(identity);
+ }
+ }
+
+ private String getCallingPackageName() {
+ final String[] packages = mContext.getPackageManager().getPackagesForUid(
+ Binder.getCallingUid());
+ if (packages != null && packages.length > 0) {
+ return packages[0];
+ }
+ return "unknown";
+ }
+
@Override
public int getTvInputState(String inputId, int userId) {
final int resolvedUserId = resolveCallingUserId(Binder.getCallingPid(),
@@ -2233,18 +2263,6 @@
}
}
}
-
- @Override
- public void setTvInputInfo(String inputId, TvInputInfo inputInfo) {
- ensureValidInput(inputInfo);
- synchronized (mLock) {
- if (DEBUG) {
- Slog.d(TAG, "setTvInputInfo(" + inputInfo + ")");
- }
- UserState userState = getOrCreateUserStateLocked(mUserId);
- notifyTvInputInfoChanged(userState, inputId, inputInfo);
- }
- }
}
private final class SessionCallback extends ITvInputSessionCallback.Stub {