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

Commit d822ade4 authored by Riley Jones's avatar Riley Jones Committed by Android (Google) Code Review
Browse files

Merge "Drag-to-edit closes quick settings when going to the edit shortcut screen." into main

parents 4ec6f064 ea5f5bb2
Loading
Loading
Loading
Loading
+0 −40
Original line number Diff line number Diff line
@@ -21,17 +21,10 @@ import static android.view.ViewGroup.LayoutParams.WRAP_CONTENT;
import android.annotation.SuppressLint;
import android.content.ComponentCallbacks;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.content.res.Configuration;
import android.graphics.PointF;
import android.graphics.Rect;
import android.graphics.drawable.GradientDrawable;
import android.os.Bundle;
import android.os.UserHandle;
import android.provider.Settings;
import android.provider.SettingsStringUtil;
import android.view.ViewGroup;
import android.view.ViewTreeObserver;
import android.widget.FrameLayout;
@@ -434,22 +427,6 @@ class MenuView extends FrameLayout implements
        onPositionChanged();
    }

    void gotoEditScreen() {
        if (!Flags.floatingMenuDragToEdit()) {
            return;
        }
        mMenuAnimationController.flingMenuThenSpringToEdge(
                getMenuPosition().x, 100f, 0f);

        Intent intent = getIntentForEditScreen();
        PackageManager packageManager = getContext().getPackageManager();
        List<ResolveInfo> activities = packageManager.queryIntentActivities(intent,
                PackageManager.ResolveInfoFlags.of(PackageManager.MATCH_DEFAULT_ONLY));
        if (!activities.isEmpty()) {
            mContext.startActivity(intent);
        }
    }

    void incrementTexMetricForAllTargets(String metric) {
        if (!Flags.floatingMenuDragToEdit()) {
            return;
@@ -464,23 +441,6 @@ class MenuView extends FrameLayout implements
        Counter.logIncrementWithUid(metric, uid);
    }

    Intent getIntentForEditScreen() {
        List<String> targets = new SettingsStringUtil.ColonDelimitedSet.OfStrings(
                mSecureSettings.getStringForUser(
                        Settings.Secure.ACCESSIBILITY_BUTTON_TARGETS,
                        UserHandle.USER_CURRENT)).stream().toList();

        Intent intent = new Intent(
                Settings.ACTION_ACCESSIBILITY_SHORTCUT_SETTINGS);
        Bundle args = new Bundle();
        Bundle fragmentArgs = new Bundle();
        fragmentArgs.putStringArray("targets", targets.toArray(new String[0]));
        args.putBundle(":settings:show_fragment_args", fragmentArgs);
        intent.replaceExtras(args);
        intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP);
        return intent;
    }

    private InstantInsetLayerDrawable getContainerViewInsetLayer() {
        return (InstantInsetLayerDrawable) getBackground();
    }
+42 −1
Original line number Diff line number Diff line
@@ -36,19 +36,24 @@ import android.annotation.IntDef;
import android.annotation.StringDef;
import android.annotation.SuppressLint;
import android.app.NotificationManager;
import android.app.StatusBarManager;
import android.content.BroadcastReceiver;
import android.content.ComponentCallbacks;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.content.res.Configuration;
import android.content.res.Resources;
import android.graphics.Rect;
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.os.UserHandle;
import android.provider.Settings;
import android.provider.SettingsStringUtil;
import android.util.ArraySet;
import android.view.MotionEvent;
import android.view.View;
@@ -120,6 +125,7 @@ class MenuViewLayer extends FrameLayout implements
    private final MenuAnimationController mMenuAnimationController;
    private final AccessibilityManager mAccessibilityManager;
    private final NotificationManager mNotificationManager;
    private StatusBarManager mStatusBarManager;
    private final MenuNotificationFactory mNotificationFactory;
    private final Handler mHandler = new Handler(Looper.getMainLooper());
    private final IAccessibilityFloatingMenu mFloatingMenu;
@@ -246,6 +252,7 @@ class MenuViewLayer extends FrameLayout implements
        mDismissView.getCircle().setId(R.id.action_remove_menu);
        mNotificationFactory = new MenuNotificationFactory(context);
        mNotificationManager = context.getSystemService(NotificationManager.class);
        mStatusBarManager = context.getSystemService(StatusBarManager.class);

        if (Flags.floatingMenuDragToEdit()) {
            mDragToInteractAnimationController = new DragToInteractAnimationController(
@@ -488,7 +495,7 @@ class MenuViewLayer extends FrameLayout implements
            mMenuView.incrementTexMetricForAllTargets(TEX_METRIC_DISMISS);
        } else if (id == R.id.action_edit
                && Flags.floatingMenuDragToEdit()) {
            mMenuView.gotoEditScreen();
            gotoEditScreen();
            mMenuView.incrementTexMetricForAllTargets(TEX_METRIC_EDIT);
        }
        mDismissView.hide();
@@ -497,6 +504,40 @@ class MenuViewLayer extends FrameLayout implements
                id, /* scaleUp= */ false);
    }

    void gotoEditScreen() {
        if (!Flags.floatingMenuDragToEdit()) {
            return;
        }
        mMenuAnimationController.flingMenuThenSpringToEdge(
                mMenuView.getMenuPosition().x, 100f, 0f);

        Intent intent = getIntentForEditScreen();
        PackageManager packageManager = getContext().getPackageManager();
        List<ResolveInfo> activities = packageManager.queryIntentActivities(intent,
                PackageManager.ResolveInfoFlags.of(PackageManager.MATCH_DEFAULT_ONLY));
        if (!activities.isEmpty()) {
            mContext.startActivity(intent);
            mStatusBarManager.collapsePanels();
        }
    }

    Intent getIntentForEditScreen() {
        List<String> targets = new SettingsStringUtil.ColonDelimitedSet.OfStrings(
                mSecureSettings.getStringForUser(
                        Settings.Secure.ACCESSIBILITY_BUTTON_TARGETS,
                        UserHandle.USER_CURRENT)).stream().toList();

        Intent intent = new Intent(
                Settings.ACTION_ACCESSIBILITY_SHORTCUT_SETTINGS);
        Bundle args = new Bundle();
        Bundle fragmentArgs = new Bundle();
        fragmentArgs.putStringArray("targets", targets.toArray(new String[0]));
        args.putBundle(":settings:show_fragment_args", fragmentArgs);
        intent.replaceExtras(args);
        intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP);
        return intent;
    }

    private CharSequence getMigrationMessage() {
        final Intent intent = new Intent(Settings.ACTION_ACCESSIBILITY_DETAILS_SETTINGS);
        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+1 −1
Original line number Diff line number Diff line
@@ -90,12 +90,12 @@ public class MenuItemAccessibilityDelegateTest extends SysuiTestCase {
        mMenuView = spy(new MenuView(mContext, stubMenuViewModel, stubMenuViewAppearance,
                mSecureSettings));
        mMenuView.setTranslationY(halfScreenHeight);
        doNothing().when(mMenuView).gotoEditScreen();

        mMenuViewLayer = spy(new MenuViewLayer(
                mContext, stubWindowManager, mAccessibilityManager,
                stubMenuViewModel, stubMenuViewAppearance, mMenuView,
                mock(IAccessibilityFloatingMenu.class), mSecureSettings));
        doNothing().when(mMenuViewLayer).gotoEditScreen();

        doReturn(mDraggableBounds).when(mMenuView).getMenuDraggableBounds();
        mStubListView = new RecyclerView(mContext);
+42 −4
Original line number Diff line number Diff line
@@ -35,6 +35,7 @@ import static org.mockito.Mockito.doNothing;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.eq;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
@@ -49,6 +50,7 @@ import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.content.pm.ServiceInfo;
import android.graphics.Insets;
@@ -136,6 +138,8 @@ public class MenuViewLayerTest extends SysuiTestCase {
    private WindowManager mStubWindowManager;
    @Mock
    private AccessibilityManager mStubAccessibilityManager;
    @Mock
    private PackageManager mMockPackageManager;
    private final SecureSettings mSecureSettings = TestUtils.mockSecureSettings();

    private final NotificationManager mMockNotificationManager = mock(NotificationManager.class);
@@ -162,14 +166,15 @@ public class MenuViewLayerTest extends SysuiTestCase {
                new MenuView(mSpyContext, mMenuViewModel, menuViewAppearance, mSecureSettings));
        // Ensure tests don't actually update metrics.
        doNothing().when(mMenuView).incrementTexMetric(any(), anyInt());
        doNothing().when(mMenuView).gotoEditScreen();

        mMenuViewLayer = spy(new MenuViewLayer(mSpyContext, mStubWindowManager,
                mStubAccessibilityManager, mMenuViewModel, menuViewAppearance, mMenuView,
                mFloatingMenu, mSecureSettings));
        mMenuView = (MenuView) mMenuViewLayer.getChildAt(LayerIndex.MENU_VIEW);
        mMenuAnimationController = mMenuView.getMenuAnimationController();

        doNothing().when(mSpyContext).startActivity(any());
        when(mSpyContext.getPackageManager()).thenReturn(mMockPackageManager);

        mLastAccessibilityButtonTargets =
                Settings.Secure.getStringForUser(mSpyContext.getContentResolver(),
                        Settings.Secure.ACCESSIBILITY_BUTTON_TARGETS, UserHandle.USER_CURRENT);
@@ -277,9 +282,31 @@ public class MenuViewLayerTest extends SysuiTestCase {

    @Test
    @EnableFlags(Flags.FLAG_FLOATING_MENU_DRAG_TO_EDIT)
    public void onEditAction_gotoEditScreen_isCalled() {
    public void onEditAction_startsActivity() {
        mockActivityQuery(true);
        mMenuViewLayer.dispatchAccessibilityAction(R.id.action_edit);
        ArgumentCaptor<Intent> intentCaptor = ArgumentCaptor.forClass(Intent.class);
        verify(mSpyContext).startActivity(intentCaptor.capture());
        assertThat(intentCaptor.getValue().getAction()).isEqualTo(
                mMenuViewLayer.getIntentForEditScreen().getAction());
    }

    @Test
    @EnableFlags(Flags.FLAG_FLOATING_MENU_DRAG_TO_EDIT)
    public void onEditAction_noResolve_doesNotStart() {
        mockActivityQuery(false);
        mMenuViewLayer.dispatchAccessibilityAction(R.id.action_edit);
        verify(mMenuView).gotoEditScreen();
        verify(mSpyContext, never()).startActivity(any());
    }

    @Test
    public void getIntentForEditScreen_validate() {
        Intent intent = mMenuViewLayer.getIntentForEditScreen();
        String[] targets = intent.getBundleExtra(
                ":settings:show_fragment_args").getStringArray("targets");

        assertThat(intent.getAction()).isEqualTo(Settings.ACTION_ACCESSIBILITY_SHORTCUT_SETTINGS);
        assertThat(targets).asList().containsExactlyElementsIn(TestUtils.TEST_BUTTON_TARGETS);
    }

    @Test
@@ -500,4 +527,15 @@ public class MenuViewLayerTest extends SysuiTestCase {
        magnetListener.onReleasedInTarget(
                new MagnetizedObject.MagneticTarget(view, 200), mock(MagnetizedObject.class));
    }

    private void mockActivityQuery(boolean successfulQuery) {
        // Query just needs to return a non-empty set to be successful.
        ArrayList<ResolveInfo> resolveInfos = new ArrayList<>();
        if (successfulQuery) {
            resolveInfos.add(new ResolveInfo());
        }
        when(mMockPackageManager.queryIntentActivities(
                any(), any(PackageManager.ResolveInfoFlags.class))).thenReturn(resolveInfos);
    }

}
+0 −47
Original line number Diff line number Diff line
@@ -22,19 +22,13 @@ import static com.google.common.truth.Truth.assertThat;

import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.doNothing;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;

import android.app.UiModeManager;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.graphics.Rect;
import android.graphics.drawable.GradientDrawable;
import android.platform.test.annotations.EnableFlags;
import android.provider.Settings;
import android.testing.AndroidTestingRunner;
import android.testing.TestableLooper;
import android.view.WindowManager;
@@ -58,8 +52,6 @@ import org.mockito.Mock;
import org.mockito.junit.MockitoJUnit;
import org.mockito.junit.MockitoRule;

import java.util.ArrayList;

/** Tests for {@link MenuView}. */
@RunWith(AndroidTestingRunner.class)
@TestableLooper.RunWithLooper(setAsMainLooper = true)
@@ -79,8 +71,6 @@ public class MenuViewTest extends SysuiTestCase {
    private AccessibilityManager mAccessibilityManager;

    private SysuiTestableContext mSpyContext;
    @Mock
    private PackageManager mMockPackageManager;

    @Before
    public void setUp() throws Exception {
@@ -91,7 +81,6 @@ public class MenuViewTest extends SysuiTestCase {
        mSpyContext = spy(mContext);
        doNothing().when(mSpyContext).startActivity(any());

        when(mSpyContext.getPackageManager()).thenReturn(mMockPackageManager);
        final SecureSettings secureSettings = TestUtils.mockSecureSettings();
        final MenuViewModel stubMenuViewModel = new MenuViewModel(mContext, mAccessibilityManager,
                secureSettings);
@@ -178,32 +167,6 @@ public class MenuViewTest extends SysuiTestCase {
        assertThat(radiiAnimator.isStarted()).isTrue();
    }

    @Test
    public void getIntentForEditScreen_validate() {
        Intent intent = mMenuView.getIntentForEditScreen();
        String[] targets = intent.getBundleExtra(
                ":settings:show_fragment_args").getStringArray("targets");

        assertThat(intent.getAction()).isEqualTo(Settings.ACTION_ACCESSIBILITY_SHORTCUT_SETTINGS);
        assertThat(targets).asList().containsExactlyElementsIn(TestUtils.TEST_BUTTON_TARGETS);
    }

    @Test
    @EnableFlags(Flags.FLAG_FLOATING_MENU_DRAG_TO_EDIT)
    public void gotoEditScreen_sendsIntent() {
        mockActivityQuery(true);
        mMenuView.gotoEditScreen();
        verify(mSpyContext).startActivity(any());
    }

    @Test
    @EnableFlags(Flags.FLAG_FLOATING_MENU_DRAG_TO_EDIT)
    public void gotoEditScreen_noResolve_doesNotStart() {
        mockActivityQuery(false);
        mMenuView.gotoEditScreen();
        verify(mSpyContext, never()).startActivity(any());
    }

    private InstantInsetLayerDrawable getMenuViewInsetLayer() {
        return (InstantInsetLayerDrawable) mMenuView.getBackground();
    }
@@ -226,14 +189,4 @@ public class MenuViewTest extends SysuiTestCase {
        mUiModeManager.setNightMode(mNightMode);
        Prefs.putString(mContext, Prefs.Key.ACCESSIBILITY_FLOATING_MENU_POSITION, mLastPosition);
    }

    private void mockActivityQuery(boolean successfulQuery) {
        // Query just needs to return a non-empty set to be successful.
        ArrayList<ResolveInfo> resolveInfos = new ArrayList<>();
        if (successfulQuery) {
            resolveInfos.add(new ResolveInfo());
        }
        when(mMockPackageManager.queryIntentActivities(
                any(), any(PackageManager.ResolveInfoFlags.class))).thenReturn(resolveInfos);
    }
}