Changed createOnDeviceTranslator to be asynchronous with callback.
Bug: 176208267 Test: atest CtsTranslationTestCases Change-Id: Icedc953611e70dc208cbef54b4e459ebb0ccd5a9
This commit is contained in:
@@ -52839,7 +52839,8 @@ package android.view.translation {
|
|||||||
method public void addOnDeviceTranslationCapabilityUpdateListener(@NonNull java.util.concurrent.Executor, @NonNull java.util.function.Consumer<android.view.translation.TranslationCapability>);
|
method public void addOnDeviceTranslationCapabilityUpdateListener(@NonNull java.util.concurrent.Executor, @NonNull java.util.function.Consumer<android.view.translation.TranslationCapability>);
|
||||||
method @Deprecated public void addOnDeviceTranslationCapabilityUpdateListener(int, int, @NonNull android.app.PendingIntent);
|
method @Deprecated public void addOnDeviceTranslationCapabilityUpdateListener(int, int, @NonNull android.app.PendingIntent);
|
||||||
method @Deprecated public void addTranslationCapabilityUpdateListener(int, int, @NonNull android.app.PendingIntent);
|
method @Deprecated public void addTranslationCapabilityUpdateListener(int, int, @NonNull android.app.PendingIntent);
|
||||||
method @Nullable @WorkerThread public android.view.translation.Translator createOnDeviceTranslator(@NonNull android.view.translation.TranslationContext);
|
method public void createOnDeviceTranslator(@NonNull android.view.translation.TranslationContext, @NonNull java.util.concurrent.Executor, @NonNull java.util.function.Consumer<android.view.translation.Translator>);
|
||||||
|
method @Deprecated @Nullable @WorkerThread public android.view.translation.Translator createOnDeviceTranslator(@NonNull android.view.translation.TranslationContext);
|
||||||
method @Deprecated @Nullable @WorkerThread public android.view.translation.Translator createTranslator(@NonNull android.view.translation.TranslationContext);
|
method @Deprecated @Nullable @WorkerThread public android.view.translation.Translator createTranslator(@NonNull android.view.translation.TranslationContext);
|
||||||
method @NonNull @WorkerThread public java.util.Set<android.view.translation.TranslationCapability> getOnDeviceTranslationCapabilities(int, int);
|
method @NonNull @WorkerThread public java.util.Set<android.view.translation.TranslationCapability> getOnDeviceTranslationCapabilities(int, int);
|
||||||
method @Nullable public android.app.PendingIntent getOnDeviceTranslationSettingsActivityIntent();
|
method @Nullable public android.app.PendingIntent getOnDeviceTranslationSettingsActivityIntent();
|
||||||
|
|||||||
@@ -100,10 +100,6 @@ public final class TranslationManager {
|
|||||||
|
|
||||||
private final ITranslationManager mService;
|
private final ITranslationManager mService;
|
||||||
|
|
||||||
@Nullable
|
|
||||||
@GuardedBy("mLock")
|
|
||||||
private ITranslationDirectManager mDirectServiceBinder;
|
|
||||||
|
|
||||||
@NonNull
|
@NonNull
|
||||||
@GuardedBy("mLock")
|
@GuardedBy("mLock")
|
||||||
private final SparseArray<Translator> mTranslators = new SparseArray<>();
|
private final SparseArray<Translator> mTranslators = new SparseArray<>();
|
||||||
@@ -128,14 +124,75 @@ public final class TranslationManager {
|
|||||||
mHandler = Handler.createAsync(Looper.getMainLooper());
|
mHandler = Handler.createAsync(Looper.getMainLooper());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates an on-device Translator for natural language translation.
|
||||||
|
*
|
||||||
|
* @param translationContext {@link TranslationContext} containing the specs for creating the
|
||||||
|
* Translator.
|
||||||
|
* @param executor Executor to run callback operations
|
||||||
|
* @param callback {@link Consumer} to receive the translator. A {@code null} value is returned
|
||||||
|
* if the service could not create the translator.
|
||||||
|
*/
|
||||||
|
public void createOnDeviceTranslator(@NonNull TranslationContext translationContext,
|
||||||
|
@NonNull @CallbackExecutor Executor executor, @NonNull Consumer<Translator> callback) {
|
||||||
|
Objects.requireNonNull(translationContext, "translationContext cannot be null");
|
||||||
|
Objects.requireNonNull(executor, "executor cannot be null");
|
||||||
|
Objects.requireNonNull(callback, "callback cannot be null");
|
||||||
|
|
||||||
|
synchronized (mLock) {
|
||||||
|
// TODO(b/176464808): Disallow multiple Translator now, it will throw
|
||||||
|
// IllegalStateException. Need to discuss if we can allow multiple Translators.
|
||||||
|
if (mTranslatorIds.containsKey(translationContext)) {
|
||||||
|
executor.execute(() -> callback.accept(
|
||||||
|
mTranslators.get(mTranslatorIds.get(translationContext))));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
int translatorId;
|
||||||
|
do {
|
||||||
|
translatorId = Math.abs(ID_GENERATOR.nextInt());
|
||||||
|
} while (translatorId == 0 || mTranslators.indexOfKey(translatorId) >= 0);
|
||||||
|
final int tId = translatorId;
|
||||||
|
|
||||||
|
new Translator(mContext, translationContext, translatorId, this, mHandler, mService,
|
||||||
|
new Consumer<Translator>() {
|
||||||
|
@Override
|
||||||
|
public void accept(Translator translator) {
|
||||||
|
if (translator == null) {
|
||||||
|
final long token = Binder.clearCallingIdentity();
|
||||||
|
try {
|
||||||
|
executor.execute(() -> callback.accept(null));
|
||||||
|
} finally {
|
||||||
|
Binder.restoreCallingIdentity(token);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
mTranslators.put(tId, translator);
|
||||||
|
mTranslatorIds.put(translationContext, tId);
|
||||||
|
final long token = Binder.clearCallingIdentity();
|
||||||
|
try {
|
||||||
|
executor.execute(() -> callback.accept(translator));
|
||||||
|
} finally {
|
||||||
|
Binder.restoreCallingIdentity(token);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates an on-device Translator for natural language translation.
|
* Creates an on-device Translator for natural language translation.
|
||||||
*
|
*
|
||||||
* <p><strong>NOTE: </strong>Call on a worker thread.
|
* <p><strong>NOTE: </strong>Call on a worker thread.
|
||||||
*
|
*
|
||||||
|
* @deprecated use {@link #createOnDeviceTranslator(TranslationContext, Executor, Consumer)}
|
||||||
|
* instead.
|
||||||
|
*
|
||||||
* @param translationContext {@link TranslationContext} containing the specs for creating the
|
* @param translationContext {@link TranslationContext} containing the specs for creating the
|
||||||
* Translator.
|
* Translator.
|
||||||
*/
|
*/
|
||||||
|
@Deprecated
|
||||||
@Nullable
|
@Nullable
|
||||||
@WorkerThread
|
@WorkerThread
|
||||||
public Translator createOnDeviceTranslator(@NonNull TranslationContext translationContext) {
|
public Translator createOnDeviceTranslator(@NonNull TranslationContext translationContext) {
|
||||||
|
|||||||
@@ -101,10 +101,18 @@ public class Translator {
|
|||||||
public static final String EXTRA_SESSION_ID = "sessionId";
|
public static final String EXTRA_SESSION_ID = "sessionId";
|
||||||
|
|
||||||
static class ServiceBinderReceiver extends IResultReceiver.Stub {
|
static class ServiceBinderReceiver extends IResultReceiver.Stub {
|
||||||
|
// TODO: refactor how translator is instantiated after removing deprecated createTranslator.
|
||||||
private final WeakReference<Translator> mTranslator;
|
private final WeakReference<Translator> mTranslator;
|
||||||
private final CountDownLatch mLatch = new CountDownLatch(1);
|
private final CountDownLatch mLatch = new CountDownLatch(1);
|
||||||
private int mSessionId;
|
private int mSessionId;
|
||||||
|
|
||||||
|
private Consumer<Translator> mCallback;
|
||||||
|
|
||||||
|
ServiceBinderReceiver(Translator translator, Consumer<Translator> callback) {
|
||||||
|
mTranslator = new WeakReference<>(translator);
|
||||||
|
mCallback = callback;
|
||||||
|
}
|
||||||
|
|
||||||
ServiceBinderReceiver(Translator translator) {
|
ServiceBinderReceiver(Translator translator) {
|
||||||
mTranslator = new WeakReference<>(translator);
|
mTranslator = new WeakReference<>(translator);
|
||||||
}
|
}
|
||||||
@@ -126,6 +134,9 @@ public class Translator {
|
|||||||
public void send(int resultCode, Bundle resultData) {
|
public void send(int resultCode, Bundle resultData) {
|
||||||
if (resultCode == STATUS_SYNC_CALL_FAIL) {
|
if (resultCode == STATUS_SYNC_CALL_FAIL) {
|
||||||
mLatch.countDown();
|
mLatch.countDown();
|
||||||
|
if (mCallback != null) {
|
||||||
|
mCallback.accept(null);
|
||||||
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
mSessionId = resultData.getInt(EXTRA_SESSION_ID);
|
mSessionId = resultData.getInt(EXTRA_SESSION_ID);
|
||||||
@@ -146,6 +157,9 @@ public class Translator {
|
|||||||
}
|
}
|
||||||
translator.setServiceBinder(binder);
|
translator.setServiceBinder(binder);
|
||||||
mLatch.countDown();
|
mLatch.countDown();
|
||||||
|
if (mCallback != null) {
|
||||||
|
mCallback.accept(translator);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO(b/176464808): maybe make SyncResultReceiver.TimeoutException constructor public
|
// TODO(b/176464808): maybe make SyncResultReceiver.TimeoutException constructor public
|
||||||
@@ -157,6 +171,32 @@ public class Translator {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create the Translator.
|
||||||
|
*
|
||||||
|
* @hide
|
||||||
|
*/
|
||||||
|
public Translator(@NonNull Context context,
|
||||||
|
@NonNull TranslationContext translationContext, int sessionId,
|
||||||
|
@NonNull TranslationManager translationManager, @NonNull Handler handler,
|
||||||
|
@Nullable ITranslationManager systemServerBinder,
|
||||||
|
@NonNull Consumer<Translator> callback) {
|
||||||
|
mContext = context;
|
||||||
|
mTranslationContext = translationContext;
|
||||||
|
mId = sessionId;
|
||||||
|
mManager = translationManager;
|
||||||
|
mHandler = handler;
|
||||||
|
mSystemServerBinder = systemServerBinder;
|
||||||
|
mServiceBinderReceiver = new ServiceBinderReceiver(this, callback);
|
||||||
|
|
||||||
|
try {
|
||||||
|
mSystemServerBinder.onSessionCreated(mTranslationContext, mId,
|
||||||
|
mServiceBinderReceiver, mContext.getUserId());
|
||||||
|
} catch (RemoteException e) {
|
||||||
|
Log.w(TAG, "RemoteException calling startSession(): " + e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create the Translator.
|
* Create the Translator.
|
||||||
*
|
*
|
||||||
|
|||||||
Reference in New Issue
Block a user