From cf72270a2ea1cfaa53882e518994387532f5baca Mon Sep 17 00:00:00 2001 From: Matt Pietal Date: Tue, 13 Apr 2021 09:59:30 -0400 Subject: [PATCH] QS Wallet priority placement If the wallet service is available at all, move the tile into a priority position so it is easily visible to users. Fixes: 183024893 Test: atest AutoTileManagerTest WalletControllerImplTest Change-Id: I8c75dff785555e3ca9d9a68ea3747f4c2fa35188 --- .../QuickAccessWalletServiceInfo.java | 5 +- .../android/systemui/qs/dagger/QSModule.java | 3 + .../statusbar/phone/AutoTileManager.java | 18 ++++++ .../policy/DeviceControlsControllerImpl.kt | 2 +- .../statusbar/policy/WalletController.kt | 25 ++++++++ .../statusbar/policy/WalletControllerImpl.kt | 51 +++++++++++++++ .../policy/dagger/StatusBarPolicyModule.java | 6 ++ .../statusbar/phone/AutoTileManagerTest.java | 17 ++++- .../policy/WalletControllerImplTest.kt | 64 +++++++++++++++++++ 9 files changed, 186 insertions(+), 5 deletions(-) create mode 100644 packages/SystemUI/src/com/android/systemui/statusbar/policy/WalletController.kt create mode 100644 packages/SystemUI/src/com/android/systemui/statusbar/policy/WalletControllerImpl.kt create mode 100644 packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/WalletControllerImplTest.kt diff --git a/core/java/android/service/quickaccesswallet/QuickAccessWalletServiceInfo.java b/core/java/android/service/quickaccesswallet/QuickAccessWalletServiceInfo.java index 5d718440e2da1..c87407e9d38c8 100644 --- a/core/java/android/service/quickaccesswallet/QuickAccessWalletServiceInfo.java +++ b/core/java/android/service/quickaccesswallet/QuickAccessWalletServiceInfo.java @@ -98,7 +98,10 @@ class QuickAccessWalletServiceInfo { intent.setPackage(packageName); List resolveInfos = context.getPackageManager().queryIntentServices(intent, - PackageManager.MATCH_DEFAULT_ONLY | PackageManager.GET_META_DATA); + PackageManager.MATCH_DIRECT_BOOT_AWARE + | PackageManager.MATCH_DIRECT_BOOT_UNAWARE + | PackageManager.MATCH_DEFAULT_ONLY + | PackageManager.GET_META_DATA); return resolveInfos.isEmpty() ? null : resolveInfos.get(0).serviceInfo; } diff --git a/packages/SystemUI/src/com/android/systemui/qs/dagger/QSModule.java b/packages/SystemUI/src/com/android/systemui/qs/dagger/QSModule.java index 75a7e8e09afa4..de3be78e5463c 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/dagger/QSModule.java +++ b/packages/SystemUI/src/com/android/systemui/qs/dagger/QSModule.java @@ -34,6 +34,7 @@ import com.android.systemui.statusbar.policy.CastController; import com.android.systemui.statusbar.policy.DataSaverController; import com.android.systemui.statusbar.policy.DeviceControlsController; import com.android.systemui.statusbar.policy.HotspotController; +import com.android.systemui.statusbar.policy.WalletController; import com.android.systemui.util.settings.SecureSettings; import javax.inject.Named; @@ -63,6 +64,7 @@ public interface QSModule { CastController castController, ReduceBrightColorsController reduceBrightColorsController, DeviceControlsController deviceControlsController, + WalletController walletController, @Named(RBC_AVAILABLE) boolean isReduceBrightColorsAvailable) { AutoTileManager manager = new AutoTileManager( context, @@ -77,6 +79,7 @@ public interface QSModule { castController, reduceBrightColorsController, deviceControlsController, + walletController, isReduceBrightColorsAvailable ); manager.init(); diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/AutoTileManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/AutoTileManager.java index 88e5364cd55f5..3dd4a3b9300ee 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/AutoTileManager.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/AutoTileManager.java @@ -39,6 +39,7 @@ import com.android.systemui.statusbar.policy.DataSaverController.Listener; import com.android.systemui.statusbar.policy.DeviceControlsController; import com.android.systemui.statusbar.policy.HotspotController; import com.android.systemui.statusbar.policy.HotspotController.Callback; +import com.android.systemui.statusbar.policy.WalletController; import com.android.systemui.util.UserAwareController; import com.android.systemui.util.settings.SecureSettings; @@ -60,6 +61,7 @@ public class AutoTileManager implements UserAwareController { public static final String NIGHT = "night"; public static final String CAST = "cast"; public static final String DEVICE_CONTROLS = "controls"; + public static final String WALLET = "wallet"; public static final String BRIGHTNESS = "reduce_brightness"; static final String SETTING_SEPARATOR = ":"; @@ -77,6 +79,7 @@ public class AutoTileManager implements UserAwareController { private final NightDisplayListener mNightDisplayListener; private final CastController mCastController; private final DeviceControlsController mDeviceControlsController; + private final WalletController mWalletController; private final ReduceBrightColorsController mReduceBrightColorsController; private final boolean mIsReduceBrightColorsAvailable; private final ArrayList mAutoAddSettingList = new ArrayList<>(); @@ -92,6 +95,7 @@ public class AutoTileManager implements UserAwareController { CastController castController, ReduceBrightColorsController reduceBrightColorsController, DeviceControlsController deviceControlsController, + WalletController walletController, @Named(RBC_AVAILABLE) boolean isReduceBrightColorsAvailable) { mContext = context; mHost = host; @@ -107,6 +111,7 @@ public class AutoTileManager implements UserAwareController { mReduceBrightColorsController = reduceBrightColorsController; mIsReduceBrightColorsAvailable = isReduceBrightColorsAvailable; mDeviceControlsController = deviceControlsController; + mWalletController = walletController; } /** @@ -146,6 +151,9 @@ public class AutoTileManager implements UserAwareController { if (!mAutoTracker.isAdded(DEVICE_CONTROLS)) { mDeviceControlsController.setCallback(mDeviceControlsCallback); } + if (!mAutoTracker.isAdded(WALLET)) { + initWalletController(); + } int settingsN = mAutoAddSettingList.size(); for (int i = 0; i < settingsN; i++) { @@ -294,6 +302,16 @@ public class AutoTileManager implements UserAwareController { } }; + private void initWalletController() { + if (mAutoTracker.isAdded(WALLET)) return; + Integer position = mWalletController.getWalletPosition(); + + if (position != null) { + mHost.addTile(WALLET, position); + mAutoTracker.setTileAdded(WALLET); + } + } + @VisibleForTesting final NightDisplayListener.Callback mNightDisplayCallback = new NightDisplayListener.Callback() { diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/DeviceControlsControllerImpl.kt b/packages/SystemUI/src/com/android/systemui/statusbar/policy/DeviceControlsControllerImpl.kt index d3907ae9a150d..a4fd647ee643b 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/DeviceControlsControllerImpl.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/DeviceControlsControllerImpl.kt @@ -61,7 +61,7 @@ public class DeviceControlsControllerImpl @Inject constructor( companion object { private const val TAG = "DeviceControlsControllerImpl" - internal const val QS_PRIORITY_POSITION = 3 + internal const val QS_PRIORITY_POSITION = 2 internal const val QS_DEFAULT_POSITION = POSITION_AT_END internal const val PREFS_CONTROLS_SEEDING_COMPLETED = "SeedingCompleted" diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/WalletController.kt b/packages/SystemUI/src/com/android/systemui/statusbar/policy/WalletController.kt new file mode 100644 index 0000000000000..eaad477d75e25 --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/WalletController.kt @@ -0,0 +1,25 @@ +/* + * Copyright (C) 2021 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.systemui.statusbar.policy + +/** + * Supports adding a Quick Access Wallet QS tile + */ +interface WalletController { + /** @return valid position or null to indicate no tile should be set */ + fun getWalletPosition(): Int? +} diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/WalletControllerImpl.kt b/packages/SystemUI/src/com/android/systemui/statusbar/policy/WalletControllerImpl.kt new file mode 100644 index 0000000000000..af1284459d63f --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/WalletControllerImpl.kt @@ -0,0 +1,51 @@ +/* + * Copyright (C) 2021 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.systemui.statusbar.policy + +import android.service.quickaccesswallet.QuickAccessWalletClient +import android.util.Log + +import com.android.systemui.dagger.SysUISingleton + +import javax.inject.Inject + +/** + * Check if the wallet service is available for use, and place the tile. + */ +@SysUISingleton +public class WalletControllerImpl @Inject constructor( + private val quickAccessWalletClient: QuickAccessWalletClient +) : WalletController { + + companion object { + private const val TAG = "WalletControllerImpl" + internal const val QS_PRIORITY_POSITION = 2 + } + + /** + * @return QS_PRIORITY_POSITION or null to indicate no tile should be set + */ + override fun getWalletPosition(): Int? { + return if (quickAccessWalletClient.isWalletServiceAvailable()) { + Log.i(TAG, "Setting WalletTile position: $QS_PRIORITY_POSITION") + QS_PRIORITY_POSITION + } else { + Log.i(TAG, "Setting WalletTile position: null") + null + } + } +} diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/dagger/StatusBarPolicyModule.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/dagger/StatusBarPolicyModule.java index 7666022610992..9fb0453a28888 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/dagger/StatusBarPolicyModule.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/dagger/StatusBarPolicyModule.java @@ -48,6 +48,8 @@ import com.android.systemui.statusbar.policy.SecurityController; import com.android.systemui.statusbar.policy.SecurityControllerImpl; import com.android.systemui.statusbar.policy.UserInfoController; import com.android.systemui.statusbar.policy.UserInfoControllerImpl; +import com.android.systemui.statusbar.policy.WalletController; +import com.android.systemui.statusbar.policy.WalletControllerImpl; import com.android.systemui.statusbar.policy.ZenModeController; import com.android.systemui.statusbar.policy.ZenModeControllerImpl; @@ -118,6 +120,10 @@ public interface StatusBarPolicyModule { DeviceControlsController provideDeviceControlsController( DeviceControlsControllerImpl controllerImpl); + /** */ + @Binds + WalletController provideWalletController(WalletControllerImpl controllerImpl); + /** */ @Binds NetworkController.AccessPointController provideAccessPointController( diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/AutoTileManagerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/AutoTileManagerTest.java index ac160d6dd9fb1..3f5d220957cd0 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/AutoTileManagerTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/AutoTileManagerTest.java @@ -30,6 +30,7 @@ import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.inOrder; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.never; +import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; @@ -56,6 +57,7 @@ import com.android.systemui.statusbar.policy.CastController.CastDevice; import com.android.systemui.statusbar.policy.DataSaverController; import com.android.systemui.statusbar.policy.DeviceControlsController; import com.android.systemui.statusbar.policy.HotspotController; +import com.android.systemui.statusbar.policy.WalletController; import com.android.systemui.util.settings.FakeSettings; import com.android.systemui.util.settings.SecureSettings; @@ -95,7 +97,8 @@ public class AutoTileManagerTest extends SysuiTestCase { @Mock private ManagedProfileController mManagedProfileController; @Mock private NightDisplayListener mNightDisplayListener; @Mock private ReduceBrightColorsController mReduceBrightColorsController; - @Mock private DeviceControlsController mDeviceControlsController;; + @Mock private DeviceControlsController mDeviceControlsController; + @Mock private WalletController mWalletController; @Mock(answer = Answers.RETURNS_SELF) private AutoAddTracker.Builder mAutoAddTrackerBuilder; @Mock private Context mUserContext; @@ -142,6 +145,7 @@ public class AutoTileManagerTest extends SysuiTestCase { CastController castController, ReduceBrightColorsController reduceBrightColorsController, DeviceControlsController deviceControlsController, + WalletController walletController, @Named(RBC_AVAILABLE) boolean isReduceBrightColorsAvailable) { return new AutoTileManager(context, autoAddTrackerBuilder, mQsTileHost, Handler.createAsync(TestableLooper.get(this).getLooper()), @@ -153,6 +157,7 @@ public class AutoTileManagerTest extends SysuiTestCase { castController, reduceBrightColorsController, deviceControlsController, + walletController, isReduceBrightColorsAvailable); } @@ -160,7 +165,7 @@ public class AutoTileManagerTest extends SysuiTestCase { return createAutoTileManager(context, mAutoAddTrackerBuilder, mHotspotController, mDataSaverController, mManagedProfileController, mNightDisplayListener, mCastController, mReduceBrightColorsController, mDeviceControlsController, - mIsReduceBrightColorsAvailable); + mWalletController, mIsReduceBrightColorsAvailable); } @Test @@ -175,10 +180,11 @@ public class AutoTileManagerTest extends SysuiTestCase { CastController cC = mock(CastController.class); ReduceBrightColorsController rBC = mock(ReduceBrightColorsController.class); DeviceControlsController dCC = mock(DeviceControlsController.class); + WalletController wC = mock(WalletController.class); AutoTileManager manager = createAutoTileManager(mock(Context.class), builder, hC, dSC, mPC, nDS, cC, rBC, - dCC, true); + dCC, wC, true); verify(tracker, never()).initialize(); verify(hC, never()).addCallback(any()); @@ -188,6 +194,7 @@ public class AutoTileManagerTest extends SysuiTestCase { verify(cC, never()).addCallback(any()); verify(rBC, never()).addCallback(any()); verify(dCC, never()).setCallback(any()); + verify(wC, never()).getWalletPosition(); assertNull(manager.getSecureSettingForKey(TEST_SETTING)); assertNull(manager.getSecureSettingForKey(TEST_SETTING_COMPONENT)); } @@ -240,6 +247,8 @@ public class AutoTileManagerTest extends SysuiTestCase { inOrderDevices.verify(mDeviceControlsController).removeCallback(); inOrderDevices.verify(mDeviceControlsController).setCallback(any()); + verify(mWalletController, times(2)).getWalletPosition(); + SecureSetting setting = mAutoTileManager.getSecureSettingForKey(TEST_SETTING); assertEquals(USER + 1, setting.getCurrentUser()); assertTrue(setting.isListening()); @@ -288,6 +297,8 @@ public class AutoTileManagerTest extends SysuiTestCase { inOrderDevices.verify(mDeviceControlsController).removeCallback(); inOrderDevices.verify(mDeviceControlsController).setCallback(any()); + verify(mWalletController, times(2)).getWalletPosition(); + SecureSetting setting = mAutoTileManager.getSecureSettingForKey(TEST_SETTING); assertEquals(USER + 1, setting.getCurrentUser()); assertFalse(setting.isListening()); diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/WalletControllerImplTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/WalletControllerImplTest.kt new file mode 100644 index 0000000000000..dbc2e3471c287 --- /dev/null +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/WalletControllerImplTest.kt @@ -0,0 +1,64 @@ +/* + * Copyright (C) 2021 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.systemui.statusbar.policy + +import android.service.quickaccesswallet.QuickAccessWalletClient +import android.testing.AndroidTestingRunner + +import androidx.test.filters.SmallTest + +import com.android.systemui.SysuiTestCase +import com.android.systemui.statusbar.policy.DeviceControlsControllerImpl.Companion.QS_PRIORITY_POSITION + +import com.google.common.truth.Truth.assertThat + +import org.junit.Before +import org.junit.Test +import org.junit.runner.RunWith + +import org.mockito.Mock +import org.mockito.MockitoAnnotations +import org.mockito.Mockito.`when` + +@SmallTest +@RunWith(AndroidTestingRunner::class) +class WalletControllerImplTest : SysuiTestCase() { + + @Mock + private lateinit var quickAccessWalletClient: QuickAccessWalletClient + + private lateinit var controller: WalletController + + @Before + fun setUp() { + MockitoAnnotations.initMocks(this) + + controller = WalletControllerImpl(quickAccessWalletClient) + } + + @Test + fun testResultIsNullWhenNoServiceAvailable() { + `when`(quickAccessWalletClient.isWalletServiceAvailable()).thenReturn(false) + assertThat(controller.getWalletPosition()).isNull() + } + + @Test + fun testResultIsIntWhenServiceAvailable() { + `when`(quickAccessWalletClient.isWalletServiceAvailable()).thenReturn(true) + assertThat(controller.getWalletPosition()).isEqualTo(QS_PRIORITY_POSITION) + } +}