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

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

Merge "Avoid users add one-handed mode by edit shortcut dialog in unsupported...

Merge "Avoid users add one-handed mode by edit shortcut dialog in unsupported devices" into tm-qpr-dev
parents bc68ad7c e30a2697
Loading
Loading
Loading
Loading
+8 −5
Original line number Original line Diff line number Diff line
@@ -21,6 +21,7 @@ import static android.view.WindowManager.LayoutParams.TYPE_KEYGUARD_DIALOG;
import static android.view.accessibility.AccessibilityManager.ACCESSIBILITY_SHORTCUT_KEY;
import static android.view.accessibility.AccessibilityManager.ACCESSIBILITY_SHORTCUT_KEY;


import static com.android.internal.accessibility.dialog.AccessibilityTargetHelper.getTargets;
import static com.android.internal.accessibility.dialog.AccessibilityTargetHelper.getTargets;
import static com.android.internal.os.RoSystemProperties.SUPPORT_ONE_HANDED_MODE;
import static com.android.internal.util.ArrayUtils.convertToLongArray;
import static com.android.internal.util.ArrayUtils.convertToLongArray;


import android.accessibilityservice.AccessibilityServiceInfo;
import android.accessibilityservice.AccessibilityServiceInfo;
@@ -147,11 +148,13 @@ public class AccessibilityShortcutController {
                            Settings.Secure.ACCESSIBILITY_DISPLAY_DALTONIZER_ENABLED,
                            Settings.Secure.ACCESSIBILITY_DISPLAY_DALTONIZER_ENABLED,
                            "1" /* Value to enable */, "0" /* Value to disable */,
                            "1" /* Value to enable */, "0" /* Value to disable */,
                            R.string.color_correction_feature_name));
                            R.string.color_correction_feature_name));
            if (SUPPORT_ONE_HANDED_MODE) {
                featuresMap.put(ONE_HANDED_COMPONENT_NAME,
                featuresMap.put(ONE_HANDED_COMPONENT_NAME,
                        new ToggleableFrameworkFeatureInfo(
                        new ToggleableFrameworkFeatureInfo(
                                Settings.Secure.ONE_HANDED_MODE_ACTIVATED,
                                Settings.Secure.ONE_HANDED_MODE_ACTIVATED,
                                "1" /* Value to enable */, "0" /* Value to disable */,
                                "1" /* Value to enable */, "0" /* Value to disable */,
                                R.string.one_handed_mode_feature_name));
                                R.string.one_handed_mode_feature_name));
            }
            featuresMap.put(REDUCE_BRIGHT_COLORS_COMPONENT_NAME,
            featuresMap.put(REDUCE_BRIGHT_COLORS_COMPONENT_NAME,
                    new ToggleableFrameworkFeatureInfo(
                    new ToggleableFrameworkFeatureInfo(
                            Settings.Secure.REDUCE_BRIGHT_COLORS_ACTIVATED,
                            Settings.Secure.REDUCE_BRIGHT_COLORS_ACTIVATED,
+16 −14
Original line number Original line Diff line number Diff line
@@ -25,6 +25,7 @@ import static com.android.internal.accessibility.AccessibilityShortcutController
import static com.android.internal.accessibility.AccessibilityShortcutController.REDUCE_BRIGHT_COLORS_COMPONENT_NAME;
import static com.android.internal.accessibility.AccessibilityShortcutController.REDUCE_BRIGHT_COLORS_COMPONENT_NAME;
import static com.android.internal.accessibility.util.AccessibilityUtils.getAccessibilityServiceFragmentType;
import static com.android.internal.accessibility.util.AccessibilityUtils.getAccessibilityServiceFragmentType;
import static com.android.internal.accessibility.util.ShortcutUtils.isShortcutContained;
import static com.android.internal.accessibility.util.ShortcutUtils.isShortcutContained;
import static com.android.internal.os.RoSystemProperties.SUPPORT_ONE_HANDED_MODE;


import android.accessibilityservice.AccessibilityServiceInfo;
import android.accessibilityservice.AccessibilityServiceInfo;
import android.accessibilityservice.AccessibilityShortcutInfo;
import android.accessibilityservice.AccessibilityShortcutInfo;
@@ -209,6 +210,7 @@ public final class AccessibilityTargetHelper {
                        context.getString(R.string.accessibility_magnification_chooser_text),
                        context.getString(R.string.accessibility_magnification_chooser_text),
                        context.getDrawable(R.drawable.ic_accessibility_magnification),
                        context.getDrawable(R.drawable.ic_accessibility_magnification),
                        Settings.Secure.ACCESSIBILITY_DISPLAY_MAGNIFICATION_NAVBAR_ENABLED);
                        Settings.Secure.ACCESSIBILITY_DISPLAY_MAGNIFICATION_NAVBAR_ENABLED);
        targets.add(magnification);


        final ToggleAllowListingFeatureTarget daltonizer =
        final ToggleAllowListingFeatureTarget daltonizer =
                new ToggleAllowListingFeatureTarget(context,
                new ToggleAllowListingFeatureTarget(context,
@@ -219,6 +221,7 @@ public final class AccessibilityTargetHelper {
                        context.getString(R.string.color_correction_feature_name),
                        context.getString(R.string.color_correction_feature_name),
                        context.getDrawable(R.drawable.ic_accessibility_color_correction),
                        context.getDrawable(R.drawable.ic_accessibility_color_correction),
                        Settings.Secure.ACCESSIBILITY_DISPLAY_DALTONIZER_ENABLED);
                        Settings.Secure.ACCESSIBILITY_DISPLAY_DALTONIZER_ENABLED);
        targets.add(daltonizer);


        final ToggleAllowListingFeatureTarget colorInversion =
        final ToggleAllowListingFeatureTarget colorInversion =
                new ToggleAllowListingFeatureTarget(context,
                new ToggleAllowListingFeatureTarget(context,
@@ -229,7 +232,9 @@ public final class AccessibilityTargetHelper {
                        context.getString(R.string.color_inversion_feature_name),
                        context.getString(R.string.color_inversion_feature_name),
                        context.getDrawable(R.drawable.ic_accessibility_color_inversion),
                        context.getDrawable(R.drawable.ic_accessibility_color_inversion),
                        Settings.Secure.ACCESSIBILITY_DISPLAY_INVERSION_ENABLED);
                        Settings.Secure.ACCESSIBILITY_DISPLAY_INVERSION_ENABLED);
        targets.add(colorInversion);


        if (SUPPORT_ONE_HANDED_MODE) {
            final ToggleAllowListingFeatureTarget oneHandedMode =
            final ToggleAllowListingFeatureTarget oneHandedMode =
                    new ToggleAllowListingFeatureTarget(context,
                    new ToggleAllowListingFeatureTarget(context,
                            shortcutType,
                            shortcutType,
@@ -239,6 +244,8 @@ public final class AccessibilityTargetHelper {
                            context.getString(R.string.one_handed_mode_feature_name),
                            context.getString(R.string.one_handed_mode_feature_name),
                            context.getDrawable(R.drawable.ic_accessibility_one_handed),
                            context.getDrawable(R.drawable.ic_accessibility_one_handed),
                            Settings.Secure.ONE_HANDED_MODE_ACTIVATED);
                            Settings.Secure.ONE_HANDED_MODE_ACTIVATED);
            targets.add(oneHandedMode);
        }


        final ToggleAllowListingFeatureTarget reduceBrightColors =
        final ToggleAllowListingFeatureTarget reduceBrightColors =
                new ToggleAllowListingFeatureTarget(context,
                new ToggleAllowListingFeatureTarget(context,
@@ -249,11 +256,6 @@ public final class AccessibilityTargetHelper {
                        context.getString(R.string.reduce_bright_colors_feature_name),
                        context.getString(R.string.reduce_bright_colors_feature_name),
                        context.getDrawable(R.drawable.ic_accessibility_reduce_bright_colors),
                        context.getDrawable(R.drawable.ic_accessibility_reduce_bright_colors),
                        Settings.Secure.REDUCE_BRIGHT_COLORS_ACTIVATED);
                        Settings.Secure.REDUCE_BRIGHT_COLORS_ACTIVATED);

        targets.add(magnification);
        targets.add(daltonizer);
        targets.add(colorInversion);
        targets.add(oneHandedMode);
        targets.add(reduceBrightColors);
        targets.add(reduceBrightColors);


        return targets;
        return targets;
+2 −0
Original line number Original line Diff line number Diff line
@@ -31,6 +31,8 @@ public class RoSystemProperties {
            SystemProperties.getInt("ro.factorytest", 0);
            SystemProperties.getInt("ro.factorytest", 0);
    public static final String CONTROL_PRIVAPP_PERMISSIONS =
    public static final String CONTROL_PRIVAPP_PERMISSIONS =
            SystemProperties.get("ro.control_privapp_permissions");
            SystemProperties.get("ro.control_privapp_permissions");
    public static final boolean SUPPORT_ONE_HANDED_MODE =
            SystemProperties.getBoolean("ro.support_one_handed_mode", /* def= */ false);


    // ------ ro.hdmi.* -------- //
    // ------ ro.hdmi.* -------- //
    /**
    /**
+1 −0
Original line number Original line Diff line number Diff line
@@ -1414,6 +1414,7 @@
        <activity android:name="com.android.internal.app.ChooserWrapperActivity"/>
        <activity android:name="com.android.internal.app.ChooserWrapperActivity"/>
        <activity android:name="com.android.internal.app.ResolverWrapperActivity"/>
        <activity android:name="com.android.internal.app.ResolverWrapperActivity"/>
        <activity android:name="com.android.internal.app.IntentForwarderActivityTest$IntentForwarderWrapperActivity"/>
        <activity android:name="com.android.internal.app.IntentForwarderActivityTest$IntentForwarderWrapperActivity"/>
        <activity android:name="com.android.internal.accessibility.AccessibilityShortcutChooserActivityTest$TestAccessibilityShortcutChooserActivity"/>


        <receiver android:name="android.app.activity.AbortReceiver"
        <receiver android:name="android.app.activity.AbortReceiver"
            android:exported="true">
            android:exported="true">
+182 −0
Original line number Original line Diff line number Diff line
/*
 * Copyright (C) 2022 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 com.android.internal.accessibility;

import static androidx.test.espresso.Espresso.onView;
import static androidx.test.espresso.action.ViewActions.click;
import static androidx.test.espresso.action.ViewActions.doubleClick;
import static androidx.test.espresso.action.ViewActions.scrollTo;
import static androidx.test.espresso.action.ViewActions.swipeUp;
import static androidx.test.espresso.assertion.ViewAssertions.doesNotExist;
import static androidx.test.espresso.assertion.ViewAssertions.matches;
import static androidx.test.espresso.matcher.RootMatchers.isDialog;
import static androidx.test.espresso.matcher.ViewMatchers.isDisplayed;
import static androidx.test.espresso.matcher.ViewMatchers.withClassName;
import static androidx.test.espresso.matcher.ViewMatchers.withId;
import static androidx.test.espresso.matcher.ViewMatchers.withText;

import static org.hamcrest.Matchers.allOf;
import static org.hamcrest.Matchers.endsWith;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.Mockito.when;

import android.accessibilityservice.AccessibilityServiceInfo;
import android.content.ComponentName;
import android.content.Context;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.content.pm.ServiceInfo;
import android.os.Handler;
import android.view.accessibility.AccessibilityManager;
import android.view.accessibility.IAccessibilityManager;

import androidx.lifecycle.Lifecycle;
import androidx.test.core.app.ActivityScenario;
import androidx.test.platform.app.InstrumentationRegistry;
import androidx.test.runner.AndroidJUnit4;

import com.android.internal.R;
import com.android.internal.accessibility.dialog.AccessibilityShortcutChooserActivity;

import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.junit.MockitoJUnit;
import org.mockito.junit.MockitoRule;

import java.util.Collections;

/**
 * Tests for {@link AccessibilityShortcutChooserActivity}.
 */
@RunWith(AndroidJUnit4.class)
public class AccessibilityShortcutChooserActivityTest {
    private static final String ONE_HANDED_MODE = "One-Handed mode";
    private static final String TEST_LABEL = "TEST_LABEL";
    private static final ComponentName TEST_COMPONENT_NAME = new ComponentName("package", "class");

    @Rule
    public final MockitoRule mMockitoRule = MockitoJUnit.rule();
    @Mock
    private AccessibilityServiceInfo mAccessibilityServiceInfo;
    @Mock
    private ResolveInfo mResolveInfo;
    @Mock
    private ServiceInfo mServiceInfo;
    @Mock
    private ApplicationInfo mApplicationInfo;
    @Mock
    private IAccessibilityManager mAccessibilityManagerService;

    @Test
    public void doubleClickTestServiceAndClickDenyButton_permissionDialogDoesNotExist()
            throws Exception {
        configureTestService();
        final ActivityScenario<TestAccessibilityShortcutChooserActivity> scenario =
                ActivityScenario.launch(TestAccessibilityShortcutChooserActivity.class);
        scenario.moveToState(Lifecycle.State.CREATED);
        scenario.moveToState(Lifecycle.State.STARTED);
        scenario.moveToState(Lifecycle.State.RESUMED);

        onView(withText(R.string.accessibility_select_shortcut_menu_title)).inRoot(
                isDialog()).check(matches(isDisplayed()));
        onView(withText(R.string.edit_accessibility_shortcut_menu_button)).perform(click());
        onView(withText(TEST_LABEL)).perform(scrollTo(), doubleClick());
        onView(withId(R.id.accessibility_permission_enable_deny_button)).perform(scrollTo(),
                click());

        onView(withId(R.id.accessibility_permissionDialog_title)).inRoot(isDialog()).check(
                doesNotExist());
        scenario.moveToState(Lifecycle.State.DESTROYED);
    }

    @Test
    public void popEditShortcutMenuList_oneHandedModeEnabled_shouldBeInListView() {
        TestUtils.setOneHandedModeEnabled(this, /* enabled= */ true);
        final ActivityScenario<TestAccessibilityShortcutChooserActivity> scenario =
                ActivityScenario.launch(TestAccessibilityShortcutChooserActivity.class);
        scenario.moveToState(Lifecycle.State.CREATED);
        scenario.moveToState(Lifecycle.State.STARTED);
        scenario.moveToState(Lifecycle.State.RESUMED);

        onView(withText(R.string.accessibility_select_shortcut_menu_title)).inRoot(
                isDialog()).check(matches(isDisplayed()));
        onView(withText(R.string.edit_accessibility_shortcut_menu_button)).perform(click());
        onView(allOf(withClassName(endsWith("ListView")), isDisplayed())).perform(swipeUp());
        InstrumentationRegistry.getInstrumentation().waitForIdleSync();

        onView(withText(ONE_HANDED_MODE)).inRoot(isDialog()).check(matches(isDisplayed()));
        scenario.moveToState(Lifecycle.State.DESTROYED);
    }

    @Test
    public void popEditShortcutMenuList_oneHandedModeDisabled_shouldNotBeInListView() {
        TestUtils.setOneHandedModeEnabled(this, /* enabled= */ false);
        final ActivityScenario<TestAccessibilityShortcutChooserActivity> scenario =
                ActivityScenario.launch(TestAccessibilityShortcutChooserActivity.class);
        scenario.moveToState(Lifecycle.State.CREATED);
        scenario.moveToState(Lifecycle.State.STARTED);
        scenario.moveToState(Lifecycle.State.RESUMED);

        onView(withText(R.string.accessibility_select_shortcut_menu_title)).inRoot(
                isDialog()).check(matches(isDisplayed()));
        onView(withText(R.string.edit_accessibility_shortcut_menu_button)).perform(click());
        onView(allOf(withClassName(endsWith("ListView")), isDisplayed())).perform(swipeUp());
        InstrumentationRegistry.getInstrumentation().waitForIdleSync();

        onView(withText(ONE_HANDED_MODE)).inRoot(isDialog()).check(doesNotExist());
        scenario.moveToState(Lifecycle.State.DESTROYED);
    }

    private void configureTestService() throws Exception {
        when(mAccessibilityServiceInfo.getResolveInfo()).thenReturn(mResolveInfo);
        mResolveInfo.serviceInfo = mServiceInfo;
        mServiceInfo.applicationInfo = mApplicationInfo;
        when(mResolveInfo.loadLabel(any(PackageManager.class))).thenReturn(TEST_LABEL);
        when(mAccessibilityServiceInfo.getComponentName()).thenReturn(TEST_COMPONENT_NAME);
        when(mAccessibilityManagerService.getInstalledAccessibilityServiceList(
                anyInt())).thenReturn(Collections.singletonList(mAccessibilityServiceInfo));

        TestAccessibilityShortcutChooserActivity.setupForTesting(mAccessibilityManagerService);
    }

    /**
     * Used for testing.
     */
    public static class TestAccessibilityShortcutChooserActivity extends
            AccessibilityShortcutChooserActivity {
        private static IAccessibilityManager sAccessibilityManagerService;

        public static void setupForTesting(IAccessibilityManager accessibilityManagerService) {
            sAccessibilityManagerService = accessibilityManagerService;
        }

        @Override
        public Object getSystemService(String name) {
            if (Context.ACCESSIBILITY_SERVICE.equals(name)
                    && sAccessibilityManagerService != null) {
                return new AccessibilityManager(this, new Handler(getMainLooper()),
                        sAccessibilityManagerService, /* userId= */ 0, /* serviceConnect= */ true);
            }

            return super.getSystemService(name);
        }
    }
}
Loading