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

Commit 901ca0f2 authored by lucychang's avatar lucychang Committed by Lucy Chang
Browse files

Send componentName via extra for Accessibility usage notification

Send componentName via extra instead of idenfifier for Accessibility
usage notification intents because the identifier is used to identify
different intents only. The formal way to send data is via extra, thus
the notification can be launched by adb command.

Bug: 176965357
Test: enable a11y service and execute adb command below.
adb shell am broadcast -a PolicyWarningUIController.ACTION_SEND_NOTIFICATION
-p android --receiver-permission android.permission.MANAGE_ACCESSIBILITY
--ei android.intent.extra.USER_ID 0
--ecn android.intent.extra.COMPONENT_NAME xxx/yyy

Change-Id: I898b66efc05f0144981dd16bd92d719c756b4c2d
parent f5042bcc
Loading
Loading
Loading
Loading
+23 −17
Original line number Diff line number Diff line
@@ -158,24 +158,29 @@ public class PolicyWarningUIController {
        final Calendar cal = Calendar.getInstance();
        cal.add(Calendar.HOUR, SEND_NOTIFICATION_DELAY_HOURS);
        mAlarmManager.set(RTC_WAKEUP, cal.getTimeInMillis(),
                createPendingIntent(mContext, userId, ACTION_SEND_NOTIFICATION,
                        service.flattenToShortString()));
                createPendingIntent(mContext, userId, ACTION_SEND_NOTIFICATION, service));
    }

    private void cancelAlarm(int userId, ComponentName service) {
        mAlarmManager.cancel(
                createPendingIntent(mContext, userId, ACTION_SEND_NOTIFICATION,
                        service.flattenToShortString()));
                createPendingIntent(mContext, userId, ACTION_SEND_NOTIFICATION, service));
    }

    protected static PendingIntent createPendingIntent(Context context, int userId, String action,
            String serviceComponentName) {
            ComponentName serviceComponentName) {
        return PendingIntent.getBroadcast(context, 0,
                createIntent(context, userId, action, serviceComponentName),
                PendingIntent.FLAG_IMMUTABLE);
    }

    protected static Intent createIntent(Context context, int userId, String action,
            ComponentName serviceComponentName) {
        final Intent intent = new Intent(action);
        intent.setPackage(context.getPackageName())
                .setIdentifier(serviceComponentName)
                .setIdentifier(serviceComponentName.flattenToShortString())
                .putExtra(Intent.EXTRA_COMPONENT_NAME, serviceComponentName)
                .putExtra(Intent.EXTRA_USER_ID, userId);
        return PendingIntent.getBroadcast(context, 0, intent,
                PendingIntent.FLAG_IMMUTABLE);
        return intent;
    }

    /** A sub class to handle notifications and settings on the main thread. */
@@ -204,10 +209,9 @@ public class PolicyWarningUIController {
        @Override
        public void onReceive(Context context, Intent intent) {
            final String action = intent.getAction();
            final String service = intent.getIdentifier();
            final ComponentName componentName = ComponentName.unflattenFromString(service);
            if (TextUtils.isEmpty(action) || TextUtils.isEmpty(service)
                    || componentName == null) {
            final ComponentName componentName = intent.getParcelableExtra(
                    Intent.EXTRA_COMPONENT_NAME);
            if (TextUtils.isEmpty(action) || componentName == null) {
                return;
            }
            final int userId = intent.getIntExtra(Intent.EXTRA_USER_ID, UserHandle.USER_SYSTEM);
@@ -215,7 +219,8 @@ public class PolicyWarningUIController {
                trySendNotification(userId, componentName);
            } else if (ACTION_A11Y_SETTINGS.equals(action)) {
                launchSettings(userId, componentName);
                mNotificationManager.cancel(service, NOTE_A11Y_VIEW_AND_CONTROL_ACCESS);
                mNotificationManager.cancel(componentName.flattenToShortString(),
                        NOTE_A11Y_VIEW_AND_CONTROL_ACCESS);
                onNotificationCanceled(userId, componentName);
            } else if (ACTION_DISMISS_NOTIFICATION.equals(action)) {
                onNotificationCanceled(userId, componentName);
@@ -257,8 +262,7 @@ public class PolicyWarningUIController {
                                mContext.getPackageManager());
                        final int size = mContext.getResources().getDimensionPixelSize(
                                android.R.dimen.app_icon_size);
                        sendNotification(userId, componentName.flattenToShortString(),
                                displayName,
                        sendNotification(userId, componentName, displayName,
                                ImageUtils.buildScaledBitmap(drawable, size, size));
                    }
                    break;
@@ -289,7 +293,8 @@ public class PolicyWarningUIController {
            }
        }

        private void sendNotification(int userId, String serviceComponentName, CharSequence name,
        private void sendNotification(int userId, ComponentName serviceComponentName,
                CharSequence name,
                Bitmap bitmap) {
            final Notification.Builder notificationBuilder = new Notification.Builder(mContext,
                    SystemNotificationChannels.ACCESSIBILITY_SECURITY_POLICY);
@@ -315,7 +320,8 @@ public class PolicyWarningUIController {
            if (bitmap != null) {
                notificationBuilder.setLargeIcon(bitmap);
            }
            mNotificationManager.notify(serviceComponentName, NOTE_A11Y_VIEW_AND_CONTROL_ACCESS,
            mNotificationManager.notify(serviceComponentName.flattenToShortString(),
                    NOTE_A11Y_VIEW_AND_CONTROL_ACCESS,
                    notificationBuilder.build());
        }

+16 −26
Original line number Diff line number Diff line
@@ -119,36 +119,36 @@ public class PolicyWarningUIControllerTest {
        when(mAccessibilitySecurityPolicy.isA11yCategoryService(
                mMockA11yServiceInfo)).thenReturn(false);

        mFakeNotificationController.onReceive(mContext, createIntent(TEST_USER_ID,
        mFakeNotificationController.onReceive(mContext,
                PolicyWarningUIController.createIntent(mContext, TEST_USER_ID,
                        PolicyWarningUIController.ACTION_SEND_NOTIFICATION,
                TEST_COMPONENT_NAME.flattenToShortString()));
                        TEST_COMPONENT_NAME));

        verify(mNotificationManager).notify(eq(TEST_COMPONENT_NAME.flattenToShortString()),
                eq(NOTE_A11Y_VIEW_AND_CONTROL_ACCESS), any(
                        Notification.class));
                eq(NOTE_A11Y_VIEW_AND_CONTROL_ACCESS), any(Notification.class));
    }

    @Test
    public void receiveActionA11ySettings_launchA11ySettingsAndDismissNotification() {
        mFakeNotificationController.onReceive(mContext,
                createIntent(TEST_USER_ID, PolicyWarningUIController.ACTION_A11Y_SETTINGS,
                        TEST_COMPONENT_NAME.flattenToShortString()));
                PolicyWarningUIController.createIntent(mContext, TEST_USER_ID,
                        PolicyWarningUIController.ACTION_A11Y_SETTINGS,
                        TEST_COMPONENT_NAME));

        verifyLaunchA11ySettings();
        verify(mNotificationManager).cancel(TEST_COMPONENT_NAME.flattenToShortString(),
                NOTE_A11Y_VIEW_AND_CONTROL_ACCESS);
        assertNotifiedSettingsEqual(TEST_USER_ID,
                TEST_COMPONENT_NAME.flattenToShortString());
        assertNotifiedSettingsEqual(TEST_USER_ID, TEST_COMPONENT_NAME.flattenToShortString());
    }

    @Test
    public void receiveActionDismissNotification_addToNotifiedSettings() {
        mFakeNotificationController.onReceive(mContext, createIntent(TEST_USER_ID,
        mFakeNotificationController.onReceive(mContext,
                PolicyWarningUIController.createIntent(mContext, TEST_USER_ID,
                        PolicyWarningUIController.ACTION_DISMISS_NOTIFICATION,
                TEST_COMPONENT_NAME.flattenToShortString()));
                        TEST_COMPONENT_NAME));

        assertNotifiedSettingsEqual(TEST_USER_ID,
                TEST_COMPONENT_NAME.flattenToShortString());
        assertNotifiedSettingsEqual(TEST_USER_ID, TEST_COMPONENT_NAME.flattenToShortString());
    }

    @Test
@@ -172,8 +172,7 @@ public class PolicyWarningUIControllerTest {

        verify(mAlarmManager).set(eq(RTC_WAKEUP), anyLong(),
                eq(PolicyWarningUIController.createPendingIntent(mContext, TEST_USER_ID,
                        PolicyWarningUIController.ACTION_SEND_NOTIFICATION,
                        TEST_COMPONENT_NAME.flattenToShortString())));
                        PolicyWarningUIController.ACTION_SEND_NOTIFICATION, TEST_COMPONENT_NAME)));
    }

    @Test
@@ -184,8 +183,7 @@ public class PolicyWarningUIControllerTest {

        verify(mAlarmManager).cancel(
                eq(PolicyWarningUIController.createPendingIntent(mContext, TEST_USER_ID,
                        PolicyWarningUIController.ACTION_SEND_NOTIFICATION,
                        TEST_COMPONENT_NAME.flattenToShortString())));
                        PolicyWarningUIController.ACTION_SEND_NOTIFICATION, TEST_COMPONENT_NAME)));
    }

    private void assertNotifiedSettingsEqual(int userId, String settingString) {
@@ -196,14 +194,6 @@ public class PolicyWarningUIControllerTest {
        assertEquals(settingString, notifiedServicesSetting);
    }

    private Intent createIntent(int userId, String action, String serviceComponentName) {
        final Intent intent = new Intent(action);
        intent.setPackage(mContext.getPackageName())
                .setIdentifier(serviceComponentName)
                .putExtra(Intent.EXTRA_USER_ID, userId);
        return intent;
    }

    private void verifyLaunchA11ySettings() {
        final ArgumentCaptor<Intent> intentCaptor = ArgumentCaptor.forClass(Intent.class);
        final ArgumentCaptor<UserHandle> userHandleCaptor = ArgumentCaptor.forClass(