Loading core/api/current.txt +1 −0 Original line number Diff line number Diff line Loading @@ -52570,6 +52570,7 @@ package android.view.translation { method public void addTranslationCapabilityUpdateListener(int, int, @NonNull android.app.PendingIntent); method @Nullable @WorkerThread public android.view.translation.Translator createTranslator(@NonNull android.view.translation.TranslationContext); method @NonNull @WorkerThread public java.util.Set<android.view.translation.TranslationCapability> getTranslationCapabilities(int, int); method @Nullable public android.app.PendingIntent getTranslationSettingsActivityIntent(); method public void removeTranslationCapabilityUpdateListener(int, int, @NonNull android.app.PendingIntent); } core/java/android/service/translation/TranslationServiceInfo.java +2 −2 Original line number Diff line number Diff line Loading @@ -100,9 +100,9 @@ public final class TranslationServiceInfo { if (!Manifest.permission.BIND_TRANSLATION_SERVICE.equals(si.permission)) { Slog.w(TAG, "TranslationServiceInfo from '" + si.packageName + "' does not require permission " + Manifest.permission.BIND_CONTENT_CAPTURE_SERVICE); + Manifest.permission.BIND_TRANSLATION_SERVICE); throw new SecurityException("Service does not require permission " + Manifest.permission.BIND_CONTENT_CAPTURE_SERVICE); + Manifest.permission.BIND_TRANSLATION_SERVICE); } mServiceInfo = si; Loading core/java/android/view/translation/ITranslationManager.aidl +1 −0 Original line number Diff line number Diff line Loading @@ -46,4 +46,5 @@ oneway interface ITranslationManager { void registerUiTranslationStateCallback(in IRemoteCallback callback, int userId); void unregisterUiTranslationStateCallback(in IRemoteCallback callback, int userId); void getServiceSettingsActivity(in IResultReceiver result, int userId); } core/java/android/view/translation/TranslationManager.java +26 −0 Original line number Diff line number Diff line Loading @@ -35,6 +35,7 @@ import android.util.Pair; import android.util.SparseArray; import com.android.internal.annotations.GuardedBy; import com.android.internal.util.SyncResultReceiver; import java.util.ArrayList; import java.util.Collections; Loading Loading @@ -263,6 +264,31 @@ public final class TranslationManager { //TODO: Add method to propagate updates to mTCapabilityUpdateListeners /** * Returns an immutable PendingIntent which can used by apps to launch translation settings. * * @return An immutable PendingIntent or {@code null} if one of reason met: * <ul> * <li>Device manufacturer (OEM) does not provide TranslationService.</li> * <li>The TranslationService doesn't provide the Settings.</li> * </ul> **/ @Nullable public PendingIntent getTranslationSettingsActivityIntent() { final SyncResultReceiver resultReceiver = new SyncResultReceiver(SYNC_CALLS_TIMEOUT_MS); try { mService.getServiceSettingsActivity(resultReceiver, mContext.getUserId()); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } try { return resultReceiver.getParcelableResult(); } catch (SyncResultReceiver.TimeoutException e) { Log.e(TAG, "Fail to get translation service settings activity."); return null; } } void removeTranslator(int id) { synchronized (mLock) { mTranslators.remove(id); Loading services/translation/java/com/android/server/translation/TranslationManagerService.java +47 −0 Original line number Diff line number Diff line Loading @@ -17,13 +17,19 @@ package com.android.server.translation; import static android.Manifest.permission.MANAGE_UI_TRANSLATION; import static android.app.PendingIntent.FLAG_IMMUTABLE; import static android.content.Context.TRANSLATION_MANAGER_SERVICE; import static android.view.translation.TranslationManager.STATUS_SYNC_CALL_FAIL; import static android.view.translation.TranslationManager.STATUS_SYNC_CALL_SUCCESS; import static com.android.internal.util.SyncResultReceiver.bundleFor; import android.annotation.NonNull; import android.annotation.Nullable; import android.app.PendingIntent; import android.content.ComponentName; import android.content.Context; import android.content.Intent; import android.content.pm.PackageManager; import android.os.Binder; import android.os.IBinder; Loading @@ -31,6 +37,7 @@ import android.os.IRemoteCallback; import android.os.RemoteException; import android.os.ResultReceiver; import android.os.ShellCallback; import android.os.UserHandle; import android.util.Slog; import android.view.autofill.AutofillId; import android.view.translation.ITranslationManager; Loading Loading @@ -231,6 +238,46 @@ public final class TranslationManagerService } } @Override public void getServiceSettingsActivity(IResultReceiver result, int userId) { final TranslationManagerServiceImpl service; synchronized (mLock) { service = getServiceForUserLocked(userId); } if (service != null) { final ComponentName componentName = service.getServiceSettingsActivityLocked(); if (componentName == null) { try { result.send(STATUS_SYNC_CALL_SUCCESS, null); } catch (RemoteException e) { Slog.w(TAG, "Unable to send getServiceSettingsActivity(): " + e); } } final Intent intent = new Intent(); intent.setComponent(componentName); final long identity = Binder.clearCallingIdentity(); try { final PendingIntent pendingIntent = PendingIntent.getActivityAsUser(getContext(), 0, intent, FLAG_IMMUTABLE, null, new UserHandle(userId)); try { result.send(STATUS_SYNC_CALL_SUCCESS, bundleFor(pendingIntent)); } catch (RemoteException e) { Slog.w(TAG, "Unable to send getServiceSettingsActivity(): " + e); } } finally { Binder.restoreCallingIdentity(identity); } } else { try { result.send(STATUS_SYNC_CALL_FAIL, null); } catch (RemoteException e) { Slog.w(TAG, "Unable to send getServiceSettingsActivity(): " + e); } } } /** * Dump the service state into the given stream. You run "adb shell dumpsys translation". */ Loading Loading
core/api/current.txt +1 −0 Original line number Diff line number Diff line Loading @@ -52570,6 +52570,7 @@ package android.view.translation { method public void addTranslationCapabilityUpdateListener(int, int, @NonNull android.app.PendingIntent); method @Nullable @WorkerThread public android.view.translation.Translator createTranslator(@NonNull android.view.translation.TranslationContext); method @NonNull @WorkerThread public java.util.Set<android.view.translation.TranslationCapability> getTranslationCapabilities(int, int); method @Nullable public android.app.PendingIntent getTranslationSettingsActivityIntent(); method public void removeTranslationCapabilityUpdateListener(int, int, @NonNull android.app.PendingIntent); }
core/java/android/service/translation/TranslationServiceInfo.java +2 −2 Original line number Diff line number Diff line Loading @@ -100,9 +100,9 @@ public final class TranslationServiceInfo { if (!Manifest.permission.BIND_TRANSLATION_SERVICE.equals(si.permission)) { Slog.w(TAG, "TranslationServiceInfo from '" + si.packageName + "' does not require permission " + Manifest.permission.BIND_CONTENT_CAPTURE_SERVICE); + Manifest.permission.BIND_TRANSLATION_SERVICE); throw new SecurityException("Service does not require permission " + Manifest.permission.BIND_CONTENT_CAPTURE_SERVICE); + Manifest.permission.BIND_TRANSLATION_SERVICE); } mServiceInfo = si; Loading
core/java/android/view/translation/ITranslationManager.aidl +1 −0 Original line number Diff line number Diff line Loading @@ -46,4 +46,5 @@ oneway interface ITranslationManager { void registerUiTranslationStateCallback(in IRemoteCallback callback, int userId); void unregisterUiTranslationStateCallback(in IRemoteCallback callback, int userId); void getServiceSettingsActivity(in IResultReceiver result, int userId); }
core/java/android/view/translation/TranslationManager.java +26 −0 Original line number Diff line number Diff line Loading @@ -35,6 +35,7 @@ import android.util.Pair; import android.util.SparseArray; import com.android.internal.annotations.GuardedBy; import com.android.internal.util.SyncResultReceiver; import java.util.ArrayList; import java.util.Collections; Loading Loading @@ -263,6 +264,31 @@ public final class TranslationManager { //TODO: Add method to propagate updates to mTCapabilityUpdateListeners /** * Returns an immutable PendingIntent which can used by apps to launch translation settings. * * @return An immutable PendingIntent or {@code null} if one of reason met: * <ul> * <li>Device manufacturer (OEM) does not provide TranslationService.</li> * <li>The TranslationService doesn't provide the Settings.</li> * </ul> **/ @Nullable public PendingIntent getTranslationSettingsActivityIntent() { final SyncResultReceiver resultReceiver = new SyncResultReceiver(SYNC_CALLS_TIMEOUT_MS); try { mService.getServiceSettingsActivity(resultReceiver, mContext.getUserId()); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } try { return resultReceiver.getParcelableResult(); } catch (SyncResultReceiver.TimeoutException e) { Log.e(TAG, "Fail to get translation service settings activity."); return null; } } void removeTranslator(int id) { synchronized (mLock) { mTranslators.remove(id); Loading
services/translation/java/com/android/server/translation/TranslationManagerService.java +47 −0 Original line number Diff line number Diff line Loading @@ -17,13 +17,19 @@ package com.android.server.translation; import static android.Manifest.permission.MANAGE_UI_TRANSLATION; import static android.app.PendingIntent.FLAG_IMMUTABLE; import static android.content.Context.TRANSLATION_MANAGER_SERVICE; import static android.view.translation.TranslationManager.STATUS_SYNC_CALL_FAIL; import static android.view.translation.TranslationManager.STATUS_SYNC_CALL_SUCCESS; import static com.android.internal.util.SyncResultReceiver.bundleFor; import android.annotation.NonNull; import android.annotation.Nullable; import android.app.PendingIntent; import android.content.ComponentName; import android.content.Context; import android.content.Intent; import android.content.pm.PackageManager; import android.os.Binder; import android.os.IBinder; Loading @@ -31,6 +37,7 @@ import android.os.IRemoteCallback; import android.os.RemoteException; import android.os.ResultReceiver; import android.os.ShellCallback; import android.os.UserHandle; import android.util.Slog; import android.view.autofill.AutofillId; import android.view.translation.ITranslationManager; Loading Loading @@ -231,6 +238,46 @@ public final class TranslationManagerService } } @Override public void getServiceSettingsActivity(IResultReceiver result, int userId) { final TranslationManagerServiceImpl service; synchronized (mLock) { service = getServiceForUserLocked(userId); } if (service != null) { final ComponentName componentName = service.getServiceSettingsActivityLocked(); if (componentName == null) { try { result.send(STATUS_SYNC_CALL_SUCCESS, null); } catch (RemoteException e) { Slog.w(TAG, "Unable to send getServiceSettingsActivity(): " + e); } } final Intent intent = new Intent(); intent.setComponent(componentName); final long identity = Binder.clearCallingIdentity(); try { final PendingIntent pendingIntent = PendingIntent.getActivityAsUser(getContext(), 0, intent, FLAG_IMMUTABLE, null, new UserHandle(userId)); try { result.send(STATUS_SYNC_CALL_SUCCESS, bundleFor(pendingIntent)); } catch (RemoteException e) { Slog.w(TAG, "Unable to send getServiceSettingsActivity(): " + e); } } finally { Binder.restoreCallingIdentity(identity); } } else { try { result.send(STATUS_SYNC_CALL_FAIL, null); } catch (RemoteException e) { Slog.w(TAG, "Unable to send getServiceSettingsActivity(): " + e); } } } /** * Dump the service state into the given stream. You run "adb shell dumpsys translation". */ Loading