Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 2d41f532 authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Android (Google) Code Review
Browse files

Merge "Changed createOnDeviceTranslator to be asynchronous with callback." into sc-dev

parents cda17304 50a637b1
Loading
Loading
Loading
Loading
+2 −1
Original line number Diff line number Diff line
@@ -52841,7 +52841,8 @@ package android.view.translation {
    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 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 @NonNull @WorkerThread public java.util.Set<android.view.translation.TranslationCapability> getOnDeviceTranslationCapabilities(int, int);
    method @Nullable public android.app.PendingIntent getOnDeviceTranslationSettingsActivityIntent();
+61 −4
Original line number Diff line number Diff line
@@ -100,10 +100,6 @@ public final class TranslationManager {

    private final ITranslationManager mService;

    @Nullable
    @GuardedBy("mLock")
    private ITranslationDirectManager mDirectServiceBinder;

    @NonNull
    @GuardedBy("mLock")
    private final SparseArray<Translator> mTranslators = new SparseArray<>();
@@ -128,14 +124,75 @@ public final class TranslationManager {
        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.
     *
     * <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
     *                                                     Translator.
     */
    @Deprecated
    @Nullable
    @WorkerThread
    public Translator createOnDeviceTranslator(@NonNull TranslationContext translationContext) {
+40 −0
Original line number Diff line number Diff line
@@ -101,10 +101,18 @@ public class Translator {
    public static final String EXTRA_SESSION_ID = "sessionId";

    static class ServiceBinderReceiver extends IResultReceiver.Stub {
        // TODO: refactor how translator is instantiated after removing deprecated createTranslator.
        private final WeakReference<Translator> mTranslator;
        private final CountDownLatch mLatch = new CountDownLatch(1);
        private int mSessionId;

        private Consumer<Translator> mCallback;

        ServiceBinderReceiver(Translator translator, Consumer<Translator> callback) {
            mTranslator = new WeakReference<>(translator);
            mCallback = callback;
        }

        ServiceBinderReceiver(Translator translator) {
            mTranslator = new WeakReference<>(translator);
        }
@@ -126,6 +134,9 @@ public class Translator {
        public void send(int resultCode, Bundle resultData) {
            if (resultCode == STATUS_SYNC_CALL_FAIL) {
                mLatch.countDown();
                if (mCallback != null) {
                    mCallback.accept(null);
                }
                return;
            }
            mSessionId = resultData.getInt(EXTRA_SESSION_ID);
@@ -146,6 +157,9 @@ public class Translator {
            }
            translator.setServiceBinder(binder);
            mLatch.countDown();
            if (mCallback != null) {
                mCallback.accept(translator);
            }
        }

        // 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.
     *