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

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

Merge "Add APIs that can notify client ui translation state."

parents d4391287 feb36772
Loading
Loading
Loading
Loading
+13 −0
Original line number Diff line number Diff line
@@ -137,6 +137,7 @@ package android {
    field public static final String MANAGE_SOUND_TRIGGER = "android.permission.MANAGE_SOUND_TRIGGER";
    field public static final String MANAGE_SUBSCRIPTION_PLANS = "android.permission.MANAGE_SUBSCRIPTION_PLANS";
    field public static final String MANAGE_TIME_AND_ZONE_DETECTION = "android.permission.MANAGE_TIME_AND_ZONE_DETECTION";
    field public static final String MANAGE_UI_TRANSLATION = "android.permission.MANAGE_UI_TRANSLATION";
    field public static final String MANAGE_USB = "android.permission.MANAGE_USB";
    field public static final String MANAGE_USERS = "android.permission.MANAGE_USERS";
    field public static final String MANAGE_USER_OEM_UNLOCK_STATE = "android.permission.MANAGE_USER_OEM_UNLOCK_STATE";
@@ -1947,6 +1948,7 @@ package android.content {
    field public static final String SYSTEM_UPDATE_SERVICE = "system_update";
    field public static final String TETHERING_SERVICE = "tethering";
    field public static final String TRANSLATION_MANAGER_SERVICE = "transformer";
    field public static final String UI_TRANSLATION_SERVICE = "ui_translation";
    field public static final String VR_SERVICE = "vrmanager";
    field public static final String WIFI_NL80211_SERVICE = "wifinl80211";
    field @Deprecated public static final String WIFI_RTT_SERVICE = "rttmanager";
@@ -13437,6 +13439,17 @@ package android.view.contentcapture {
}
package android.view.translation {
  public final class UiTranslationManager {
    method @RequiresPermission(android.Manifest.permission.MANAGE_UI_TRANSLATION) public void finishTranslation(int);
    method @RequiresPermission(android.Manifest.permission.MANAGE_UI_TRANSLATION) public void pauseTranslation(int);
    method @RequiresPermission(android.Manifest.permission.MANAGE_UI_TRANSLATION) public void resumeTranslation(int);
    method @RequiresPermission(android.Manifest.permission.MANAGE_UI_TRANSLATION) public void startTranslation(@NonNull android.view.translation.TranslationSpec, @NonNull android.view.translation.TranslationSpec, @NonNull java.util.List<android.view.autofill.AutofillId>, int);
  }
}
package android.webkit {
  public abstract class CookieManager {
+14 −0
Original line number Diff line number Diff line
@@ -210,6 +210,7 @@ import android.view.textclassifier.TextClassificationManager;
import android.view.textservice.TextServicesManager;
import android.view.translation.ITranslationManager;
import android.view.translation.TranslationManager;
import android.view.translation.UiTranslationManager;

import com.android.internal.app.IAppOpsService;
import com.android.internal.app.IBatteryStats;
@@ -1187,6 +1188,19 @@ public final class SystemServiceRegistry {
                        return null;
                    }});

        registerService(Context.UI_TRANSLATION_SERVICE, UiTranslationManager.class,
                new CachedServiceFetcher<UiTranslationManager>() {
                    @Override
                    public UiTranslationManager createService(ContextImpl ctx)
                            throws ServiceNotFoundException {
                        IBinder b = ServiceManager.getService(Context.TRANSLATION_MANAGER_SERVICE);
                        ITranslationManager service = ITranslationManager.Stub.asInterface(b);
                        if (service != null) {
                            return new UiTranslationManager(ctx.getOuterContext(), service);
                        }
                        return null;
                    }});

        registerService(Context.SEARCH_UI_SERVICE, SearchUiManager.class,
            new CachedServiceFetcher<SearchUiManager>() {
                @Override
+9 −0
Original line number Diff line number Diff line
@@ -4519,6 +4519,15 @@ public abstract class Context {
    @SuppressLint("ServiceName")
    public static final String TRANSLATION_MANAGER_SERVICE = "transformer";

    /**
     * Official published name of the translation service which supports ui translation function.
     *
     * @hide
     * @see #getSystemService(String)
     */
    @SystemApi
    public static final String UI_TRANSLATION_SERVICE = "ui_translation";

    /**
     * Used for getting content selections and classifications for task snapshots.
     *
+9 −0
Original line number Diff line number Diff line
@@ -16,10 +16,15 @@

package android.view.translation;

import android.content.ComponentName;
import android.os.IBinder;
import android.service.translation.TranslationRequest;
import android.view.autofill.AutofillId;
import android.view.translation.TranslationSpec;
import com.android.internal.os.IResultReceiver;

import java.util.List;

/**
 * Mediator between apps being translated and translation service implementation.
 *
@@ -29,4 +34,8 @@ oneway interface ITranslationManager {
    void getSupportedLocales(in IResultReceiver receiver, int userId);
    void onSessionCreated(in TranslationSpec sourceSpec, in TranslationSpec destSpec,
         int sessionId, in IResultReceiver receiver, int userId);

    void updateUiTranslationState(int state, in TranslationSpec sourceSpec,
         in TranslationSpec destSpec, in List<AutofillId> viewIds, in int taskId,
         int userId);
}
+179 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2020 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package android.view.translation;

import android.annotation.IntDef;
import android.annotation.NonNull;
import android.annotation.RequiresPermission;
import android.annotation.SystemApi;
import android.content.Context;
import android.os.RemoteException;
import android.view.View;
import android.view.autofill.AutofillId;

import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.util.List;
import java.util.Objects;

/**
 * The {@link UiTranslationManager} class provides ways for apps to use the ui translation
 * function in framework.
 *
 * @hide
 */
@SystemApi
public final class UiTranslationManager {

    private static final String TAG = "UiTranslationManager";

    /**
     * The state caller request to disable utranslation,, it is no longer need to ui translation.
     *
     * @hide
     */
    public static final int STATE_UI_TRANSLATION_STARTED = 0;
    /**
     * The state caller request to pause ui translation, it will switch back to the original text.
     *
     * @hide
     */
    public static final int STATE_UI_TRANSLATION_PAUSED = 1;
    /**
     * The state caller request to resume the paused ui translation, it will show the translated
     * text again if the text had been translated.
     *
     * @hide
     */
    public static final int STATE_UI_TRANSLATION_RESUMED = 2;
    /**
     * The state the caller request to enable ui translation.
     *
     * @hide
     */
    public static final int STATE_UI_TRANSLATION_FINISHED = 3;
    /**
     * @hide
     */
    @IntDef(prefix = {"STATE__TRANSLATION"}, value = {
            STATE_UI_TRANSLATION_STARTED,
            STATE_UI_TRANSLATION_PAUSED,
            STATE_UI_TRANSLATION_RESUMED,
            STATE_UI_TRANSLATION_FINISHED
    })
    @Retention(RetentionPolicy.SOURCE)
    public @interface UiTranslationState {
    }

    @NonNull
    private final Context mContext;

    private final ITranslationManager mService;

    /**
     * @hide
     */
    public UiTranslationManager(@NonNull Context context, ITranslationManager service) {
        mContext = Objects.requireNonNull(context);
        mService = service;
    }

    /**
     * Request ui translation for a given Views.
     *
     * @param sourceSpec {@link TranslationSpec} for the data to be translated.
     * @param destSpec {@link TranslationSpec} for the translated data.
     * @param viewIds A list of the {@link View}'s {@link AutofillId} which needs to be translated
     * @param taskId the Activity Task id which needs ui translation
     */
    @RequiresPermission(android.Manifest.permission.MANAGE_UI_TRANSLATION)
    public void startTranslation(@NonNull TranslationSpec sourceSpec,
            @NonNull TranslationSpec destSpec, @NonNull List<AutofillId> viewIds,
            int taskId) {
        // TODO(b/177789967): Return result code or find a way to notify the status.
        // TODO(b/177394471): The is a temparary API, the expected is requestUiTranslation(
        //  TranslationSpec, TranslationSpec,List<AutofillId>, Binder). We may need more time to
        //  implement it, use task id as initial version for demo.
        Objects.requireNonNull(sourceSpec);
        Objects.requireNonNull(destSpec);
        Objects.requireNonNull(viewIds);

        try {
            mService.updateUiTranslationState(STATE_UI_TRANSLATION_STARTED, sourceSpec,
                    destSpec, viewIds, taskId, mContext.getUserId());
        } catch (RemoteException e) {
            throw e.rethrowFromSystemServer();
        }
    }

    /**
     * Request to disable the ui translation. It will destroy all the {@link Translator}s and no
     * longer to show to show the translated text.
     *
     * @param taskId the Activity Task id which needs ui translation
     */
    @RequiresPermission(android.Manifest.permission.MANAGE_UI_TRANSLATION)
    public void finishTranslation(int taskId) {
        try {
            // TODO(b/177394471): The is a temparary API, the expected is finishUiTranslation(
            //  Binder). We may need more time to implement it, use task id as initial version.
            mService.updateUiTranslationState(STATE_UI_TRANSLATION_FINISHED,
                    null /* sourceSpec */, null /* destSpec*/, null /* viewIds */, taskId,
                    mContext.getUserId());
        } catch (RemoteException e) {
            throw e.rethrowFromSystemServer();
        }
    }

    /**
     * Request to pause the current ui translation's {@link Translator} which will switch back to
     * the original language.
     *
     * @param taskId the Activity Task id which needs ui translation
     */
    @RequiresPermission(android.Manifest.permission.MANAGE_UI_TRANSLATION)
    public void pauseTranslation(int taskId) {
        try {
            // TODO(b/177394471): The is a temparary API, the expected is pauseUiTranslation(Binder)
            // We may need more time to implement it, use task id as initial version for demo
            mService.updateUiTranslationState(STATE_UI_TRANSLATION_PAUSED,
                    null /* sourceSpec */, null /* destSpec*/, null /* viewIds */, taskId,
                    mContext.getUserId());
        } catch (RemoteException e) {
            throw e.rethrowFromSystemServer();
        }
    }

    /**
     * Request to resume the paused ui translation's {@link Translator} which will switch to the
     * translated language if the text had been translated.
     *
     * @param taskId the Activity Task id which needs ui translation
     */
    @RequiresPermission(android.Manifest.permission.MANAGE_UI_TRANSLATION)
    public void resumeTranslation(int taskId) {
        try {
            // TODO(b/177394471): The is a temparary API, the expected is resumeUiTranslation(
            //  Binder). We may need more time to implement it, use task id as initial version.
            mService.updateUiTranslationState(STATE_UI_TRANSLATION_RESUMED,
                    null /* sourceSpec */, null /* destSpec*/, null /* viewIds */,
                    taskId, mContext.getUserId());
        } catch (RemoteException e) {
            throw e.rethrowFromSystemServer();
        }
    }
}
Loading