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

Commit 5d1ebc4f authored by Joanne Chung's avatar Joanne Chung Committed by Android (Google) Code Review
Browse files

Merge "API feedback: TranslationCapability APIs refinement." into sc-dev

parents fc020769 2fcdb2cf
Loading
Loading
Loading
Loading
+4 −2
Original line number Diff line number Diff line
@@ -52836,7 +52836,8 @@ package android.view.translation {
  }
  public final class TranslationManager {
    method public void addOnDeviceTranslationCapabilityUpdateListener(int, int, @NonNull android.app.PendingIntent);
    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 @Deprecated @Nullable @WorkerThread public android.view.translation.Translator createTranslator(@NonNull android.view.translation.TranslationContext);
@@ -52844,7 +52845,8 @@ package android.view.translation {
    method @Nullable public android.app.PendingIntent getOnDeviceTranslationSettingsActivityIntent();
    method @Deprecated @NonNull @WorkerThread public java.util.Set<android.view.translation.TranslationCapability> getTranslationCapabilities(int, int);
    method @Deprecated @Nullable public android.app.PendingIntent getTranslationSettingsActivityIntent();
    method public void removeOnDeviceTranslationCapabilityUpdateListener(int, int, @NonNull android.app.PendingIntent);
    method public void removeOnDeviceTranslationCapabilityUpdateListener(@NonNull java.util.function.Consumer<android.view.translation.TranslationCapability>);
    method @Deprecated public void removeOnDeviceTranslationCapabilityUpdateListener(int, int, @NonNull android.app.PendingIntent);
    method @Deprecated public void removeTranslationCapabilityUpdateListener(int, int, @NonNull android.app.PendingIntent);
  }
+2 −0
Original line number Diff line number Diff line
@@ -34,6 +34,8 @@ import java.util.List;
oneway interface ITranslationManager {
    void onTranslationCapabilitiesRequest(int sourceFormat, int destFormat,
         in ResultReceiver receiver, int userId);
    void registerTranslationCapabilityCallback(in IRemoteCallback callback, int userId);
    void unregisterTranslationCapabilityCallback(in IRemoteCallback callback, int userId);
    void onSessionCreated(in TranslationContext translationContext,
         int sessionId, in IResultReceiver receiver, int userId);

+80 −21
Original line number Diff line number Diff line
@@ -16,6 +16,7 @@

package android.view.translation;

import android.annotation.CallbackExecutor;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.SystemService;
@@ -41,12 +42,14 @@ import com.android.internal.util.SyncResultReceiver;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Map;
import java.util.Objects;
import java.util.Random;
import java.util.Set;
import java.util.concurrent.Executor;
import java.util.concurrent.TimeoutException;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.function.Consumer;

/**
 * The {@link TranslationManager} class provides ways for apps to integrate and use the
@@ -81,11 +84,14 @@ public final class TranslationManager {
     */
    public static final String EXTRA_CAPABILITIES = "translation_capabilities";

    // TODO: implement update listeners and propagate updates.
    @GuardedBy("mLock")
    private final ArrayMap<Pair<Integer, Integer>, ArrayList<PendingIntent>>
            mTranslationCapabilityUpdateListeners = new ArrayMap<>();

    @GuardedBy("mLock")
    private final Map<Consumer<TranslationCapability>, IRemoteCallback> mCapabilityCallbacks =
            new ArrayMap<>();

    private static final Random ID_GENERATOR = new Random();
    private final Object mLock = new Object();

@@ -232,16 +238,42 @@ public final class TranslationManager {
    }

    /**
     * Registers a {@link PendingIntent} to listen for updates on states of on-device
     * Adds a {@link TranslationCapability} Consumer to listen for updates on states of on-device
     * {@link TranslationCapability}s.
     *
     * <p>IMPORTANT: the pending intent must be called to start a service, or a broadcast if it is
     * an explicit intent.</p>
     *
     * @param sourceFormat data format for the input data to be translated.
     * @param targetFormat data format for the expected translated output data.
     * @param pendingIntent the pending intent to invoke when updates are received.
     * @param capabilityListener a {@link TranslationCapability} Consumer to receive the updated
     * {@link TranslationCapability} from the on-device translation service.
     */
    public void addOnDeviceTranslationCapabilityUpdateListener(
            @NonNull @CallbackExecutor Executor executor,
            @NonNull Consumer<TranslationCapability> capabilityListener) {
        Objects.requireNonNull(executor, "executor should not be null");
        Objects.requireNonNull(capabilityListener, "capability listener should not be null");

        synchronized (mLock) {
            if (mCapabilityCallbacks.containsKey(capabilityListener)) {
                Log.w(TAG, "addOnDeviceTranslationCapabilityUpdateListener: the listener for "
                        + capabilityListener + " already registered; ignoring.");
                return;
            }
            final IRemoteCallback remoteCallback = new TranslationCapabilityRemoteCallback(executor,
                    capabilityListener);
            try {
                mService.registerTranslationCapabilityCallback(remoteCallback,
                        mContext.getUserId());
            } catch (RemoteException e) {
                throw e.rethrowFromSystemServer();
            }
            mCapabilityCallbacks.put(capabilityListener, remoteCallback);
        }
    }


    /**
     * @deprecated Use {@link TranslationManager#addOnDeviceTranslationCapabilityUpdateListener(
     * java.util.concurrent.Executor, java.util.function.Consumer)}
     */
    @Deprecated
    public void addOnDeviceTranslationCapabilityUpdateListener(
            @TranslationSpec.DataFormat int sourceFormat,
            @TranslationSpec.DataFormat int targetFormat,
@@ -256,8 +288,8 @@ public final class TranslationManager {
    }

    /**
     * @deprecated Use {@link #addOnDeviceTranslationCapabilityUpdateListener(int, int,
     *  PendingIntent)}
     * @deprecated Use {@link TranslationManager#addOnDeviceTranslationCapabilityUpdateListener(
     * java.util.concurrent.Executor, java.util.function.Consumer)}
     */
    @Deprecated
    public void addTranslationCapabilityUpdateListener(
@@ -268,13 +300,37 @@ public final class TranslationManager {
    }

    /**
     * Unregisters a {@link PendingIntent} to listen for updates on states of on-device
     * {@link TranslationCapability}s.
     * Removes a {@link TranslationCapability} Consumer to listen for updates on states of
     * on-device {@link TranslationCapability}s.
     *
     * @param sourceFormat data format for the input data to be translated.
     * @param targetFormat data format for the expected translated output data.
     * @param pendingIntent the pending intent to unregister
     * @param capabilityListener the {@link TranslationCapability} Consumer to unregister
     */
    public void removeOnDeviceTranslationCapabilityUpdateListener(
            @NonNull Consumer<TranslationCapability> capabilityListener) {
        Objects.requireNonNull(capabilityListener, "capability callback should not be null");

        synchronized (mLock) {
            final IRemoteCallback remoteCallback = mCapabilityCallbacks.get(capabilityListener);
            if (remoteCallback == null) {
                Log.w(TAG, "removeOnDeviceTranslationCapabilityUpdateListener: the capability "
                        + "listener not found; ignoring.");
                return;
            }
            try {
                mService.unregisterTranslationCapabilityCallback(remoteCallback,
                        mContext.getUserId());
            } catch (RemoteException e) {
                throw e.rethrowFromSystemServer();
            }
            mCapabilityCallbacks.remove(capabilityListener);
        }
    }

    /**
     * @deprecated Use {@link #removeOnDeviceTranslationCapabilityUpdateListener(
     * java.util.function.Consumer)}.
     */
    @Deprecated
    public void removeOnDeviceTranslationCapabilityUpdateListener(
            @TranslationSpec.DataFormat int sourceFormat,
            @TranslationSpec.DataFormat int targetFormat,
@@ -300,8 +356,8 @@ public final class TranslationManager {
    }

    /**
     * @deprecated Use {@link #removeOnDeviceTranslationCapabilityUpdateListener(int, int,
     *  PendingIntent)}
     * @deprecated Use {@link #removeOnDeviceTranslationCapabilityUpdateListener(
     * java.util.function.Consumer)}.
     */
    @Deprecated
    public void removeTranslationCapabilityUpdateListener(
@@ -366,9 +422,12 @@ public final class TranslationManager {
    private static class TranslationCapabilityRemoteCallback extends
            IRemoteCallback.Stub {
        private final Executor mExecutor;
        private final Consumer<TranslationCapability> mListener;

        TranslationCapabilityRemoteCallback(Executor executor) {
        TranslationCapabilityRemoteCallback(Executor executor,
                Consumer<TranslationCapability> listener) {
            mExecutor = executor;
            mListener = listener;
        }

        @Override
@@ -378,9 +437,9 @@ public final class TranslationManager {
        }

        private void onTranslationCapabilityUpdate(Bundle bundle) {
            TranslationCapability capability = (TranslationCapability) bundle.getParcelable(
                    EXTRA_CAPABILITIES);
            //TODO: Implement after deciding how capability listeners are implemented.
            TranslationCapability capability =
                    (TranslationCapability) bundle.getParcelable(EXTRA_CAPABILITIES);
            mListener.accept(capability);
        }
    }
}
+22 −0
Original line number Diff line number Diff line
@@ -169,6 +169,28 @@ public final class TranslationManagerService
            }
        }

        @Override
        public void registerTranslationCapabilityCallback(IRemoteCallback callback, int userId) {
            TranslationManagerServiceImpl service;
            synchronized (mLock) {
                service = getServiceForUserLocked(userId);
            }
            if (service != null) {
                service.registerTranslationCapabilityCallback(callback, Binder.getCallingUid());
            }
        }

        @Override
        public void unregisterTranslationCapabilityCallback(IRemoteCallback callback, int userId) {
            TranslationManagerServiceImpl service;
            synchronized (mLock) {
                service = getServiceForUserLocked(userId);
            }
            if (service != null) {
                service.unregisterTranslationCapabilityCallback(callback);
            }
        }

        @Override
        public void onSessionCreated(TranslationContext translationContext,
                int sessionId, IResultReceiver receiver, int userId) throws RemoteException {
+9 −0
Original line number Diff line number Diff line
@@ -142,6 +142,15 @@ final class TranslationManagerServiceImpl extends
        }
    }

    public void registerTranslationCapabilityCallback(IRemoteCallback callback, int sourceUid) {
        mTranslationCapabilityCallbacks.register(callback, sourceUid);
        ensureRemoteServiceLocked();
    }

    public void unregisterTranslationCapabilityCallback(IRemoteCallback callback) {
        mTranslationCapabilityCallbacks.unregister(callback);
    }

    @GuardedBy("mLock")
    void onSessionCreatedLocked(@NonNull TranslationContext translationContext, int sessionId,
            IResultReceiver resultReceiver) {