Loading core/java/android/app/prediction/AppPredictionContext.java +10 −0 Original line number Diff line number Diff line Loading @@ -100,6 +100,16 @@ public final class AppPredictionContext implements Parcelable { && mPackageName.equals(other.mPackageName); } @NonNull @Override public String toString() { return new StringBuilder(this.getClass().getSimpleName()) .append("[mUiSurface=").append(mUiSurface) .append(",mPackageName=").append(mPackageName) .append(",mPredictedTargetCount=").append(mPredictedTargetCount) .append(",mExtras=").append(mExtras.toString()).append("]").toString(); } @Override public int describeContents() { return 0; Loading services/appprediction/java/com/android/server/appprediction/AppPredictionPerUserService.java +84 −41 Original line number Diff line number Diff line Loading @@ -32,11 +32,14 @@ import android.os.RemoteCallbackList; import android.os.RemoteException; import android.service.appprediction.AppPredictionService; import android.util.ArrayMap; import android.util.ArraySet; import android.util.Slog; import com.android.internal.annotations.GuardedBy; import com.android.server.infra.AbstractPerUserSystemService; import java.util.Map; import java.util.Set; import java.util.function.Consumer; /** Loading @@ -48,9 +51,13 @@ public class AppPredictionPerUserService extends private static final String TAG = AppPredictionPerUserService.class.getSimpleName(); @Nullable /** * A lookup of remote services in respect to their {@link ComponentName}. */ @NonNull @GuardedBy("mLock") private RemoteAppPredictionService mRemoteService; private final ArrayMap<ComponentName, RemoteAppPredictionService> mRemoteServices = new ArrayMap<>(); /** * When {@code true}, remote service died but service state is kept so it's restored after Loading Loading @@ -92,7 +99,7 @@ public class AppPredictionPerUserService extends if (enabledChanged) { if (!isEnabledLocked()) { // Clear the remote service for the next call mRemoteService = null; mRemoteServices.clear(); } } return enabledChanged; Loading @@ -104,14 +111,14 @@ public class AppPredictionPerUserService extends @GuardedBy("mLock") public void onCreatePredictionSessionLocked(@NonNull AppPredictionContext context, @NonNull AppPredictionSessionId sessionId) { final RemoteAppPredictionService service = getRemoteServiceLocked(); if (service != null) { service.onCreatePredictionSession(context, sessionId); if (!mSessionInfos.containsKey(sessionId)) { mSessionInfos.put(sessionId, new AppPredictionSessionInfo(sessionId, context, this::removeAppPredictionSessionInfo)); resolveComponentName(context), this::removeAppPredictionSessionInfo)); } final RemoteAppPredictionService service = getRemoteServiceLocked( getComponentName(sessionId)); if (service != null) { service.onCreatePredictionSession(context, sessionId); } } Loading @@ -121,7 +128,8 @@ public class AppPredictionPerUserService extends @GuardedBy("mLock") public void notifyAppTargetEventLocked(@NonNull AppPredictionSessionId sessionId, @NonNull AppTargetEvent event) { final RemoteAppPredictionService service = getRemoteServiceLocked(); final RemoteAppPredictionService service = getRemoteServiceLocked( getComponentName(sessionId)); if (service != null) { service.notifyAppTargetEvent(sessionId, event); } Loading @@ -133,7 +141,8 @@ public class AppPredictionPerUserService extends @GuardedBy("mLock") public void notifyLaunchLocationShownLocked(@NonNull AppPredictionSessionId sessionId, @NonNull String launchLocation, @NonNull ParceledListSlice targetIds) { final RemoteAppPredictionService service = getRemoteServiceLocked(); final RemoteAppPredictionService service = getRemoteServiceLocked( getComponentName(sessionId)); if (service != null) { service.notifyLaunchLocationShown(sessionId, launchLocation, targetIds); } Loading @@ -145,7 +154,8 @@ public class AppPredictionPerUserService extends @GuardedBy("mLock") public void sortAppTargetsLocked(@NonNull AppPredictionSessionId sessionId, @NonNull ParceledListSlice targets, @NonNull IPredictionCallback callback) { final RemoteAppPredictionService service = getRemoteServiceLocked(); final RemoteAppPredictionService service = getRemoteServiceLocked( getComponentName(sessionId)); if (service != null) { service.sortAppTargets(sessionId, targets, callback); } Loading @@ -157,7 +167,8 @@ public class AppPredictionPerUserService extends @GuardedBy("mLock") public void registerPredictionUpdatesLocked(@NonNull AppPredictionSessionId sessionId, @NonNull IPredictionCallback callback) { final RemoteAppPredictionService service = getRemoteServiceLocked(); final RemoteAppPredictionService service = getRemoteServiceLocked( getComponentName(sessionId)); if (service != null) { service.registerPredictionUpdates(sessionId, callback); Loading @@ -174,7 +185,8 @@ public class AppPredictionPerUserService extends @GuardedBy("mLock") public void unregisterPredictionUpdatesLocked(@NonNull AppPredictionSessionId sessionId, @NonNull IPredictionCallback callback) { final RemoteAppPredictionService service = getRemoteServiceLocked(); final RemoteAppPredictionService service = getRemoteServiceLocked( getComponentName(sessionId)); if (service != null) { service.unregisterPredictionUpdates(sessionId, callback); Loading @@ -190,7 +202,8 @@ public class AppPredictionPerUserService extends */ @GuardedBy("mLock") public void requestPredictionUpdateLocked(@NonNull AppPredictionSessionId sessionId) { final RemoteAppPredictionService service = getRemoteServiceLocked(); final RemoteAppPredictionService service = getRemoteServiceLocked( getComponentName(sessionId)); if (service != null) { service.requestPredictionUpdate(sessionId); } Loading @@ -201,7 +214,8 @@ public class AppPredictionPerUserService extends */ @GuardedBy("mLock") public void onDestroyPredictionSessionLocked(@NonNull AppPredictionSessionId sessionId) { final RemoteAppPredictionService service = getRemoteServiceLocked(); final RemoteAppPredictionService service = getRemoteServiceLocked( getComponentName(sessionId)); if (service != null) { service.onDestroyPredictionSession(sessionId); Loading Loading @@ -229,7 +243,7 @@ public class AppPredictionPerUserService extends synchronized (mLock) { if (mZombie) { // Sanity check - shouldn't happen if (mRemoteService == null) { if (mRemoteServices.isEmpty()) { Slog.w(TAG, "Cannot resurrect sessions because remote service is null"); return; } Loading Loading @@ -266,22 +280,30 @@ public class AppPredictionPerUserService extends } private void destroyAndRebindRemoteService() { if (mRemoteService == null) { if (mRemoteServices.isEmpty()) { return; } if (isDebug()) { Slog.d(TAG, "Destroying the old remote service."); } mRemoteService.destroy(); mRemoteService = null; final Set<Map.Entry<ComponentName, RemoteAppPredictionService>> services = new ArraySet<>(mRemoteServices.entrySet()); mRemoteServices.clear(); services.stream().forEach(entry -> destroyAndRebindRemoteService( entry.getKey(), entry.getValue())); } mRemoteService = getRemoteServiceLocked(); if (mRemoteService != null) { private void destroyAndRebindRemoteService( @NonNull final ComponentName component, @NonNull final RemoteAppPredictionService service) { service.destroy(); final RemoteAppPredictionService newService = getRemoteServiceLocked(component); if (newService != null) { if (isDebug()) { Slog.d(TAG, "Rebinding to the new remote service."); } mRemoteService.reconnect(); newService.reconnect(); } } Loading @@ -292,7 +314,7 @@ public class AppPredictionPerUserService extends private void resurrectSessionsLocked() { final int numSessions = mSessionInfos.size(); if (isDebug()) { Slog.d(TAG, "Resurrecting remote service (" + mRemoteService + ") on " Slog.d(TAG, "Resurrecting remote service (" + mRemoteServices + ") on " + numSessions + " sessions."); } Loading @@ -310,32 +332,49 @@ public class AppPredictionPerUserService extends } } @GuardedBy("mLock") @Nullable private RemoteAppPredictionService getRemoteServiceLocked() { if (mRemoteService == null) { private ComponentName resolveComponentName(@NonNull final AppPredictionContext context) { // TODO: add logic to determine serviceName based on context final String serviceName = getComponentNameLocked(); if (serviceName == null) { if (mMaster.verbose) { Slog.v(TAG, "getRemoteServiceLocked(): not set"); Slog.v(TAG, "getRemoteServiceLocked(): not set, context = " + context); } return null; } ComponentName serviceComponent = ComponentName.unflattenFromString(serviceName); return ComponentName.unflattenFromString(serviceName); } mRemoteService = new RemoteAppPredictionService(getContext(), @Nullable private ComponentName getComponentName(@NonNull final AppPredictionSessionId sessionId) { AppPredictionSessionInfo sessionInfo = mSessionInfos.get(sessionId); return sessionInfo == null ? null : sessionInfo.mComponentName; } @GuardedBy("mLock") @Nullable private RemoteAppPredictionService getRemoteServiceLocked( @Nullable final ComponentName serviceComponent) { if (serviceComponent == null) return null; if (!mRemoteServices.containsKey(serviceComponent)) { mRemoteServices.put(serviceComponent, new RemoteAppPredictionService(getContext(), AppPredictionService.SERVICE_INTERFACE, serviceComponent, mUserId, this, mMaster.isBindInstantServiceAllowed(), mMaster.verbose); mMaster.isBindInstantServiceAllowed(), mMaster.verbose)); } return mRemoteService; return mRemoteServices.get(serviceComponent); } private static final class AppPredictionSessionInfo { private static final boolean DEBUG = false; // Do not submit with true @NonNull private final AppPredictionSessionId mSessionId; @NonNull private final AppPredictionContext mPredictionContext; @Nullable private final ComponentName mComponentName; @NonNull private final Consumer<AppPredictionSessionId> mRemoveSessionInfoAction; private final RemoteCallbackList<IPredictionCallback> mCallbacks = Loading @@ -352,13 +391,17 @@ public class AppPredictionPerUserService extends } }; AppPredictionSessionInfo(AppPredictionSessionId id, AppPredictionContext predictionContext, Consumer<AppPredictionSessionId> removeSessionInfoAction) { AppPredictionSessionInfo( @NonNull final AppPredictionSessionId id, @NonNull final AppPredictionContext predictionContext, @Nullable final ComponentName componentName, @NonNull final Consumer<AppPredictionSessionId> removeSessionInfoAction) { if (DEBUG) { Slog.d(TAG, "Creating AppPredictionSessionInfo for session Id=" + id); } mSessionId = id; mPredictionContext = predictionContext; mComponentName = componentName; mRemoveSessionInfoAction = removeSessionInfoAction; } Loading Loading @@ -390,8 +433,8 @@ public class AppPredictionPerUserService extends void resurrectSessionLocked(AppPredictionPerUserService service) { int callbackCount = mCallbacks.getRegisteredCallbackCount(); if (DEBUG) { Slog.d(TAG, "Resurrecting remote service (" + service.getRemoteServiceLocked() + ") for session Id=" + mSessionId + " and " Slog.d(TAG, "Resurrecting remote service (" + service.getRemoteServiceLocked( mComponentName) + ") for session Id=" + mSessionId + " and " + callbackCount + " callbacks."); } service.onCreatePredictionSessionLocked(mPredictionContext, mSessionId); Loading Loading
core/java/android/app/prediction/AppPredictionContext.java +10 −0 Original line number Diff line number Diff line Loading @@ -100,6 +100,16 @@ public final class AppPredictionContext implements Parcelable { && mPackageName.equals(other.mPackageName); } @NonNull @Override public String toString() { return new StringBuilder(this.getClass().getSimpleName()) .append("[mUiSurface=").append(mUiSurface) .append(",mPackageName=").append(mPackageName) .append(",mPredictedTargetCount=").append(mPredictedTargetCount) .append(",mExtras=").append(mExtras.toString()).append("]").toString(); } @Override public int describeContents() { return 0; Loading
services/appprediction/java/com/android/server/appprediction/AppPredictionPerUserService.java +84 −41 Original line number Diff line number Diff line Loading @@ -32,11 +32,14 @@ import android.os.RemoteCallbackList; import android.os.RemoteException; import android.service.appprediction.AppPredictionService; import android.util.ArrayMap; import android.util.ArraySet; import android.util.Slog; import com.android.internal.annotations.GuardedBy; import com.android.server.infra.AbstractPerUserSystemService; import java.util.Map; import java.util.Set; import java.util.function.Consumer; /** Loading @@ -48,9 +51,13 @@ public class AppPredictionPerUserService extends private static final String TAG = AppPredictionPerUserService.class.getSimpleName(); @Nullable /** * A lookup of remote services in respect to their {@link ComponentName}. */ @NonNull @GuardedBy("mLock") private RemoteAppPredictionService mRemoteService; private final ArrayMap<ComponentName, RemoteAppPredictionService> mRemoteServices = new ArrayMap<>(); /** * When {@code true}, remote service died but service state is kept so it's restored after Loading Loading @@ -92,7 +99,7 @@ public class AppPredictionPerUserService extends if (enabledChanged) { if (!isEnabledLocked()) { // Clear the remote service for the next call mRemoteService = null; mRemoteServices.clear(); } } return enabledChanged; Loading @@ -104,14 +111,14 @@ public class AppPredictionPerUserService extends @GuardedBy("mLock") public void onCreatePredictionSessionLocked(@NonNull AppPredictionContext context, @NonNull AppPredictionSessionId sessionId) { final RemoteAppPredictionService service = getRemoteServiceLocked(); if (service != null) { service.onCreatePredictionSession(context, sessionId); if (!mSessionInfos.containsKey(sessionId)) { mSessionInfos.put(sessionId, new AppPredictionSessionInfo(sessionId, context, this::removeAppPredictionSessionInfo)); resolveComponentName(context), this::removeAppPredictionSessionInfo)); } final RemoteAppPredictionService service = getRemoteServiceLocked( getComponentName(sessionId)); if (service != null) { service.onCreatePredictionSession(context, sessionId); } } Loading @@ -121,7 +128,8 @@ public class AppPredictionPerUserService extends @GuardedBy("mLock") public void notifyAppTargetEventLocked(@NonNull AppPredictionSessionId sessionId, @NonNull AppTargetEvent event) { final RemoteAppPredictionService service = getRemoteServiceLocked(); final RemoteAppPredictionService service = getRemoteServiceLocked( getComponentName(sessionId)); if (service != null) { service.notifyAppTargetEvent(sessionId, event); } Loading @@ -133,7 +141,8 @@ public class AppPredictionPerUserService extends @GuardedBy("mLock") public void notifyLaunchLocationShownLocked(@NonNull AppPredictionSessionId sessionId, @NonNull String launchLocation, @NonNull ParceledListSlice targetIds) { final RemoteAppPredictionService service = getRemoteServiceLocked(); final RemoteAppPredictionService service = getRemoteServiceLocked( getComponentName(sessionId)); if (service != null) { service.notifyLaunchLocationShown(sessionId, launchLocation, targetIds); } Loading @@ -145,7 +154,8 @@ public class AppPredictionPerUserService extends @GuardedBy("mLock") public void sortAppTargetsLocked(@NonNull AppPredictionSessionId sessionId, @NonNull ParceledListSlice targets, @NonNull IPredictionCallback callback) { final RemoteAppPredictionService service = getRemoteServiceLocked(); final RemoteAppPredictionService service = getRemoteServiceLocked( getComponentName(sessionId)); if (service != null) { service.sortAppTargets(sessionId, targets, callback); } Loading @@ -157,7 +167,8 @@ public class AppPredictionPerUserService extends @GuardedBy("mLock") public void registerPredictionUpdatesLocked(@NonNull AppPredictionSessionId sessionId, @NonNull IPredictionCallback callback) { final RemoteAppPredictionService service = getRemoteServiceLocked(); final RemoteAppPredictionService service = getRemoteServiceLocked( getComponentName(sessionId)); if (service != null) { service.registerPredictionUpdates(sessionId, callback); Loading @@ -174,7 +185,8 @@ public class AppPredictionPerUserService extends @GuardedBy("mLock") public void unregisterPredictionUpdatesLocked(@NonNull AppPredictionSessionId sessionId, @NonNull IPredictionCallback callback) { final RemoteAppPredictionService service = getRemoteServiceLocked(); final RemoteAppPredictionService service = getRemoteServiceLocked( getComponentName(sessionId)); if (service != null) { service.unregisterPredictionUpdates(sessionId, callback); Loading @@ -190,7 +202,8 @@ public class AppPredictionPerUserService extends */ @GuardedBy("mLock") public void requestPredictionUpdateLocked(@NonNull AppPredictionSessionId sessionId) { final RemoteAppPredictionService service = getRemoteServiceLocked(); final RemoteAppPredictionService service = getRemoteServiceLocked( getComponentName(sessionId)); if (service != null) { service.requestPredictionUpdate(sessionId); } Loading @@ -201,7 +214,8 @@ public class AppPredictionPerUserService extends */ @GuardedBy("mLock") public void onDestroyPredictionSessionLocked(@NonNull AppPredictionSessionId sessionId) { final RemoteAppPredictionService service = getRemoteServiceLocked(); final RemoteAppPredictionService service = getRemoteServiceLocked( getComponentName(sessionId)); if (service != null) { service.onDestroyPredictionSession(sessionId); Loading Loading @@ -229,7 +243,7 @@ public class AppPredictionPerUserService extends synchronized (mLock) { if (mZombie) { // Sanity check - shouldn't happen if (mRemoteService == null) { if (mRemoteServices.isEmpty()) { Slog.w(TAG, "Cannot resurrect sessions because remote service is null"); return; } Loading Loading @@ -266,22 +280,30 @@ public class AppPredictionPerUserService extends } private void destroyAndRebindRemoteService() { if (mRemoteService == null) { if (mRemoteServices.isEmpty()) { return; } if (isDebug()) { Slog.d(TAG, "Destroying the old remote service."); } mRemoteService.destroy(); mRemoteService = null; final Set<Map.Entry<ComponentName, RemoteAppPredictionService>> services = new ArraySet<>(mRemoteServices.entrySet()); mRemoteServices.clear(); services.stream().forEach(entry -> destroyAndRebindRemoteService( entry.getKey(), entry.getValue())); } mRemoteService = getRemoteServiceLocked(); if (mRemoteService != null) { private void destroyAndRebindRemoteService( @NonNull final ComponentName component, @NonNull final RemoteAppPredictionService service) { service.destroy(); final RemoteAppPredictionService newService = getRemoteServiceLocked(component); if (newService != null) { if (isDebug()) { Slog.d(TAG, "Rebinding to the new remote service."); } mRemoteService.reconnect(); newService.reconnect(); } } Loading @@ -292,7 +314,7 @@ public class AppPredictionPerUserService extends private void resurrectSessionsLocked() { final int numSessions = mSessionInfos.size(); if (isDebug()) { Slog.d(TAG, "Resurrecting remote service (" + mRemoteService + ") on " Slog.d(TAG, "Resurrecting remote service (" + mRemoteServices + ") on " + numSessions + " sessions."); } Loading @@ -310,32 +332,49 @@ public class AppPredictionPerUserService extends } } @GuardedBy("mLock") @Nullable private RemoteAppPredictionService getRemoteServiceLocked() { if (mRemoteService == null) { private ComponentName resolveComponentName(@NonNull final AppPredictionContext context) { // TODO: add logic to determine serviceName based on context final String serviceName = getComponentNameLocked(); if (serviceName == null) { if (mMaster.verbose) { Slog.v(TAG, "getRemoteServiceLocked(): not set"); Slog.v(TAG, "getRemoteServiceLocked(): not set, context = " + context); } return null; } ComponentName serviceComponent = ComponentName.unflattenFromString(serviceName); return ComponentName.unflattenFromString(serviceName); } mRemoteService = new RemoteAppPredictionService(getContext(), @Nullable private ComponentName getComponentName(@NonNull final AppPredictionSessionId sessionId) { AppPredictionSessionInfo sessionInfo = mSessionInfos.get(sessionId); return sessionInfo == null ? null : sessionInfo.mComponentName; } @GuardedBy("mLock") @Nullable private RemoteAppPredictionService getRemoteServiceLocked( @Nullable final ComponentName serviceComponent) { if (serviceComponent == null) return null; if (!mRemoteServices.containsKey(serviceComponent)) { mRemoteServices.put(serviceComponent, new RemoteAppPredictionService(getContext(), AppPredictionService.SERVICE_INTERFACE, serviceComponent, mUserId, this, mMaster.isBindInstantServiceAllowed(), mMaster.verbose); mMaster.isBindInstantServiceAllowed(), mMaster.verbose)); } return mRemoteService; return mRemoteServices.get(serviceComponent); } private static final class AppPredictionSessionInfo { private static final boolean DEBUG = false; // Do not submit with true @NonNull private final AppPredictionSessionId mSessionId; @NonNull private final AppPredictionContext mPredictionContext; @Nullable private final ComponentName mComponentName; @NonNull private final Consumer<AppPredictionSessionId> mRemoveSessionInfoAction; private final RemoteCallbackList<IPredictionCallback> mCallbacks = Loading @@ -352,13 +391,17 @@ public class AppPredictionPerUserService extends } }; AppPredictionSessionInfo(AppPredictionSessionId id, AppPredictionContext predictionContext, Consumer<AppPredictionSessionId> removeSessionInfoAction) { AppPredictionSessionInfo( @NonNull final AppPredictionSessionId id, @NonNull final AppPredictionContext predictionContext, @Nullable final ComponentName componentName, @NonNull final Consumer<AppPredictionSessionId> removeSessionInfoAction) { if (DEBUG) { Slog.d(TAG, "Creating AppPredictionSessionInfo for session Id=" + id); } mSessionId = id; mPredictionContext = predictionContext; mComponentName = componentName; mRemoveSessionInfoAction = removeSessionInfoAction; } Loading Loading @@ -390,8 +433,8 @@ public class AppPredictionPerUserService extends void resurrectSessionLocked(AppPredictionPerUserService service) { int callbackCount = mCallbacks.getRegisteredCallbackCount(); if (DEBUG) { Slog.d(TAG, "Resurrecting remote service (" + service.getRemoteServiceLocked() + ") for session Id=" + mSessionId + " and " Slog.d(TAG, "Resurrecting remote service (" + service.getRemoteServiceLocked( mComponentName) + ") for session Id=" + mSessionId + " and " + callbackCount + " callbacks."); } service.onCreatePredictionSessionLocked(mPredictionContext, mSessionId); Loading