am cacba761: Notify of the update of TvInputInfo
* commit 'cacba7615051b8667d5b2b178603ed78eb492e28':
Notify of the update of TvInputInfo
diff --git a/media/java/android/media/tv/ITvInputManagerCallback.aidl b/media/java/android/media/tv/ITvInputManagerCallback.aidl
index 50a7636..6792680 100644
--- a/media/java/android/media/tv/ITvInputManagerCallback.aidl
+++ b/media/java/android/media/tv/ITvInputManagerCallback.aidl
@@ -24,4 +24,5 @@
void onInputStateChanged(in String inputId, int state);
void onInputAdded(in String inputId);
void onInputRemoved(in String inputId);
+ void onInputUpdated(in String inputId);
}
diff --git a/media/java/android/media/tv/TvInputManager.java b/media/java/android/media/tv/TvInputManager.java
index b7a230c..f809f54 100644
--- a/media/java/android/media/tv/TvInputManager.java
+++ b/media/java/android/media/tv/TvInputManager.java
@@ -477,6 +477,18 @@
*/
public void onInputRemoved(String inputId) {
}
+
+ /**
+ * This is called when a TV input is updated. The update of TV input happens when it is
+ * reinstalled or the media on which the newer version of TV input exists is
+ * available/unavailable.
+ *
+ * @param inputId The id of the TV input.
+ * @hide
+ */
+ @SystemApi
+ public void onInputUpdated(String inputId) {
+ }
}
private static final class TvInputCallbackRecord {
@@ -518,6 +530,15 @@
}
});
}
+
+ public void postInputUpdated(final String inputId) {
+ mHandler.post(new Runnable() {
+ @Override
+ public void run() {
+ mListener.onInputUpdated(inputId);
+ }
+ });
+ }
}
/**
@@ -707,6 +728,15 @@
}
}
}
+
+ @Override
+ public void onInputUpdated(String inputId) {
+ synchronized (mLock) {
+ for (TvInputListenerRecord record : mTvInputListenerRecordsList) {
+ record.postInputUpdated(inputId);
+ }
+ }
+ }
};
try {
if (mService != null) {
diff --git a/services/core/java/com/android/server/tv/TvInputManagerService.java b/services/core/java/com/android/server/tv/TvInputManagerService.java
index 3380f71..adae84fd 100644
--- a/services/core/java/com/android/server/tv/TvInputManagerService.java
+++ b/services/core/java/com/android/server/tv/TvInputManagerService.java
@@ -85,6 +85,7 @@
import java.io.IOException;
import java.io.PrintWriter;
import java.util.ArrayList;
+import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
@@ -139,7 +140,7 @@
registerBroadcastReceivers();
} else if (phase == SystemService.PHASE_THIRD_PARTY_APPS_CAN_START) {
synchronized (mLock) {
- buildTvInputListLocked(mCurrentUserId);
+ buildTvInputListLocked(mCurrentUserId, null);
buildTvContentRatingSystemListLocked(mCurrentUserId);
}
}
@@ -148,19 +149,64 @@
private void registerBroadcastReceivers() {
PackageMonitor monitor = new PackageMonitor() {
+ private void buildTvInputList(String[] packages) {
+ synchronized (mLock) {
+ buildTvInputListLocked(getChangingUserId(), packages);
+ buildTvContentRatingSystemListLocked(getChangingUserId());
+ }
+ }
+
+ @Override
+ public void onPackageUpdateFinished(String packageName, int uid) {
+ if (DEBUG) Slog.d(TAG, "onPackageUpdateFinished(packageName=" + packageName + ")");
+ // This callback is invoked when the TV input is reinstalled.
+ // In this case, isReplacing() always returns true.
+ buildTvInputList(new String[] { packageName });
+ }
+
+ @Override
+ public void onPackagesAvailable(String[] packages) {
+ if (DEBUG) {
+ Slog.d(TAG, "onPackagesAvailable(packages=" + Arrays.toString(packages) + ")");
+ }
+ // This callback is invoked when the media on which some packages exist become
+ // available.
+ if (isReplacing()) {
+ buildTvInputList(packages);
+ }
+ }
+
+ @Override
+ public void onPackagesUnavailable(String[] packages) {
+ // This callback is invoked when the media on which some packages exist become
+ // unavailable.
+ if (DEBUG) {
+ Slog.d(TAG, "onPackagesUnavailable(packages=" + Arrays.toString(packages)
+ + ")");
+ }
+ if (isReplacing()) {
+ buildTvInputList(packages);
+ }
+ }
+
@Override
public void onSomePackagesChanged() {
+ // TODO: Use finer-grained methods(e.g. onPackageAdded, onPackageRemoved) to manage
+ // the TV inputs.
if (DEBUG) Slog.d(TAG, "onSomePackagesChanged()");
- synchronized (mLock) {
- buildTvInputListLocked(mCurrentUserId);
- buildTvContentRatingSystemListLocked(mCurrentUserId);
+ if (isReplacing()) {
+ if (DEBUG) Slog.d(TAG, "Skipped building TV input list due to replacing");
+ // When the package is updated, buildTvInputListLocked is called in other
+ // methods instead.
+ return;
}
+ buildTvInputList(null);
}
@Override
public void onPackageRemoved(String packageName, int uid) {
synchronized (mLock) {
- UserState userState = getUserStateLocked(mCurrentUserId);
+ UserState userState = getUserStateLocked(getChangingUserId());
if (!userState.packageSet.contains(packageName)) {
// Not a TV input package.
return;
@@ -218,13 +264,11 @@
component.getPackageName()) == PackageManager.PERMISSION_GRANTED;
}
- private void buildTvInputListLocked(int userId) {
+ private void buildTvInputListLocked(int userId, String[] updatedPackages) {
UserState userState = getUserStateLocked(userId);
userState.packageSet.clear();
- if (DEBUG) {
- Slog.d(TAG, "buildTvInputList");
- }
+ if (DEBUG) Slog.d(TAG, "buildTvInputList");
PackageManager pm = mContext.getPackageManager();
List<ResolveInfo> services = pm.queryIntentServices(
new Intent(TvInputService.SERVICE_INTERFACE),
@@ -278,6 +322,15 @@
for (String inputId : inputMap.keySet()) {
if (!userState.inputMap.containsKey(inputId)) {
notifyInputAddedLocked(userState, inputId);
+ } else if (updatedPackages != null) {
+ // Notify the package updates
+ TvInputState inputState = inputMap.get(inputId);
+ for (String updatedPackage : updatedPackages) {
+ if (inputState.info.getComponent().getPackageName().equals(updatedPackage)) {
+ notifyInputUpdatedLocked(userState, inputId);
+ break;
+ }
+ }
}
}
@@ -337,7 +390,7 @@
userState = new UserState(mContext, userId);
}
mUserStates.put(userId, userState);
- buildTvInputListLocked(userId);
+ buildTvInputListLocked(userId, null);
buildTvContentRatingSystemListLocked(userId);
}
}
@@ -649,6 +702,19 @@
}
}
+ private void notifyInputUpdatedLocked(UserState userState, String inputId) {
+ if (DEBUG) {
+ Slog.d(TAG, "notifyInputUpdatedLocked(inputId=" + inputId + ")");
+ }
+ for (ITvInputManagerCallback callback : userState.callbackSet) {
+ try {
+ callback.onInputUpdated(inputId);
+ } catch (RemoteException e) {
+ Slog.e(TAG, "failed to report updated input to callback", e);
+ }
+ }
+ }
+
private void notifyInputStateChangedLocked(UserState userState, String inputId,
int state, ITvInputManagerCallback targetCallback) {
if (DEBUG) {
@@ -1813,7 +1879,7 @@
private void addTvInputLocked(TvInputInfo inputInfo) {
ServiceState serviceState = getServiceStateLocked(mComponent, mUserId);
serviceState.inputList.add(inputInfo);
- buildTvInputListLocked(mUserId);
+ buildTvInputListLocked(mUserId, null);
}
@Override
@@ -1851,7 +1917,7 @@
}
}
if (removed) {
- buildTvInputListLocked(mUserId);
+ buildTvInputListLocked(mUserId, null);
mTvInputHardwareManager.removeTvInput(inputId);
} else {
Slog.e(TAG, "failed to remove input " + inputId);