diff options
| author | 2020-05-27 20:44:35 +0000 | |
|---|---|---|
| committer | 2020-05-27 20:44:35 +0000 | |
| commit | 0711557c680910d73ea2b3dc1ea72f0a749fdfc0 (patch) | |
| tree | d0b7ce889c1bf177fb184c5c5591da35b9af92f5 | |
| parent | 1e8ce29af70225b9f80300b3770acc4be3b6a523 (diff) | |
| parent | 137951c7b4496ead228fcd193f879098e37de4d2 (diff) | |
Merge "Gate controls controllers with system feature flag" into rvc-dev
9 files changed, 236 insertions, 21 deletions
diff --git a/packages/SystemUI/src/com/android/systemui/controls/dagger/ControlsComponent.kt b/packages/SystemUI/src/com/android/systemui/controls/dagger/ControlsComponent.kt new file mode 100644 index 000000000000..9a5b96078e95 --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/controls/dagger/ControlsComponent.kt @@ -0,0 +1,55 @@ +/* + * Copyright (C) 2020 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.controls.dagger + +import com.android.systemui.controls.controller.ControlsController +import com.android.systemui.controls.management.ControlsListingController +import com.android.systemui.controls.ui.ControlsUiController +import dagger.Lazy +import java.util.Optional +import javax.inject.Inject +import javax.inject.Singleton + +/** + * Pseudo-component to inject into classes outside `com.android.systemui.controls`. + * + * If `featureEnabled` is false, all the optionals should be empty. The controllers will only be + * instantiated if `featureEnabled` is true. + */ +@Singleton +class ControlsComponent @Inject constructor( + @ControlsFeatureEnabled private val featureEnabled: Boolean, + private val lazyControlsController: Lazy<ControlsController>, + private val lazyControlsUiController: Lazy<ControlsUiController>, + private val lazyControlsListingController: Lazy<ControlsListingController> +) { + fun getControlsController(): Optional<ControlsController> { + return if (featureEnabled) Optional.of(lazyControlsController.get()) else Optional.empty() + } + + fun getControlsUiController(): Optional<ControlsUiController> { + return if (featureEnabled) Optional.of(lazyControlsUiController.get()) else Optional.empty() + } + + fun getControlsListingController(): Optional<ControlsListingController> { + return if (featureEnabled) { + Optional.of(lazyControlsListingController.get()) + } else { + Optional.empty() + } + } +}
\ No newline at end of file diff --git a/packages/SystemUI/src/com/android/systemui/controls/dagger/ControlsFeatureEnabled.kt b/packages/SystemUI/src/com/android/systemui/controls/dagger/ControlsFeatureEnabled.kt new file mode 100644 index 000000000000..dd061c526c40 --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/controls/dagger/ControlsFeatureEnabled.kt @@ -0,0 +1,24 @@ +/* + * Copyright (C) 2020 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.controls.dagger + +import javax.inject.Qualifier + +@Qualifier +@MustBeDocumented +@Retention(AnnotationRetention.RUNTIME) +annotation class ControlsFeatureEnabled
\ No newline at end of file diff --git a/packages/SystemUI/src/com/android/systemui/controls/dagger/ControlsModule.kt b/packages/SystemUI/src/com/android/systemui/controls/dagger/ControlsModule.kt index 5765be57b5b0..4760d291072e 100644 --- a/packages/SystemUI/src/com/android/systemui/controls/dagger/ControlsModule.kt +++ b/packages/SystemUI/src/com/android/systemui/controls/dagger/ControlsModule.kt @@ -17,6 +17,7 @@ package com.android.systemui.controls.dagger import android.app.Activity +import android.content.pm.PackageManager import com.android.systemui.controls.controller.ControlsBindingController import com.android.systemui.controls.controller.ControlsBindingControllerImpl import com.android.systemui.controls.controller.ControlsController @@ -28,19 +29,39 @@ import com.android.systemui.controls.management.ControlsListingController import com.android.systemui.controls.management.ControlsListingControllerImpl import com.android.systemui.controls.management.ControlsProviderSelectorActivity import com.android.systemui.controls.management.ControlsRequestDialog -import com.android.systemui.controls.ui.ControlsUiController -import com.android.systemui.controls.ui.ControlsUiControllerImpl import com.android.systemui.controls.ui.ControlActionCoordinator import com.android.systemui.controls.ui.ControlActionCoordinatorImpl +import com.android.systemui.controls.ui.ControlsUiController +import com.android.systemui.controls.ui.ControlsUiControllerImpl import dagger.Binds import dagger.BindsOptionalOf import dagger.Module +import dagger.Provides import dagger.multibindings.ClassKey import dagger.multibindings.IntoMap +import javax.inject.Singleton +/** + * Module for injecting classes in `com.android.systemui.controls`- + * + * Classes provided by this module should only be injected directly into other classes in this + * module. For injecting outside of this module (for example, [GlobalActionsDialog], inject + * [ControlsComponent] and obtain the corresponding optionals from it. + */ @Module abstract class ControlsModule { + @Module + companion object { + @JvmStatic + @Provides + @Singleton + @ControlsFeatureEnabled + fun providesControlsFeatureEnabled(pm: PackageManager): Boolean { + return pm.hasSystemFeature(PackageManager.FEATURE_CONTROLS) + } + } + @Binds abstract fun provideControlsListingController( controller: ControlsListingControllerImpl diff --git a/packages/SystemUI/src/com/android/systemui/controls/management/ControlsRequestReceiver.kt b/packages/SystemUI/src/com/android/systemui/controls/management/ControlsRequestReceiver.kt index 0d23557ffa9e..bf84d77224b1 100644 --- a/packages/SystemUI/src/com/android/systemui/controls/management/ControlsRequestReceiver.kt +++ b/packages/SystemUI/src/com/android/systemui/controls/management/ControlsRequestReceiver.kt @@ -55,6 +55,9 @@ class ControlsRequestReceiver : BroadcastReceiver() { } override fun onReceive(context: Context, intent: Intent) { + if (!context.packageManager.hasSystemFeature(PackageManager.FEATURE_CONTROLS)) { + return + } val packageName = intent.getParcelableExtra<ComponentName>(Intent.EXTRA_COMPONENT_NAME) ?.packageName diff --git a/packages/SystemUI/src/com/android/systemui/controls/ui/ControlsUiControllerImpl.kt b/packages/SystemUI/src/com/android/systemui/controls/ui/ControlsUiControllerImpl.kt index ab3329122edc..606e94760946 100644 --- a/packages/SystemUI/src/com/android/systemui/controls/ui/ControlsUiControllerImpl.kt +++ b/packages/SystemUI/src/com/android/systemui/controls/ui/ControlsUiControllerImpl.kt @@ -60,7 +60,6 @@ import com.android.systemui.dagger.qualifiers.Main import com.android.systemui.globalactions.GlobalActionsPopupMenu import com.android.systemui.plugins.ActivityStarter import com.android.systemui.statusbar.phone.ShadeController -import com.android.systemui.statusbar.policy.KeyguardStateController import com.android.systemui.util.concurrency.DelayableExecutor import dagger.Lazy import java.text.Collator @@ -80,7 +79,6 @@ class ControlsUiControllerImpl @Inject constructor ( @Main val sharedPreferences: SharedPreferences, val controlActionCoordinator: ControlActionCoordinator, private val activityStarter: ActivityStarter, - private val keyguardStateController: KeyguardStateController, private val shadeController: ShadeController ) : ControlsUiController { diff --git a/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsDialog.java b/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsDialog.java index 61c9a967cc4c..d66b9ac3d21a 100644 --- a/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsDialog.java +++ b/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsDialog.java @@ -120,8 +120,8 @@ import com.android.systemui.broadcast.BroadcastDispatcher; import com.android.systemui.colorextraction.SysuiColorExtractor; import com.android.systemui.controls.ControlsServiceInfo; import com.android.systemui.controls.controller.ControlsController; +import com.android.systemui.controls.dagger.ControlsComponent; import com.android.systemui.controls.management.ControlsAnimations; -import com.android.systemui.controls.management.ControlsListingController; import com.android.systemui.controls.ui.ControlsUiController; import com.android.systemui.dagger.qualifiers.Background; import com.android.systemui.dagger.qualifiers.Main; @@ -140,6 +140,7 @@ import com.android.systemui.util.leak.RotationUtils; import java.util.ArrayList; import java.util.List; +import java.util.Optional; import java.util.concurrent.Executor; import javax.inject.Inject; @@ -234,11 +235,12 @@ public class GlobalActionsDialog implements DialogInterface.OnDismissListener, private final IStatusBarService mStatusBarService; private final NotificationShadeWindowController mNotificationShadeWindowController; private GlobalActionsPanelPlugin mWalletPlugin; - private ControlsUiController mControlsUiController; + private Optional<ControlsUiController> mControlsUiControllerOptional; private final IWindowManager mIWindowManager; private final Executor mBackgroundExecutor; private List<ControlsServiceInfo> mControlsServiceInfos = new ArrayList<>(); - private ControlsController mControlsController; + private Optional<ControlsController> mControlsControllerOptional; + private SharedPreferences mControlsPreferences; private final RingerModeTracker mRingerModeTracker; private int mDialogPressDelay = DIALOG_PRESS_DELAY; // ms private Handler mMainHandler; @@ -298,11 +300,11 @@ public class GlobalActionsDialog implements DialogInterface.OnDismissListener, NotificationShadeDepthController depthController, SysuiColorExtractor colorExtractor, IStatusBarService statusBarService, NotificationShadeWindowController notificationShadeWindowController, - ControlsUiController controlsUiController, IWindowManager iWindowManager, + IWindowManager iWindowManager, @Background Executor backgroundExecutor, - ControlsListingController controlsListingController, - ControlsController controlsController, UiEventLogger uiEventLogger, + UiEventLogger uiEventLogger, RingerModeTracker ringerModeTracker, SysUiState sysUiState, @Main Handler handler, + ControlsComponent controlsComponent, CurrentUserContextTracker currentUserContextTracker) { mContext = new ContextThemeWrapper(context, com.android.systemui.R.style.qs_theme); mWindowManagerFuncs = windowManagerFuncs; @@ -325,11 +327,11 @@ public class GlobalActionsDialog implements DialogInterface.OnDismissListener, mSysuiColorExtractor = colorExtractor; mStatusBarService = statusBarService; mNotificationShadeWindowController = notificationShadeWindowController; - mControlsUiController = controlsUiController; + mControlsUiControllerOptional = controlsComponent.getControlsUiController(); mIWindowManager = iWindowManager; mBackgroundExecutor = backgroundExecutor; mRingerModeTracker = ringerModeTracker; - mControlsController = controlsController; + mControlsControllerOptional = controlsComponent.getControlsController(); mSysUiState = sysUiState; mMainHandler = handler; mCurrentUserContextTracker = currentUserContextTracker; @@ -374,7 +376,7 @@ public class GlobalActionsDialog implements DialogInterface.OnDismissListener, mDialog.mWalletViewController.onDeviceLockStateChanged(!unlocked); } if (!mDialog.isShowingControls() && shouldShowControls()) { - mDialog.showControls(mControlsUiController); + mDialog.showControls(mControlsUiControllerOptional.get()); } if (unlocked) { mDialog.hideLockMessage(); @@ -383,7 +385,16 @@ public class GlobalActionsDialog implements DialogInterface.OnDismissListener, } }); - controlsListingController.addCallback(list -> mControlsServiceInfos = list); + if (controlsComponent.getControlsListingController().isPresent()) { + controlsComponent.getControlsListingController().get() + .addCallback(list -> mControlsServiceInfos = list); + } + + // Need to be user-specific with the context to make sure we read the correct prefs + Context userContext = context.createContextAsUser( + new UserHandle(mUserManager.getUserHandle()), 0); + mControlsPreferences = userContext.getSharedPreferences(PREFS_CONTROLS_FILE, + Context.MODE_PRIVATE); // Listen for changes to show controls on the power menu while locked onPowerMenuLockScreenSettingsChanged(); @@ -399,8 +410,9 @@ public class GlobalActionsDialog implements DialogInterface.OnDismissListener, } private void seedFavorites() { + if (!mControlsControllerOptional.isPresent()) return; if (mControlsServiceInfos.isEmpty() - || mControlsController.getFavorites().size() > 0) { + || mControlsControllerOptional.get().getFavorites().size() > 0) { return; } @@ -433,7 +445,7 @@ public class GlobalActionsDialog implements DialogInterface.OnDismissListener, return; } - mControlsController.seedFavoritesForComponent( + mControlsControllerOptional.get().seedFavoritesForComponent( preferredComponent, (accepted) -> { Log.i(TAG, "Controls seeded: " + accepted); @@ -636,10 +648,14 @@ public class GlobalActionsDialog implements DialogInterface.OnDismissListener, mDepthController.setShowingHomeControls(true); GlobalActionsPanelPlugin.PanelViewController walletViewController = getWalletViewController(); + ControlsUiController uiController = null; + if (mControlsUiControllerOptional.isPresent() && shouldShowControls()) { + uiController = mControlsUiControllerOptional.get(); + } ActionsDialog dialog = new ActionsDialog(mContext, mAdapter, mOverflowAdapter, walletViewController, mDepthController, mSysuiColorExtractor, mStatusBarService, mNotificationShadeWindowController, - controlsAvailable(), shouldShowControls() ? mControlsUiController : null, + controlsAvailable(), uiController, mSysUiState, this::onRotate, mKeyguardShowing); boolean walletViewAvailable = walletViewController != null && walletViewController.getPanelContent() != null; @@ -2403,7 +2419,8 @@ public class GlobalActionsDialog implements DialogInterface.OnDismissListener, private boolean controlsAvailable() { return mDeviceProvisioned - && mControlsUiController.getAvailable() + && mControlsUiControllerOptional.isPresent() + && mControlsUiControllerOptional.get().getAvailable() && !mControlsServiceInfos.isEmpty(); } diff --git a/packages/SystemUI/tests/src/com/android/systemui/controls/dagger/ControlsComponentTest.kt b/packages/SystemUI/tests/src/com/android/systemui/controls/dagger/ControlsComponentTest.kt new file mode 100644 index 000000000000..7fe682793152 --- /dev/null +++ b/packages/SystemUI/tests/src/com/android/systemui/controls/dagger/ControlsComponentTest.kt @@ -0,0 +1,81 @@ +/* + * Copyright (C) 2020 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.controls.dagger + +import android.testing.AndroidTestingRunner +import androidx.test.filters.SmallTest +import com.android.systemui.SysuiTestCase +import com.android.systemui.controls.controller.ControlsController +import com.android.systemui.controls.management.ControlsListingController +import com.android.systemui.controls.ui.ControlsUiController +import dagger.Lazy +import org.junit.Assert.assertEquals +import org.junit.Assert.assertFalse +import org.junit.Assert.assertTrue +import org.junit.Before +import org.junit.Test +import org.junit.runner.RunWith +import org.mockito.Mock +import org.mockito.MockitoAnnotations + +@SmallTest +@RunWith(AndroidTestingRunner::class) +class ControlsComponentTest : SysuiTestCase() { + + @Mock + private lateinit var controller: ControlsController + @Mock + private lateinit var uiController: ControlsUiController + @Mock + private lateinit var listingController: ControlsListingController + + @Before + fun setUp() { + MockitoAnnotations.initMocks(this) + } + + @Test + fun testFeatureEnabled() { + val component = ControlsComponent( + true, + Lazy { controller }, + Lazy { uiController }, + Lazy { listingController } + ) + + assertTrue(component.getControlsController().isPresent) + assertEquals(controller, component.getControlsController().get()) + assertTrue(component.getControlsUiController().isPresent) + assertEquals(uiController, component.getControlsUiController().get()) + assertTrue(component.getControlsListingController().isPresent) + assertEquals(listingController, component.getControlsListingController().get()) + } + + @Test + fun testFeatureDisabled() { + val component = ControlsComponent( + false, + Lazy { controller }, + Lazy { uiController }, + Lazy { listingController } + ) + + assertFalse(component.getControlsController().isPresent) + assertFalse(component.getControlsUiController().isPresent) + assertFalse(component.getControlsListingController().isPresent) + } +}
\ No newline at end of file diff --git a/packages/SystemUI/tests/src/com/android/systemui/controls/management/ControlsRequestReceiverTest.kt b/packages/SystemUI/tests/src/com/android/systemui/controls/management/ControlsRequestReceiverTest.kt index 663f011183ab..ee1cc7b1ab71 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/controls/management/ControlsRequestReceiverTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/controls/management/ControlsRequestReceiverTest.kt @@ -66,6 +66,7 @@ class ControlsRequestReceiverTest : SysuiTestCase() { MockitoAnnotations.initMocks(this) mContext.setMockPackageManager(packageManager) + `when`(packageManager.hasSystemFeature(PackageManager.FEATURE_CONTROLS)).thenReturn(true) mContext.addMockSystemService(ActivityManager::class.java, activityManager) receiver = ControlsRequestReceiver() @@ -145,6 +146,14 @@ class ControlsRequestReceiverTest : SysuiTestCase() { } ?: run { fail("Null start intent") } } + @Test + fun testFeatureDisabled_activityNotStarted() { + `when`(packageManager.hasSystemFeature(PackageManager.FEATURE_CONTROLS)).thenReturn(false) + receiver.onReceive(wrapper, intent) + + assertNull(wrapper.intent) + } + class MyWrapper(context: Context) : ContextWrapper(context) { var intent: Intent? = null diff --git a/packages/SystemUI/tests/src/com/android/systemui/globalactions/GlobalActionsDialogTest.java b/packages/SystemUI/tests/src/com/android/systemui/globalactions/GlobalActionsDialogTest.java index 487452b0d26a..32546333aac3 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/globalactions/GlobalActionsDialogTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/globalactions/GlobalActionsDialogTest.java @@ -59,6 +59,7 @@ import com.android.systemui.SysuiTestCase; import com.android.systemui.broadcast.BroadcastDispatcher; import com.android.systemui.colorextraction.SysuiColorExtractor; import com.android.systemui.controls.controller.ControlsController; +import com.android.systemui.controls.dagger.ControlsComponent; import com.android.systemui.controls.management.ControlsListingController; import com.android.systemui.controls.ui.ControlsUiController; import com.android.systemui.model.SysUiState; @@ -121,6 +122,7 @@ public class GlobalActionsDialogTest extends SysuiTestCase { @Mock GlobalActionsPanelPlugin.PanelViewController mWalletController; @Mock private Handler mHandler; @Mock private CurrentUserContextTracker mCurrentUserContextTracker; + private ControlsComponent mControlsComponent; private TestableLooper mTestableLooper; @@ -132,6 +134,13 @@ public class GlobalActionsDialogTest extends SysuiTestCase { when(mRingerModeTracker.getRingerMode()).thenReturn(mRingerModeLiveData); when(mCurrentUserContextTracker.getCurrentUserContext()).thenReturn(mContext); + mControlsComponent = new ControlsComponent( + true, + () -> mControlsController, + () -> mControlsUiController, + () -> mControlsListingController + ); + mGlobalActionsDialog = new GlobalActionsDialog(mContext, mWindowManagerFuncs, mAudioManager, @@ -156,15 +165,13 @@ public class GlobalActionsDialogTest extends SysuiTestCase { mColorExtractor, mStatusBarService, mNotificationShadeWindowController, - mControlsUiController, mWindowManager, mBackgroundExecutor, - mControlsListingController, - mControlsController, mUiEventLogger, mRingerModeTracker, mSysUiState, mHandler, + mControlsComponent, mCurrentUserContextTracker ); mGlobalActionsDialog.setZeroDialogPressDelayForTesting(); |