Loading api/system-current.txt +2 −0 Original line number Diff line number Diff line Loading @@ -11833,6 +11833,8 @@ package android.view.accessibility { public final class AccessibilityManager { method public int getAccessibilityWindowId(@Nullable android.os.IBinder); method @RequiresPermission(android.Manifest.permission.MANAGE_ACCESSIBILITY) public void performAccessibilityShortcut(); method @RequiresPermission(android.Manifest.permission.MANAGE_ACCESSIBILITY) public void registerSystemAction(@NonNull android.app.RemoteAction, int); method @RequiresPermission(android.Manifest.permission.MANAGE_ACCESSIBILITY) public void unregisterSystemAction(int); } } core/java/android/view/accessibility/AccessibilityManager.java +56 −0 Original line number Diff line number Diff line Loading @@ -31,6 +31,7 @@ import android.annotation.SystemApi; import android.annotation.SystemService; import android.annotation.TestApi; import android.annotation.UserIdInt; import android.app.RemoteAction; import android.compat.annotation.UnsupportedAppUsage; import android.content.ComponentName; import android.content.Context; Loading Loading @@ -1208,6 +1209,61 @@ public final class AccessibilityManager { } } /** * Register the provided {@link RemoteAction} with the given actionId * * @param action The remote action to be registered with the given actionId as system action. * @param actionId The id uniquely identify the system action. * @hide */ @SystemApi @RequiresPermission(Manifest.permission.MANAGE_ACCESSIBILITY) public void registerSystemAction(@NonNull RemoteAction action, int actionId) { final IAccessibilityManager service; synchronized (mLock) { service = getServiceLocked(); if (service == null) { return; } } try { service.registerSystemAction(action, actionId); if (DEBUG) { Log.i(LOG_TAG, "System action " + action.getTitle() + " is registered."); } } catch (RemoteException re) { Log.e(LOG_TAG, "Error registering system action " + action.getTitle() + " ", re); } } /** * Unregister a system action with the given actionId * * @param actionId The id uniquely identify the system action to be unregistered. * @hide */ @SystemApi @RequiresPermission(Manifest.permission.MANAGE_ACCESSIBILITY) public void unregisterSystemAction(int actionId) { final IAccessibilityManager service; synchronized (mLock) { service = getServiceLocked(); if (service == null) { return; } } try { service.unregisterSystemAction(actionId); if (DEBUG) { Log.i(LOG_TAG, "System action with actionId " + actionId + " is unregistered."); } } catch (RemoteException re) { Log.e(LOG_TAG, "Error unregistering system action with actionId " + actionId + " ", re); } } /** * Notifies that the accessibility button in the system's navigation area has been clicked * Loading core/java/android/view/accessibility/IAccessibilityManager.aidl +4 −0 Original line number Diff line number Diff line Loading @@ -16,6 +16,7 @@ package android.view.accessibility; import android.app.RemoteAction; import android.accessibilityservice.AccessibilityServiceInfo; import android.accessibilityservice.IAccessibilityServiceConnection; import android.accessibilityservice.IAccessibilityServiceClient; Loading Loading @@ -82,4 +83,7 @@ interface IAccessibilityManager { int getAccessibilityWindowId(IBinder windowToken); long getRecommendedTimeoutMillis(); oneway void registerSystemAction(in RemoteAction action, int actionId); oneway void unregisterSystemAction(int actionId); } services/tests/servicestests/src/com/android/server/accessibility/AccessibilityManagerTest.java→core/tests/coretests/src/android/view/accessibility/AccessibilityManagerTest.java +39 −5 Original line number Diff line number Diff line Loading @@ -14,7 +14,7 @@ * limitations under the License. */ package com.android.server.accessibility; package android.view.accessibility; import static junit.framework.TestCase.assertFalse; import static junit.framework.TestCase.assertSame; Loading @@ -29,16 +29,17 @@ import static org.mockito.Mockito.when; import android.accessibilityservice.AccessibilityServiceInfo; import android.app.Instrumentation; import android.app.PendingIntent; import android.app.RemoteAction; import android.content.Intent; import android.graphics.drawable.Icon; import android.os.UserHandle; import android.view.accessibility.AccessibilityEvent; import android.view.accessibility.AccessibilityManager; import android.view.accessibility.IAccessibilityManager; import android.view.accessibility.IAccessibilityManagerClient; import androidx.test.InstrumentationRegistry; import androidx.test.runner.AndroidJUnit4; import com.android.internal.util.IntPair; import com.android.server.accessibility.test.MessageCapturingHandler; import org.junit.After; import org.junit.Before; Loading @@ -57,6 +58,16 @@ import java.util.List; public class AccessibilityManagerTest { private static final boolean WITH_A11Y_ENABLED = true; private static final boolean WITH_A11Y_DISABLED = false; private static final String LABEL = "label"; private static final String INTENT_ACTION = "TESTACTION"; private static final String DESCRIPTION = "description"; private static final PendingIntent TEST_PENDING_INTENT = PendingIntent.getBroadcast( InstrumentationRegistry.getTargetContext(), 0, new Intent(INTENT_ACTION), 0); private static final RemoteAction TEST_ACTION = new RemoteAction( Icon.createWithContentUri("content://test"), LABEL, DESCRIPTION, TEST_PENDING_INTENT); @Mock private IAccessibilityManager mMockService; private MessageCapturingHandler mHandler; Loading Loading @@ -121,6 +132,29 @@ public class AccessibilityManagerTest { verify(mMockService).interrupt(UserHandle.USER_CURRENT); } @Test public void testRegisterSystemAction() throws Exception { AccessibilityManager manager = createManager(WITH_A11Y_ENABLED); RemoteAction action = new RemoteAction( Icon.createWithContentUri("content://test"), LABEL, DESCRIPTION, TEST_PENDING_INTENT); final int actionId = 0; manager.registerSystemAction(TEST_ACTION, actionId); verify(mMockService).registerSystemAction(TEST_ACTION, actionId); } @Test public void testUnregisterSystemAction() throws Exception { AccessibilityManager manager = createManager(WITH_A11Y_ENABLED); final int actionId = 0; manager.unregisterSystemAction(actionId); verify(mMockService).unregisterSystemAction(actionId); } @Test public void testIsEnabled() throws Exception { // Create manager with a11y enabled Loading services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java +57 −6 Original line number Diff line number Diff line Loading @@ -35,6 +35,7 @@ import android.annotation.Nullable; import android.app.ActivityOptions; import android.app.AlertDialog; import android.app.PendingIntent; import android.app.RemoteAction; import android.appwidget.AppWidgetManagerInternal; import android.content.ActivityNotFoundException; import android.content.BroadcastReceiver; Loading Loading @@ -148,6 +149,8 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub // their capabilities are ready. private static final int WAIT_MOTION_INJECTOR_TIMEOUT_MILLIS = 1000; static final String FUNCTION_REGISTER_SYSTEM_ACTION = "registerSystemAction"; static final String FUNCTION_UNREGISTER_SYSTEM_ACTION = "unregisterSystemAction"; private static final String FUNCTION_REGISTER_UI_TEST_AUTOMATION_SERVICE = "registerUiTestAutomationService"; Loading Loading @@ -253,6 +256,27 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub } } @VisibleForTesting AccessibilityManagerService( Context context, PackageManager packageManager, AccessibilitySecurityPolicy securityPolicy, SystemActionPerformer systemActionPerformer, AccessibilityWindowManager a11yWindowManager, AccessibilityDisplayListener a11yDisplayListener) { mContext = context; mPowerManager = (PowerManager) mContext.getSystemService(Context.POWER_SERVICE); mWindowManagerService = LocalServices.getService(WindowManagerInternal.class); mMainHandler = new MainHandler(mContext.getMainLooper()); mActivityTaskManagerService = LocalServices.getService(ActivityTaskManagerInternal.class); mPackageManager = packageManager; mSecurityPolicy = securityPolicy; mSystemActionPerformer = systemActionPerformer; mA11yWindowManager = a11yWindowManager; mA11yDisplayListener = a11yDisplayListener; init(); } /** * Creates a new instance. * Loading @@ -260,21 +284,24 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub */ public AccessibilityManagerService(Context context) { mContext = context; mPackageManager = mContext.getPackageManager(); mPowerManager = (PowerManager) mContext.getSystemService(Context.POWER_SERVICE); mWindowManagerService = LocalServices.getService(WindowManagerInternal.class); mSecurityPolicy = new AccessibilitySecurityPolicy(mContext, this); mMainHandler = new MainHandler(mContext.getMainLooper()); mActivityTaskManagerService = LocalServices.getService(ActivityTaskManagerInternal.class); mPackageManager = mContext.getPackageManager(); mSecurityPolicy = new AccessibilitySecurityPolicy(mContext, this); mSystemActionPerformer = new SystemActionPerformer(mContext, mWindowManagerService); mA11yWindowManager = new AccessibilityWindowManager(mLock, mMainHandler, mWindowManagerService, this, mSecurityPolicy, this); mA11yDisplayListener = new AccessibilityDisplayListener(mContext, mMainHandler); mSecurityPolicy.setAccessibilityWindowManager(mA11yWindowManager); mActivityTaskManagerService = LocalServices.getService(ActivityTaskManagerInternal.class); init(); } private void init() { mSecurityPolicy.setAccessibilityWindowManager(mA11yWindowManager); registerBroadcastReceivers(); new AccessibilityContentObserver(mMainHandler).register( context.getContentResolver()); mContext.getContentResolver()); } @Override Loading Loading @@ -623,6 +650,30 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub event.recycle(); } /** * This is the implementation of AccessibilityManager system API. * System UI calls into this method through AccessibilityManager system API to register a * system action. */ @Override public void registerSystemAction(RemoteAction action, int actionId) { mSecurityPolicy.enforceCallingPermission(Manifest.permission.MANAGE_ACCESSIBILITY, FUNCTION_REGISTER_SYSTEM_ACTION); mSystemActionPerformer.registerSystemAction(actionId, action); } /** * This is the implementation of AccessibilityManager system API. * System UI calls into this method through AccessibilityManager system API to unregister a * system action. */ @Override public void unregisterSystemAction(int actionId) { mSecurityPolicy.enforceCallingPermission(Manifest.permission.MANAGE_ACCESSIBILITY, FUNCTION_UNREGISTER_SYSTEM_ACTION); mSystemActionPerformer.unregisterSystemAction(actionId); } @Override public List<AccessibilityServiceInfo> getInstalledAccessibilityServiceList(int userId) { synchronized (mLock) { Loading Loading
api/system-current.txt +2 −0 Original line number Diff line number Diff line Loading @@ -11833,6 +11833,8 @@ package android.view.accessibility { public final class AccessibilityManager { method public int getAccessibilityWindowId(@Nullable android.os.IBinder); method @RequiresPermission(android.Manifest.permission.MANAGE_ACCESSIBILITY) public void performAccessibilityShortcut(); method @RequiresPermission(android.Manifest.permission.MANAGE_ACCESSIBILITY) public void registerSystemAction(@NonNull android.app.RemoteAction, int); method @RequiresPermission(android.Manifest.permission.MANAGE_ACCESSIBILITY) public void unregisterSystemAction(int); } }
core/java/android/view/accessibility/AccessibilityManager.java +56 −0 Original line number Diff line number Diff line Loading @@ -31,6 +31,7 @@ import android.annotation.SystemApi; import android.annotation.SystemService; import android.annotation.TestApi; import android.annotation.UserIdInt; import android.app.RemoteAction; import android.compat.annotation.UnsupportedAppUsage; import android.content.ComponentName; import android.content.Context; Loading Loading @@ -1208,6 +1209,61 @@ public final class AccessibilityManager { } } /** * Register the provided {@link RemoteAction} with the given actionId * * @param action The remote action to be registered with the given actionId as system action. * @param actionId The id uniquely identify the system action. * @hide */ @SystemApi @RequiresPermission(Manifest.permission.MANAGE_ACCESSIBILITY) public void registerSystemAction(@NonNull RemoteAction action, int actionId) { final IAccessibilityManager service; synchronized (mLock) { service = getServiceLocked(); if (service == null) { return; } } try { service.registerSystemAction(action, actionId); if (DEBUG) { Log.i(LOG_TAG, "System action " + action.getTitle() + " is registered."); } } catch (RemoteException re) { Log.e(LOG_TAG, "Error registering system action " + action.getTitle() + " ", re); } } /** * Unregister a system action with the given actionId * * @param actionId The id uniquely identify the system action to be unregistered. * @hide */ @SystemApi @RequiresPermission(Manifest.permission.MANAGE_ACCESSIBILITY) public void unregisterSystemAction(int actionId) { final IAccessibilityManager service; synchronized (mLock) { service = getServiceLocked(); if (service == null) { return; } } try { service.unregisterSystemAction(actionId); if (DEBUG) { Log.i(LOG_TAG, "System action with actionId " + actionId + " is unregistered."); } } catch (RemoteException re) { Log.e(LOG_TAG, "Error unregistering system action with actionId " + actionId + " ", re); } } /** * Notifies that the accessibility button in the system's navigation area has been clicked * Loading
core/java/android/view/accessibility/IAccessibilityManager.aidl +4 −0 Original line number Diff line number Diff line Loading @@ -16,6 +16,7 @@ package android.view.accessibility; import android.app.RemoteAction; import android.accessibilityservice.AccessibilityServiceInfo; import android.accessibilityservice.IAccessibilityServiceConnection; import android.accessibilityservice.IAccessibilityServiceClient; Loading Loading @@ -82,4 +83,7 @@ interface IAccessibilityManager { int getAccessibilityWindowId(IBinder windowToken); long getRecommendedTimeoutMillis(); oneway void registerSystemAction(in RemoteAction action, int actionId); oneway void unregisterSystemAction(int actionId); }
services/tests/servicestests/src/com/android/server/accessibility/AccessibilityManagerTest.java→core/tests/coretests/src/android/view/accessibility/AccessibilityManagerTest.java +39 −5 Original line number Diff line number Diff line Loading @@ -14,7 +14,7 @@ * limitations under the License. */ package com.android.server.accessibility; package android.view.accessibility; import static junit.framework.TestCase.assertFalse; import static junit.framework.TestCase.assertSame; Loading @@ -29,16 +29,17 @@ import static org.mockito.Mockito.when; import android.accessibilityservice.AccessibilityServiceInfo; import android.app.Instrumentation; import android.app.PendingIntent; import android.app.RemoteAction; import android.content.Intent; import android.graphics.drawable.Icon; import android.os.UserHandle; import android.view.accessibility.AccessibilityEvent; import android.view.accessibility.AccessibilityManager; import android.view.accessibility.IAccessibilityManager; import android.view.accessibility.IAccessibilityManagerClient; import androidx.test.InstrumentationRegistry; import androidx.test.runner.AndroidJUnit4; import com.android.internal.util.IntPair; import com.android.server.accessibility.test.MessageCapturingHandler; import org.junit.After; import org.junit.Before; Loading @@ -57,6 +58,16 @@ import java.util.List; public class AccessibilityManagerTest { private static final boolean WITH_A11Y_ENABLED = true; private static final boolean WITH_A11Y_DISABLED = false; private static final String LABEL = "label"; private static final String INTENT_ACTION = "TESTACTION"; private static final String DESCRIPTION = "description"; private static final PendingIntent TEST_PENDING_INTENT = PendingIntent.getBroadcast( InstrumentationRegistry.getTargetContext(), 0, new Intent(INTENT_ACTION), 0); private static final RemoteAction TEST_ACTION = new RemoteAction( Icon.createWithContentUri("content://test"), LABEL, DESCRIPTION, TEST_PENDING_INTENT); @Mock private IAccessibilityManager mMockService; private MessageCapturingHandler mHandler; Loading Loading @@ -121,6 +132,29 @@ public class AccessibilityManagerTest { verify(mMockService).interrupt(UserHandle.USER_CURRENT); } @Test public void testRegisterSystemAction() throws Exception { AccessibilityManager manager = createManager(WITH_A11Y_ENABLED); RemoteAction action = new RemoteAction( Icon.createWithContentUri("content://test"), LABEL, DESCRIPTION, TEST_PENDING_INTENT); final int actionId = 0; manager.registerSystemAction(TEST_ACTION, actionId); verify(mMockService).registerSystemAction(TEST_ACTION, actionId); } @Test public void testUnregisterSystemAction() throws Exception { AccessibilityManager manager = createManager(WITH_A11Y_ENABLED); final int actionId = 0; manager.unregisterSystemAction(actionId); verify(mMockService).unregisterSystemAction(actionId); } @Test public void testIsEnabled() throws Exception { // Create manager with a11y enabled Loading
services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java +57 −6 Original line number Diff line number Diff line Loading @@ -35,6 +35,7 @@ import android.annotation.Nullable; import android.app.ActivityOptions; import android.app.AlertDialog; import android.app.PendingIntent; import android.app.RemoteAction; import android.appwidget.AppWidgetManagerInternal; import android.content.ActivityNotFoundException; import android.content.BroadcastReceiver; Loading Loading @@ -148,6 +149,8 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub // their capabilities are ready. private static final int WAIT_MOTION_INJECTOR_TIMEOUT_MILLIS = 1000; static final String FUNCTION_REGISTER_SYSTEM_ACTION = "registerSystemAction"; static final String FUNCTION_UNREGISTER_SYSTEM_ACTION = "unregisterSystemAction"; private static final String FUNCTION_REGISTER_UI_TEST_AUTOMATION_SERVICE = "registerUiTestAutomationService"; Loading Loading @@ -253,6 +256,27 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub } } @VisibleForTesting AccessibilityManagerService( Context context, PackageManager packageManager, AccessibilitySecurityPolicy securityPolicy, SystemActionPerformer systemActionPerformer, AccessibilityWindowManager a11yWindowManager, AccessibilityDisplayListener a11yDisplayListener) { mContext = context; mPowerManager = (PowerManager) mContext.getSystemService(Context.POWER_SERVICE); mWindowManagerService = LocalServices.getService(WindowManagerInternal.class); mMainHandler = new MainHandler(mContext.getMainLooper()); mActivityTaskManagerService = LocalServices.getService(ActivityTaskManagerInternal.class); mPackageManager = packageManager; mSecurityPolicy = securityPolicy; mSystemActionPerformer = systemActionPerformer; mA11yWindowManager = a11yWindowManager; mA11yDisplayListener = a11yDisplayListener; init(); } /** * Creates a new instance. * Loading @@ -260,21 +284,24 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub */ public AccessibilityManagerService(Context context) { mContext = context; mPackageManager = mContext.getPackageManager(); mPowerManager = (PowerManager) mContext.getSystemService(Context.POWER_SERVICE); mWindowManagerService = LocalServices.getService(WindowManagerInternal.class); mSecurityPolicy = new AccessibilitySecurityPolicy(mContext, this); mMainHandler = new MainHandler(mContext.getMainLooper()); mActivityTaskManagerService = LocalServices.getService(ActivityTaskManagerInternal.class); mPackageManager = mContext.getPackageManager(); mSecurityPolicy = new AccessibilitySecurityPolicy(mContext, this); mSystemActionPerformer = new SystemActionPerformer(mContext, mWindowManagerService); mA11yWindowManager = new AccessibilityWindowManager(mLock, mMainHandler, mWindowManagerService, this, mSecurityPolicy, this); mA11yDisplayListener = new AccessibilityDisplayListener(mContext, mMainHandler); mSecurityPolicy.setAccessibilityWindowManager(mA11yWindowManager); mActivityTaskManagerService = LocalServices.getService(ActivityTaskManagerInternal.class); init(); } private void init() { mSecurityPolicy.setAccessibilityWindowManager(mA11yWindowManager); registerBroadcastReceivers(); new AccessibilityContentObserver(mMainHandler).register( context.getContentResolver()); mContext.getContentResolver()); } @Override Loading Loading @@ -623,6 +650,30 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub event.recycle(); } /** * This is the implementation of AccessibilityManager system API. * System UI calls into this method through AccessibilityManager system API to register a * system action. */ @Override public void registerSystemAction(RemoteAction action, int actionId) { mSecurityPolicy.enforceCallingPermission(Manifest.permission.MANAGE_ACCESSIBILITY, FUNCTION_REGISTER_SYSTEM_ACTION); mSystemActionPerformer.registerSystemAction(actionId, action); } /** * This is the implementation of AccessibilityManager system API. * System UI calls into this method through AccessibilityManager system API to unregister a * system action. */ @Override public void unregisterSystemAction(int actionId) { mSecurityPolicy.enforceCallingPermission(Manifest.permission.MANAGE_ACCESSIBILITY, FUNCTION_UNREGISTER_SYSTEM_ACTION); mSystemActionPerformer.unregisterSystemAction(actionId); } @Override public List<AccessibilityServiceInfo> getInstalledAccessibilityServiceList(int userId) { synchronized (mLock) { Loading