Merge "Add extra IApp types and AppLinkInfo APIs"
This commit is contained in:
@@ -37,6 +37,7 @@ import android.view.Surface;
|
||||
*/
|
||||
interface ITvInteractiveAppManager {
|
||||
List<TvInteractiveAppServiceInfo> getTvInteractiveAppServiceList(int userId);
|
||||
List<AppLinkInfo> getAppLinkInfoList(int userId);
|
||||
void registerAppLinkInfo(String tiasId, in AppLinkInfo info, int userId);
|
||||
void unregisterAppLinkInfo(String tiasId, in AppLinkInfo info, int userId);
|
||||
void sendAppLinkCommand(String tiasId, in Bundle command, int userId);
|
||||
|
||||
@@ -864,6 +864,24 @@ public final class TvInteractiveAppManager {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a list of available app link information.
|
||||
*
|
||||
* <P>A package must declare its app link info in its manifest using meta-data tag, so the info
|
||||
* can be detected by the system.
|
||||
*
|
||||
* @return List of {@link AppLinkInfo} for each package that deslares its app link information.
|
||||
* @hide
|
||||
*/
|
||||
@NonNull
|
||||
public List<AppLinkInfo> getAppLinkInfoList() {
|
||||
try {
|
||||
return mService.getAppLinkInfoList(mUserId);
|
||||
} catch (RemoteException e) {
|
||||
throw e.rethrowFromSystemServer();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers an Android application link info record which can be used to launch the specific
|
||||
* Android application by TV interactive App RTE.
|
||||
|
||||
@@ -57,6 +57,8 @@ public final class TvInteractiveAppServiceInfo implements Parcelable {
|
||||
INTERACTIVE_APP_TYPE_HBBTV,
|
||||
INTERACTIVE_APP_TYPE_ATSC,
|
||||
INTERACTIVE_APP_TYPE_GINGA,
|
||||
INTERACTIVE_APP_TYPE_TARGETED_AD,
|
||||
INTERACTIVE_APP_TYPE_OTHER
|
||||
})
|
||||
public @interface InteractiveAppType {}
|
||||
|
||||
@@ -66,10 +68,21 @@ public final class TvInteractiveAppServiceInfo implements Parcelable {
|
||||
public static final int INTERACTIVE_APP_TYPE_ATSC = 0x2;
|
||||
/** Ginga interactive app type */
|
||||
public static final int INTERACTIVE_APP_TYPE_GINGA = 0x4;
|
||||
/**
|
||||
* Targeted Advertisement interactive app type
|
||||
* @hide
|
||||
*/
|
||||
public static final int INTERACTIVE_APP_TYPE_TARGETED_AD = 0x8;
|
||||
/**
|
||||
* Other interactive app type
|
||||
* @hide
|
||||
*/
|
||||
public static final int INTERACTIVE_APP_TYPE_OTHER = 0x80000000;
|
||||
|
||||
private final ResolveInfo mService;
|
||||
private final String mId;
|
||||
private int mTypes;
|
||||
private final List<String> mExtraTypes = new ArrayList<>();
|
||||
|
||||
/**
|
||||
* Constructs a TvInteractiveAppServiceInfo object.
|
||||
@@ -98,18 +111,21 @@ public final class TvInteractiveAppServiceInfo implements Parcelable {
|
||||
|
||||
mService = resolveInfo;
|
||||
mId = id;
|
||||
mTypes = toTypesFlag(types);
|
||||
toTypesFlag(types);
|
||||
}
|
||||
private TvInteractiveAppServiceInfo(ResolveInfo service, String id, int types) {
|
||||
private TvInteractiveAppServiceInfo(
|
||||
ResolveInfo service, String id, int types, List<String> extraTypes) {
|
||||
mService = service;
|
||||
mId = id;
|
||||
mTypes = types;
|
||||
mExtraTypes.addAll(extraTypes);
|
||||
}
|
||||
|
||||
private TvInteractiveAppServiceInfo(@NonNull Parcel in) {
|
||||
mService = ResolveInfo.CREATOR.createFromParcel(in);
|
||||
mId = in.readString();
|
||||
mTypes = in.readInt();
|
||||
in.readStringList(mExtraTypes);
|
||||
}
|
||||
|
||||
public static final @NonNull Creator<TvInteractiveAppServiceInfo> CREATOR =
|
||||
@@ -135,6 +151,7 @@ public final class TvInteractiveAppServiceInfo implements Parcelable {
|
||||
mService.writeToParcel(dest, flags);
|
||||
dest.writeString(mId);
|
||||
dest.writeInt(mTypes);
|
||||
dest.writeStringList(mExtraTypes);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -171,6 +188,17 @@ public final class TvInteractiveAppServiceInfo implements Parcelable {
|
||||
return mTypes;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets extra supported interactive app types which are not listed.
|
||||
*
|
||||
* @see #getSupportedTypes()
|
||||
* @hide
|
||||
*/
|
||||
@NonNull
|
||||
public List<String> getExtraSupportedTypes() {
|
||||
return mExtraTypes;
|
||||
}
|
||||
|
||||
private static String generateInteractiveAppServiceId(ComponentName name) {
|
||||
return name.flattenToShortString();
|
||||
}
|
||||
@@ -219,23 +247,27 @@ public final class TvInteractiveAppServiceInfo implements Parcelable {
|
||||
}
|
||||
}
|
||||
|
||||
private static int toTypesFlag(List<String> types) {
|
||||
int flag = 0;
|
||||
private void toTypesFlag(List<String> types) {
|
||||
mTypes = 0;
|
||||
mExtraTypes.clear();
|
||||
for (String type : types) {
|
||||
switch (type) {
|
||||
case "hbbtv":
|
||||
flag |= INTERACTIVE_APP_TYPE_HBBTV;
|
||||
mTypes |= INTERACTIVE_APP_TYPE_HBBTV;
|
||||
break;
|
||||
case "atsc":
|
||||
flag |= INTERACTIVE_APP_TYPE_ATSC;
|
||||
mTypes |= INTERACTIVE_APP_TYPE_ATSC;
|
||||
break;
|
||||
case "ginga":
|
||||
flag |= INTERACTIVE_APP_TYPE_GINGA;
|
||||
mTypes |= INTERACTIVE_APP_TYPE_GINGA;
|
||||
break;
|
||||
case "targeted_ad":
|
||||
mTypes |= INTERACTIVE_APP_TYPE_TARGETED_AD;
|
||||
default:
|
||||
mTypes |= INTERACTIVE_APP_TYPE_OTHER;
|
||||
mExtraTypes.add(type);
|
||||
break;
|
||||
}
|
||||
}
|
||||
return flag;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -24,6 +24,7 @@ import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.IntentFilter;
|
||||
import android.content.ServiceConnection;
|
||||
import android.content.pm.ApplicationInfo;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.content.pm.ResolveInfo;
|
||||
import android.content.pm.ServiceInfo;
|
||||
@@ -86,6 +87,11 @@ import java.util.Set;
|
||||
public class TvInteractiveAppManagerService extends SystemService {
|
||||
private static final boolean DEBUG = false;
|
||||
private static final String TAG = "TvInteractiveAppManagerService";
|
||||
|
||||
private static final String METADATA_CLASS_NAME =
|
||||
"android.media.tv.interactive.AppLinkInfo.ClassName";
|
||||
private static final String METADATA_URI =
|
||||
"android.media.tv.interactive.AppLinkInfo.Uri";
|
||||
// A global lock.
|
||||
private final Object mLock = new Object();
|
||||
private final Context mContext;
|
||||
@@ -102,6 +108,8 @@ public class TvInteractiveAppManagerService extends SystemService {
|
||||
// TODO: remove mGetServiceListCalled if onBootPhrase work correctly
|
||||
@GuardedBy("mLock")
|
||||
private boolean mGetServiceListCalled = false;
|
||||
@GuardedBy("mLock")
|
||||
private boolean mGetAppLinkInfoListCalled = false;
|
||||
|
||||
private final UserManager mUserManager;
|
||||
|
||||
@@ -120,6 +128,41 @@ public class TvInteractiveAppManagerService extends SystemService {
|
||||
mUserManager = (UserManager) getContext().getSystemService(Context.USER_SERVICE);
|
||||
}
|
||||
|
||||
@GuardedBy("mLock")
|
||||
private void buildAppLinkInfoLocked(int userId) {
|
||||
UserState userState = getOrCreateUserStateLocked(userId);
|
||||
if (DEBUG) {
|
||||
Slogf.d(TAG, "buildAppLinkInfoLocked");
|
||||
}
|
||||
PackageManager pm = mContext.getPackageManager();
|
||||
List<ApplicationInfo> appInfos = pm.getInstalledApplicationsAsUser(
|
||||
PackageManager.ApplicationInfoFlags.of(PackageManager.GET_META_DATA), userId);
|
||||
List<AppLinkInfo> appLinkInfos = new ArrayList<>();
|
||||
for (ApplicationInfo appInfo : appInfos) {
|
||||
AppLinkInfo info = buildAppLinkInfoLocked(appInfo);
|
||||
if (info != null) {
|
||||
appLinkInfos.add(info);
|
||||
}
|
||||
}
|
||||
// sort the list by package name
|
||||
Collections.sort(appLinkInfos, Comparator.comparing(AppLinkInfo::getComponentName));
|
||||
userState.mAppLinkInfoList.clear();
|
||||
userState.mAppLinkInfoList.addAll(appLinkInfos);
|
||||
}
|
||||
|
||||
@GuardedBy("mLock")
|
||||
private AppLinkInfo buildAppLinkInfoLocked(ApplicationInfo appInfo) {
|
||||
if (appInfo.metaData == null || appInfo.packageName == null) {
|
||||
return null;
|
||||
}
|
||||
String className = appInfo.metaData.getString(METADATA_CLASS_NAME, null);
|
||||
String uri = appInfo.metaData.getString(METADATA_URI, null);
|
||||
if (className == null || uri == null) {
|
||||
return null;
|
||||
}
|
||||
return new AppLinkInfo(appInfo.packageName, className, uri);
|
||||
}
|
||||
|
||||
@GuardedBy("mLock")
|
||||
private void buildTvInteractiveAppServiceListLocked(int userId, String[] updatedPackages) {
|
||||
UserState userState = getOrCreateUserStateLocked(userId);
|
||||
@@ -311,6 +354,7 @@ public class TvInteractiveAppManagerService extends SystemService {
|
||||
} else if (phase == SystemService.PHASE_THIRD_PARTY_APPS_CAN_START) {
|
||||
synchronized (mLock) {
|
||||
buildTvInteractiveAppServiceListLocked(mCurrentUserId, null);
|
||||
buildAppLinkInfoLocked(mCurrentUserId);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -322,6 +366,7 @@ public class TvInteractiveAppManagerService extends SystemService {
|
||||
synchronized (mLock) {
|
||||
if (mCurrentUserId == userId || mRunningProfiles.contains(userId)) {
|
||||
buildTvInteractiveAppServiceListLocked(userId, packages);
|
||||
buildAppLinkInfoLocked(userId);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -428,6 +473,7 @@ public class TvInteractiveAppManagerService extends SystemService {
|
||||
|
||||
mCurrentUserId = userId;
|
||||
buildTvInteractiveAppServiceListLocked(userId, null);
|
||||
buildAppLinkInfoLocked(userId);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -513,6 +559,7 @@ public class TvInteractiveAppManagerService extends SystemService {
|
||||
private void startProfileLocked(int userId) {
|
||||
mRunningProfiles.add(userId);
|
||||
buildTvInteractiveAppServiceListLocked(userId, null);
|
||||
buildAppLinkInfoLocked(userId);
|
||||
}
|
||||
|
||||
@GuardedBy("mLock")
|
||||
@@ -667,6 +714,26 @@ public class TvInteractiveAppManagerService extends SystemService {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<AppLinkInfo> getAppLinkInfoList(int userId) {
|
||||
final int resolvedUserId = resolveCallingUserId(Binder.getCallingPid(),
|
||||
Binder.getCallingUid(), userId, "getAppLinkInfoList");
|
||||
final long identity = Binder.clearCallingIdentity();
|
||||
try {
|
||||
synchronized (mLock) {
|
||||
if (!mGetAppLinkInfoListCalled) {
|
||||
buildAppLinkInfoLocked(userId);
|
||||
mGetAppLinkInfoListCalled = true;
|
||||
}
|
||||
UserState userState = getOrCreateUserStateLocked(resolvedUserId);
|
||||
List<AppLinkInfo> appLinkInfos = new ArrayList<>(userState.mAppLinkInfoList);
|
||||
return appLinkInfos;
|
||||
}
|
||||
} finally {
|
||||
Binder.restoreCallingIdentity(identity);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void registerAppLinkInfo(String tiasId, AppLinkInfo appLinkInfo, int userId) {
|
||||
final int resolvedUserId = resolveCallingUserId(Binder.getCallingPid(),
|
||||
@@ -1996,6 +2063,8 @@ public class TvInteractiveAppManagerService extends SystemService {
|
||||
|
||||
// A set of all TV Interactive App service packages.
|
||||
private final Set<String> mPackageSet = new HashSet<>();
|
||||
// A list of all app link infos.
|
||||
private final List<AppLinkInfo> mAppLinkInfoList = new ArrayList<>();
|
||||
|
||||
// A list of callbacks.
|
||||
private final RemoteCallbackList<ITvInteractiveAppManagerCallback> mCallbacks =
|
||||
|
||||
Reference in New Issue
Block a user