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

Commit 7deda6a9 authored by ryanlwlin's avatar ryanlwlin
Browse files

Provide a way to Magnification settings via intent

Framework needs a way to launch magnification settings.

bug: 168635084
Test: adb shell am start -a \
     "android.settings.ACCESSIBILITY_DETAILS_SETTINGS"  \
     --es android.intent.extra.COMPONENT_NAME  \
     "com.android.server.accessibility/Magnification"
     AccessibilityDetailsSettingsFragmentTest
Change-Id: Iafb5ad4802a52e4bf3c443af99cd27ef0da0ea29
parent 0254a6c3
Loading
Loading
Loading
Loading
+69 −21
Original line number Diff line number Diff line
@@ -16,6 +16,8 @@

package com.android.settings.accessibility;

import static com.android.internal.accessibility.AccessibilityShortcutController.MAGNIFICATION_COMPONENT_NAME;

import android.accessibilityservice.AccessibilityServiceInfo;
import android.app.Activity;
import android.app.admin.DevicePolicyManager;
@@ -30,6 +32,9 @@ import android.text.TextUtils;
import android.util.Log;
import android.view.accessibility.AccessibilityManager;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;

import com.android.internal.annotations.VisibleForTesting;
import com.android.settings.R;
import com.android.settings.core.InstrumentedFragment;
@@ -37,6 +42,7 @@ import com.android.settings.core.SubSettingLauncher;
import com.android.settingslib.accessibility.AccessibilityUtils;

import java.util.List;
import java.util.Objects;
import java.util.Set;

public class AccessibilityDetailsSettingsFragment extends InstrumentedFragment {
@@ -61,44 +67,77 @@ public class AccessibilityDetailsSettingsFragment extends InstrumentedFragment {
            return;
        }

        // In case the A11yServiceInfo doesn't exist, go to ally services list.
        final ComponentName componentName = ComponentName.unflattenFromString(extraComponentName);
        if (openSystemAccessibilitySettingsAndFinish(componentName)) {
            return;
        }

        if (openAccessibilityDetailsSettingsAndFinish(componentName)) {
            return;
        }
        // Fall back to open accessibility services list.
        openAccessibilitySettingsAndFinish();
    }

    private boolean openSystemAccessibilitySettingsAndFinish(
            @Nullable ComponentName componentName) {
        final LaunchFragmentArguments launchArguments =
                getSystemAccessibilitySettingsLaunchArguments(componentName);
        if (launchArguments == null) {
            return false;
        }
        openSubSettings(launchArguments.mDestination, launchArguments.mArguments);
        finish();
        return true;
    }

    @Nullable
    private LaunchFragmentArguments getSystemAccessibilitySettingsLaunchArguments(
            @Nullable ComponentName componentName) {
        if (MAGNIFICATION_COMPONENT_NAME.equals(componentName)) {
            final String destination = ToggleScreenMagnificationPreferenceFragment.class.getName();
            final Bundle arguments = new Bundle();
            MagnificationGesturesPreferenceController.populateMagnificationGesturesPreferenceExtras(
                    arguments, getContext());
            return new LaunchFragmentArguments(destination, arguments);
        }
        return null;
    }


    private void openAccessibilitySettingsAndFinish() {
        openSubSettings(AccessibilitySettings.class.getName(), /* arguments= */ null);
        finish();
    }

    private boolean openAccessibilityDetailsSettingsAndFinish(
            @Nullable ComponentName componentName) {
        // In case the A11yServiceInfo doesn't exist, go to ally services list.
        final AccessibilityServiceInfo info = getAccessibilityServiceInfo(componentName);
        if (info == null) {
            Log.w(TAG, "Open accessibility services list due to invalid component name.");
            openAccessibilitySettingsAndFinish();
            return;
            Log.w(TAG, "openAccessibilityDetailsSettingsAndFinish : invalid component name.");
            return false;
        }

        // In case this accessibility service isn't permitted, go to a11y services list.
        if (!isServiceAllowed(componentName.getPackageName())) {
            Log.w(TAG,
                    "Open accessibility services list due to target accessibility service is "
                    "openAccessibilityDetailsSettingsAndFinish: target accessibility service is"
                            + "prohibited by Device Admin.");
            openAccessibilitySettingsAndFinish();
            return;
        }

        openAccessibilityDetailsSettingsAndFinish(buildArguments(info));
            return false;
        }

    @VisibleForTesting
    void openAccessibilitySettingsAndFinish() {
        new SubSettingLauncher(getActivity())
                .setDestination(AccessibilitySettings.class.getName())
                .setSourceMetricsCategory(getMetricsCategory())
                .launch();
        openSubSettings(ToggleAccessibilityServicePreferenceFragment.class.getName(),
                buildArguments(info));
        finish();
        return true;
    }

    @VisibleForTesting
    void openAccessibilityDetailsSettingsAndFinish(Bundle arguments) {
    private void openSubSettings(@NonNull String destination, @Nullable Bundle arguments) {
        new SubSettingLauncher(getActivity())
                .setDestination(ToggleAccessibilityServicePreferenceFragment.class.getName())
                .setDestination(destination)
                .setSourceMetricsCategory(getMetricsCategory())
                .setArguments(arguments)
                .launch();
        finish();
    }

    @VisibleForTesting
@@ -175,4 +214,13 @@ public class AccessibilityDetailsSettingsFragment extends InstrumentedFragment {
        }
        activity.finish();
    }

    private static class LaunchFragmentArguments {
        final String mDestination;
        final Bundle mArguments;
        LaunchFragmentArguments(@NonNull String destination, @Nullable Bundle arguments) {
            mDestination = Objects.requireNonNull(destination);
            mArguments = arguments;
        }
    }
}
+44 −8
Original line number Diff line number Diff line
@@ -16,6 +16,10 @@

package com.android.settings.accessibility;

import static com.android.internal.accessibility.AccessibilityShortcutController.MAGNIFICATION_COMPONENT_NAME;

import static com.google.common.truth.Truth.assertThat;

import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.spy;
@@ -33,11 +37,14 @@ import android.view.accessibility.AccessibilityManager;

import androidx.fragment.app.FragmentActivity;

import com.android.settings.SettingsActivity;
import com.android.settings.testutils.shadow.ShadowFragment;

import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.ArgumentCaptor;
import org.mockito.Captor;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.robolectric.RobolectricTestRunner;
@@ -61,6 +68,8 @@ public class AccessibilityDetailsSettingsFragmentTest {
    private Context mContext;
    private AccessibilityDetailsSettingsFragment mFragment;
    private ShadowAccessibilityManager mShadowAccessibilityManager;
    @Captor
    private ArgumentCaptor<Intent> mIntentArgumentCaptor;
    @Mock private FragmentActivity mActivity;

    @Before
@@ -76,39 +85,43 @@ public class AccessibilityDetailsSettingsFragmentTest {
    }

    @Test
    public void onCreate_hasValidExtraComponentName_shouldOpenAccessibilityDetailsSettings() {
    public void onCreate_hasValidExtraComponentName_launchExpectedFragmentAndFinish() {
        final Intent intent = new Intent();
        intent.putExtra(Intent.EXTRA_COMPONENT_NAME, COMPONENT_NAME);
        doReturn(intent).when(mActivity).getIntent();

        mFragment.onCreate(Bundle.EMPTY);

        verify(mFragment).openAccessibilityDetailsSettingsAndFinish(any());
        assertStartActivityWithExpectedFragment(mActivity,
                ToggleAccessibilityServicePreferenceFragment.class.getName());
        verify(mActivity).finish();
    }

    @Test
    public void onCreate_hasInvalidExtraComponentName_shouldOpenAccessibilityServicesList() {
    public void onCreate_hasInvalidExtraComponentName_launchAccessibilitySettingsAndFinish() {
        final Intent intent = new Intent();
        intent.putExtra(Intent.EXTRA_COMPONENT_NAME, PACKAGE_NAME + "/.service");
        doReturn(intent).when(mActivity).getIntent();

        mFragment.onCreate(Bundle.EMPTY);

        verify(mFragment).openAccessibilitySettingsAndFinish();
        assertStartActivityWithExpectedFragment(mActivity, AccessibilitySettings.class.getName());
        verify(mActivity).finish();
    }

    @Test
    public void onCreate_hasNoExtraComponentName_shouldOpenAccessibilityServicesList() {
    public void onCreate_hasNoExtraComponentName_launchAccessibilitySettingsAndFinish() {
        final Intent intent = new Intent();
        doReturn(intent).when(mActivity).getIntent();

        mFragment.onCreate(Bundle.EMPTY);

        verify(mFragment).openAccessibilitySettingsAndFinish();
        assertStartActivityWithExpectedFragment(mActivity, AccessibilitySettings.class.getName());
        verify(mActivity).finish();
    }

    @Test
    public void onCreate_extraComponentNameIsDisallowed_shouldOpenAccessibilityServicesList() {
    public void onCreate_extraComponentNameIsDisallowed_launchAccessibilitySettingsAndFinish() {
        final Intent intent = new Intent();
        intent.putExtra(Intent.EXTRA_COMPONENT_NAME, COMPONENT_NAME);
        doReturn(intent).when(mActivity).getIntent();
@@ -116,7 +129,23 @@ public class AccessibilityDetailsSettingsFragmentTest {

        mFragment.onCreate(Bundle.EMPTY);

        verify(mFragment).openAccessibilitySettingsAndFinish();
        assertStartActivityWithExpectedFragment(mActivity, AccessibilitySettings.class.getName());
        verify(mActivity).finish();
    }

    @Test
    public void onCreate_magnificationComponentName_launchMagnificationFragmentAndFinish() {
        final Intent intent = new Intent();
        intent.putExtra(Intent.EXTRA_COMPONENT_NAME,
                MAGNIFICATION_COMPONENT_NAME.flattenToString());
        doReturn(intent).when(mActivity).getIntent();

        mFragment.onCreate(Bundle.EMPTY);


        assertStartActivityWithExpectedFragment(mActivity,
                ToggleScreenMagnificationPreferenceFragment.class.getName());
        verify(mActivity).finish();
    }

    private AccessibilityServiceInfo getMockAccessibilityServiceInfo() {
@@ -148,4 +177,11 @@ public class AccessibilityDetailsSettingsFragmentTest {
        infoList.add(getMockAccessibilityServiceInfo());
        return infoList;
    }

    private void assertStartActivityWithExpectedFragment(Context mockContext, String fragmentName) {
        verify(mockContext).startActivity(mIntentArgumentCaptor.capture());
        assertThat(mIntentArgumentCaptor.getValue()
                .getStringExtra(SettingsActivity.EXTRA_SHOW_FRAGMENT))
                .isEqualTo(fragmentName);
    }
}