diff options
| -rw-r--r-- | core/java/android/app/prediction/AppPredictor.java | 44 |
1 files changed, 34 insertions, 10 deletions
diff --git a/core/java/android/app/prediction/AppPredictor.java b/core/java/android/app/prediction/AppPredictor.java index db3a1921c1ba..d736a219b61a 100644 --- a/core/java/android/app/prediction/AppPredictor.java +++ b/core/java/android/app/prediction/AppPredictor.java @@ -30,6 +30,8 @@ import android.os.ServiceManager; import android.util.ArrayMap; import android.util.Log; +import com.android.internal.annotations.GuardedBy; + import dalvik.system.CloseGuard; import java.util.List; @@ -74,12 +76,12 @@ public final class AppPredictor { private static final String TAG = AppPredictor.class.getSimpleName(); - private final IPredictionManager mPredictionManager; private final CloseGuard mCloseGuard = CloseGuard.get(); private final AtomicBoolean mIsClosed = new AtomicBoolean(false); private final AppPredictionSessionId mSessionId; + @GuardedBy("itself") private final ArrayMap<Callback, CallbackWrapper> mRegisteredCallbacks = new ArrayMap<>(); private final IBinder mToken = new Binder(); @@ -97,7 +99,7 @@ public final class AppPredictor { IBinder b = ServiceManager.getService(Context.APP_PREDICTION_SERVICE); mPredictionManager = IPredictionManager.Stub.asInterface(b); mSessionId = new AppPredictionSessionId( - context.getPackageName() + ":" + UUID.randomUUID().toString(), context.getUserId()); + context.getPackageName() + ":" + UUID.randomUUID(), context.getUserId()); try { mPredictionManager.createPredictionSession(predictionContext, mSessionId, mToken); } catch (RemoteException e) { @@ -158,6 +160,15 @@ public final class AppPredictor { */ public void registerPredictionUpdates(@NonNull @CallbackExecutor Executor callbackExecutor, @NonNull AppPredictor.Callback callback) { + synchronized (mRegisteredCallbacks) { + registerPredictionUpdatesLocked(callbackExecutor, callback); + } + } + + @GuardedBy("mRegisteredCallbacks") + private void registerPredictionUpdatesLocked( + @NonNull @CallbackExecutor Executor callbackExecutor, + @NonNull AppPredictor.Callback callback) { if (mIsClosed.get()) { throw new IllegalStateException("This client has already been destroyed."); } @@ -186,6 +197,13 @@ public final class AppPredictor { * @param callback The callback to be unregistered. */ public void unregisterPredictionUpdates(@NonNull AppPredictor.Callback callback) { + synchronized (mRegisteredCallbacks) { + unregisterPredictionUpdatesLocked(callback); + } + } + + @GuardedBy("mRegisteredCallbacks") + private void unregisterPredictionUpdatesLocked(@NonNull AppPredictor.Callback callback) { if (mIsClosed.get()) { throw new IllegalStateException("This client has already been destroyed."); } @@ -238,7 +256,7 @@ public final class AppPredictor { } try { - mPredictionManager.sortAppTargets(mSessionId, new ParceledListSlice(targets), + mPredictionManager.sortAppTargets(mSessionId, new ParceledListSlice<>(targets), new CallbackWrapper(callbackExecutor, callback)); } catch (RemoteException e) { Log.e(TAG, "Failed to sort targets", e); @@ -254,19 +272,25 @@ public final class AppPredictor { if (!mIsClosed.getAndSet(true)) { mCloseGuard.close(); - // Do destroy; - try { - mPredictionManager.onDestroyPredictionSession(mSessionId); - } catch (RemoteException e) { - Log.e(TAG, "Failed to notify app target event", e); - e.rethrowAsRuntimeException(); + synchronized (mRegisteredCallbacks) { + destroySessionLocked(); } - mRegisteredCallbacks.clear(); } else { throw new IllegalStateException("This client has already been destroyed."); } } + @GuardedBy("mRegisteredCallbacks") + private void destroySessionLocked() { + try { + mPredictionManager.onDestroyPredictionSession(mSessionId); + } catch (RemoteException e) { + Log.e(TAG, "Failed to notify app target event", e); + e.rethrowAsRuntimeException(); + } + mRegisteredCallbacks.clear(); + } + @Override protected void finalize() throws Throwable { try { |