Merge "Use RemoteCallbackList to store registered callbacks" into qt-dev

am: 60f7b58a9a

Change-Id: I6eace2328a4397205e522b5525ecf8cae243c031
This commit is contained in:
Mehdi Alizadeh
2019-06-20 13:15:51 -07:00
committed by android-build-merger

View File

@@ -28,7 +28,7 @@ import android.content.pm.PackageManager;
import android.content.pm.PackageManager.NameNotFoundException; import android.content.pm.PackageManager.NameNotFoundException;
import android.content.pm.ParceledListSlice; import android.content.pm.ParceledListSlice;
import android.content.pm.ServiceInfo; import android.content.pm.ServiceInfo;
import android.os.IBinder; import android.os.RemoteCallbackList;
import android.os.RemoteException; import android.os.RemoteException;
import android.service.appprediction.AppPredictionService; import android.service.appprediction.AppPredictionService;
import android.util.ArrayMap; import android.util.ArrayMap;
@@ -37,7 +37,7 @@ import android.util.Slog;
import com.android.internal.annotations.GuardedBy; import com.android.internal.annotations.GuardedBy;
import com.android.server.infra.AbstractPerUserSystemService; import com.android.server.infra.AbstractPerUserSystemService;
import java.util.ArrayList; import java.util.function.Consumer;
/** /**
* Per-user instance of {@link AppPredictionManagerService}. * Per-user instance of {@link AppPredictionManagerService}.
@@ -108,16 +108,11 @@ public class AppPredictionPerUserService extends
if (service != null) { if (service != null) {
service.onCreatePredictionSession(context, sessionId); service.onCreatePredictionSession(context, sessionId);
mSessionInfos.put(sessionId, new AppPredictionSessionInfo(sessionId, context, () -> { if (!mSessionInfos.containsKey(sessionId)) {
synchronized (mLock) { mSessionInfos.put(sessionId, new AppPredictionSessionInfo(sessionId, context,
AppPredictionSessionInfo sessionInfo = mSessionInfos.get(sessionId); this::removeAppPredictionSessionInfo));
if (sessionInfo != null) {
sessionInfo.removeAllCallbacksLocked();
mSessionInfos.remove(sessionId);
} }
} }
}));
}
} }
/** /**
@@ -212,8 +207,7 @@ public class AppPredictionPerUserService extends
AppPredictionSessionInfo sessionInfo = mSessionInfos.get(sessionId); AppPredictionSessionInfo sessionInfo = mSessionInfos.get(sessionId);
if (sessionInfo != null) { if (sessionInfo != null) {
sessionInfo.removeAllCallbacksLocked(); sessionInfo.destroy();
mSessionInfos.remove(sessionId);
} }
} }
} }
@@ -273,6 +267,15 @@ public class AppPredictionPerUserService extends
} }
} }
private void removeAppPredictionSessionInfo(AppPredictionSessionId sessionId) {
if (isDebug()) {
Slog.d(TAG, "removeAppPredictionSessionInfo(): sessionId=" + sessionId);
}
synchronized (mLock) {
mSessionInfos.remove(sessionId);
}
}
@GuardedBy("mLock") @GuardedBy("mLock")
@Nullable @Nullable
private RemoteAppPredictionService getRemoteServiceLocked() { private RemoteAppPredictionService getRemoteServiceLocked() {
@@ -295,55 +298,71 @@ public class AppPredictionPerUserService extends
} }
private static final class AppPredictionSessionInfo { private static final class AppPredictionSessionInfo {
private final AppPredictionSessionId mSessionId; private static final boolean DEBUG = false; // Do not submit with true
private final AppPredictionContext mContext;
private final ArrayList<IPredictionCallback> mCallbacks = new ArrayList<>();
private final IBinder.DeathRecipient mBinderDeathHandler;
AppPredictionSessionInfo(AppPredictionSessionId id, AppPredictionContext context, private final AppPredictionSessionId mSessionId;
IBinder.DeathRecipient binderDeathHandler) { private final AppPredictionContext mPredictionContext;
private final Consumer<AppPredictionSessionId> mRemoveSessionInfoAction;
private final RemoteCallbackList<IPredictionCallback> mCallbacks =
new RemoteCallbackList<IPredictionCallback>() {
@Override
public void onCallbackDied(IPredictionCallback callback) {
if (DEBUG) {
Slog.d(TAG, "Binder died for session Id=" + mSessionId
+ " and callback=" + callback.asBinder());
}
if (mCallbacks.getRegisteredCallbackCount() == 0) {
destroy();
}
}
};
AppPredictionSessionInfo(AppPredictionSessionId id, AppPredictionContext predictionContext,
Consumer<AppPredictionSessionId> removeSessionInfoAction) {
if (DEBUG) {
Slog.d(TAG, "Creating AppPredictionSessionInfo for session Id=" + id);
}
mSessionId = id; mSessionId = id;
mContext = context; mPredictionContext = predictionContext;
mBinderDeathHandler = binderDeathHandler; mRemoveSessionInfoAction = removeSessionInfoAction;
} }
void addCallbackLocked(IPredictionCallback callback) { void addCallbackLocked(IPredictionCallback callback) {
if (mBinderDeathHandler != null) { if (DEBUG) {
try { Slog.d(TAG, "Storing callback for session Id=" + mSessionId
callback.asBinder().linkToDeath(mBinderDeathHandler, 0); + " and callback=" + callback.asBinder());
} catch (RemoteException e) {
Slog.e(TAG, "Failed to link to death: " + e);
} }
} mCallbacks.register(callback);
mCallbacks.add(callback);
} }
void removeCallbackLocked(IPredictionCallback callback) { void removeCallbackLocked(IPredictionCallback callback) {
if (mBinderDeathHandler != null) { if (DEBUG) {
callback.asBinder().unlinkToDeath(mBinderDeathHandler, 0); Slog.d(TAG, "Removing callback for session Id=" + mSessionId
+ " and callback=" + callback.asBinder());
} }
mCallbacks.remove(callback); mCallbacks.unregister(callback);
} }
void removeAllCallbacksLocked() { void destroy() {
if (mBinderDeathHandler != null) { if (DEBUG) {
for (IPredictionCallback callback : mCallbacks) { Slog.d(TAG, "Removing all callbacks for session Id=" + mSessionId
callback.asBinder().unlinkToDeath(mBinderDeathHandler, 0); + " and " + mCallbacks.getRegisteredCallbackCount() + " callbacks.");
} }
} mCallbacks.kill();
mCallbacks.clear(); mRemoveSessionInfoAction.accept(mSessionId);
} }
void resurrectSessionLocked(AppPredictionPerUserService service) { void resurrectSessionLocked(AppPredictionPerUserService service) {
if (service.isDebug()) { int callbackCount = mCallbacks.getRegisteredCallbackCount();
if (DEBUG) {
Slog.d(TAG, "Resurrecting remote service (" + service.getRemoteServiceLocked() Slog.d(TAG, "Resurrecting remote service (" + service.getRemoteServiceLocked()
+ ") for session Id=" + mSessionId + " and " + ") for session Id=" + mSessionId + " and "
+ mCallbacks.size() + " callbacks."); + callbackCount + " callbacks.");
}
service.onCreatePredictionSessionLocked(mContext, mSessionId);
for (IPredictionCallback callback : mCallbacks) {
service.registerPredictionUpdatesLocked(mSessionId, callback);
} }
service.onCreatePredictionSessionLocked(mPredictionContext, mSessionId);
mCallbacks.broadcast(
callback -> service.registerPredictionUpdatesLocked(mSessionId, callback));
} }
} }
} }