Merge "Make AppPredictor thread-safe" into tm-qpr-dev
This commit is contained in:
@@ -30,6 +30,8 @@ import android.os.ServiceManager;
|
|||||||
import android.util.ArrayMap;
|
import android.util.ArrayMap;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
|
|
||||||
|
import com.android.internal.annotations.GuardedBy;
|
||||||
|
|
||||||
import dalvik.system.CloseGuard;
|
import dalvik.system.CloseGuard;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@@ -74,12 +76,12 @@ public final class AppPredictor {
|
|||||||
|
|
||||||
private static final String TAG = AppPredictor.class.getSimpleName();
|
private static final String TAG = AppPredictor.class.getSimpleName();
|
||||||
|
|
||||||
|
|
||||||
private final IPredictionManager mPredictionManager;
|
private final IPredictionManager mPredictionManager;
|
||||||
private final CloseGuard mCloseGuard = CloseGuard.get();
|
private final CloseGuard mCloseGuard = CloseGuard.get();
|
||||||
private final AtomicBoolean mIsClosed = new AtomicBoolean(false);
|
private final AtomicBoolean mIsClosed = new AtomicBoolean(false);
|
||||||
|
|
||||||
private final AppPredictionSessionId mSessionId;
|
private final AppPredictionSessionId mSessionId;
|
||||||
|
@GuardedBy("itself")
|
||||||
private final ArrayMap<Callback, CallbackWrapper> mRegisteredCallbacks = new ArrayMap<>();
|
private final ArrayMap<Callback, CallbackWrapper> mRegisteredCallbacks = new ArrayMap<>();
|
||||||
|
|
||||||
private final IBinder mToken = new Binder();
|
private final IBinder mToken = new Binder();
|
||||||
@@ -97,7 +99,7 @@ public final class AppPredictor {
|
|||||||
IBinder b = ServiceManager.getService(Context.APP_PREDICTION_SERVICE);
|
IBinder b = ServiceManager.getService(Context.APP_PREDICTION_SERVICE);
|
||||||
mPredictionManager = IPredictionManager.Stub.asInterface(b);
|
mPredictionManager = IPredictionManager.Stub.asInterface(b);
|
||||||
mSessionId = new AppPredictionSessionId(
|
mSessionId = new AppPredictionSessionId(
|
||||||
context.getPackageName() + ":" + UUID.randomUUID().toString(), context.getUserId());
|
context.getPackageName() + ":" + UUID.randomUUID(), context.getUserId());
|
||||||
try {
|
try {
|
||||||
mPredictionManager.createPredictionSession(predictionContext, mSessionId, mToken);
|
mPredictionManager.createPredictionSession(predictionContext, mSessionId, mToken);
|
||||||
} catch (RemoteException e) {
|
} catch (RemoteException e) {
|
||||||
@@ -158,6 +160,15 @@ public final class AppPredictor {
|
|||||||
*/
|
*/
|
||||||
public void registerPredictionUpdates(@NonNull @CallbackExecutor Executor callbackExecutor,
|
public void registerPredictionUpdates(@NonNull @CallbackExecutor Executor callbackExecutor,
|
||||||
@NonNull AppPredictor.Callback callback) {
|
@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()) {
|
if (mIsClosed.get()) {
|
||||||
throw new IllegalStateException("This client has already been destroyed.");
|
throw new IllegalStateException("This client has already been destroyed.");
|
||||||
}
|
}
|
||||||
@@ -186,6 +197,13 @@ public final class AppPredictor {
|
|||||||
* @param callback The callback to be unregistered.
|
* @param callback The callback to be unregistered.
|
||||||
*/
|
*/
|
||||||
public void unregisterPredictionUpdates(@NonNull AppPredictor.Callback callback) {
|
public void unregisterPredictionUpdates(@NonNull AppPredictor.Callback callback) {
|
||||||
|
synchronized (mRegisteredCallbacks) {
|
||||||
|
unregisterPredictionUpdatesLocked(callback);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@GuardedBy("mRegisteredCallbacks")
|
||||||
|
private void unregisterPredictionUpdatesLocked(@NonNull AppPredictor.Callback callback) {
|
||||||
if (mIsClosed.get()) {
|
if (mIsClosed.get()) {
|
||||||
throw new IllegalStateException("This client has already been destroyed.");
|
throw new IllegalStateException("This client has already been destroyed.");
|
||||||
}
|
}
|
||||||
@@ -238,7 +256,7 @@ public final class AppPredictor {
|
|||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
mPredictionManager.sortAppTargets(mSessionId, new ParceledListSlice(targets),
|
mPredictionManager.sortAppTargets(mSessionId, new ParceledListSlice<>(targets),
|
||||||
new CallbackWrapper(callbackExecutor, callback));
|
new CallbackWrapper(callbackExecutor, callback));
|
||||||
} catch (RemoteException e) {
|
} catch (RemoteException e) {
|
||||||
Log.e(TAG, "Failed to sort targets", e);
|
Log.e(TAG, "Failed to sort targets", e);
|
||||||
@@ -254,7 +272,16 @@ public final class AppPredictor {
|
|||||||
if (!mIsClosed.getAndSet(true)) {
|
if (!mIsClosed.getAndSet(true)) {
|
||||||
mCloseGuard.close();
|
mCloseGuard.close();
|
||||||
|
|
||||||
// Do destroy;
|
synchronized (mRegisteredCallbacks) {
|
||||||
|
destroySessionLocked();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
throw new IllegalStateException("This client has already been destroyed.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@GuardedBy("mRegisteredCallbacks")
|
||||||
|
private void destroySessionLocked() {
|
||||||
try {
|
try {
|
||||||
mPredictionManager.onDestroyPredictionSession(mSessionId);
|
mPredictionManager.onDestroyPredictionSession(mSessionId);
|
||||||
} catch (RemoteException e) {
|
} catch (RemoteException e) {
|
||||||
@@ -262,9 +289,6 @@ public final class AppPredictor {
|
|||||||
e.rethrowAsRuntimeException();
|
e.rethrowAsRuntimeException();
|
||||||
}
|
}
|
||||||
mRegisteredCallbacks.clear();
|
mRegisteredCallbacks.clear();
|
||||||
} else {
|
|
||||||
throw new IllegalStateException("This client has already been destroyed.");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
Reference in New Issue
Block a user