Merge "Implement ComplicationTypesUpdater."
This commit is contained in:
committed by
Android (Google) Code Review
commit
a30e852c40
@@ -31,10 +31,8 @@ import androidx.lifecycle.ViewModelStore;
|
||||
import com.android.internal.policy.PhoneWindow;
|
||||
import com.android.keyguard.KeyguardUpdateMonitor;
|
||||
import com.android.keyguard.KeyguardUpdateMonitorCallback;
|
||||
import com.android.settingslib.dream.DreamBackend;
|
||||
import com.android.systemui.dagger.qualifiers.Main;
|
||||
import com.android.systemui.dreams.complication.Complication;
|
||||
import com.android.systemui.dreams.complication.ComplicationUtils;
|
||||
import com.android.systemui.dreams.dagger.DreamOverlayComponent;
|
||||
import com.android.systemui.dreams.touch.DreamOverlayTouchMonitor;
|
||||
|
||||
@@ -59,7 +57,6 @@ public class DreamOverlayService extends android.service.dreams.DreamOverlayServ
|
||||
// content area).
|
||||
private final DreamOverlayContainerViewController mDreamOverlayContainerViewController;
|
||||
private final KeyguardUpdateMonitor mKeyguardUpdateMonitor;
|
||||
private final DreamBackend mDreamBackend;
|
||||
|
||||
// A reference to the {@link Window} used to hold the dream overlay.
|
||||
private Window mWindow;
|
||||
@@ -112,7 +109,6 @@ public class DreamOverlayService extends android.service.dreams.DreamOverlayServ
|
||||
setCurrentState(Lifecycle.State.CREATED);
|
||||
mLifecycleRegistry = component.getLifecycleRegistry();
|
||||
mDreamOverlayTouchMonitor = component.getDreamOverlayTouchMonitor();
|
||||
mDreamBackend = component.getDreamBackend();
|
||||
mDreamOverlayTouchMonitor.init();
|
||||
}
|
||||
|
||||
@@ -136,9 +132,6 @@ public class DreamOverlayService extends android.service.dreams.DreamOverlayServ
|
||||
public void onStartDream(@NonNull WindowManager.LayoutParams layoutParams) {
|
||||
setCurrentState(Lifecycle.State.STARTED);
|
||||
mExecutor.execute(() -> {
|
||||
mStateController.setAvailableComplicationTypes(
|
||||
ComplicationUtils.convertComplicationTypes(
|
||||
mDreamBackend.getEnabledComplications()));
|
||||
addOverlayWindowLocked(layoutParams);
|
||||
setCurrentState(Lifecycle.State.RESUMED);
|
||||
mStateController.setOverlayActive(true);
|
||||
|
||||
@@ -0,0 +1,85 @@
|
||||
/*
|
||||
* 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.systemui.dreams.complication;
|
||||
|
||||
import android.content.Context;
|
||||
import android.database.ContentObserver;
|
||||
import android.os.UserHandle;
|
||||
import android.provider.Settings;
|
||||
|
||||
import com.android.settingslib.dream.DreamBackend;
|
||||
import com.android.systemui.CoreStartable;
|
||||
import com.android.systemui.dagger.SysUISingleton;
|
||||
import com.android.systemui.dagger.qualifiers.Main;
|
||||
import com.android.systemui.dreams.DreamOverlayStateController;
|
||||
import com.android.systemui.util.settings.SecureSettings;
|
||||
|
||||
import java.util.concurrent.Executor;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
/**
|
||||
* {@link ComplicationTypesUpdater} observes the state of available complication types set by the
|
||||
* user, and pushes updates to {@link DreamOverlayStateController}.
|
||||
*/
|
||||
@SysUISingleton
|
||||
public class ComplicationTypesUpdater extends CoreStartable {
|
||||
private final DreamBackend mDreamBackend;
|
||||
private final Executor mExecutor;
|
||||
private final SecureSettings mSecureSettings;
|
||||
|
||||
private final DreamOverlayStateController mDreamOverlayStateController;
|
||||
|
||||
@Inject
|
||||
ComplicationTypesUpdater(Context context,
|
||||
DreamBackend dreamBackend,
|
||||
@Main Executor executor,
|
||||
SecureSettings secureSettings,
|
||||
DreamOverlayStateController dreamOverlayStateController) {
|
||||
super(context);
|
||||
|
||||
mDreamBackend = dreamBackend;
|
||||
mExecutor = executor;
|
||||
mSecureSettings = secureSettings;
|
||||
mDreamOverlayStateController = dreamOverlayStateController;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void start() {
|
||||
final ContentObserver settingsObserver = new ContentObserver(null /*handler*/) {
|
||||
@Override
|
||||
public void onChange(boolean selfChange) {
|
||||
mExecutor.execute(() -> mDreamOverlayStateController.setAvailableComplicationTypes(
|
||||
getAvailableComplicationTypes()));
|
||||
}
|
||||
};
|
||||
|
||||
mSecureSettings.registerContentObserverForUser(
|
||||
Settings.Secure.SCREENSAVER_ENABLED_COMPLICATIONS,
|
||||
settingsObserver,
|
||||
UserHandle.myUserId());
|
||||
settingsObserver.onChange(false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns complication types that are currently available by user setting.
|
||||
*/
|
||||
@Complication.ComplicationType
|
||||
private int getAvailableComplicationTypes() {
|
||||
return ComplicationUtils.convertComplicationTypes(mDreamBackend.getEnabledComplications());
|
||||
}
|
||||
}
|
||||
@@ -16,10 +16,14 @@
|
||||
|
||||
package com.android.systemui.dreams.dagger;
|
||||
|
||||
import android.content.Context;
|
||||
|
||||
import com.android.settingslib.dream.DreamBackend;
|
||||
import com.android.systemui.dreams.complication.dagger.RegisteredComplicationsModule;
|
||||
import com.android.systemui.dreams.touch.dagger.DreamTouchModule;
|
||||
|
||||
import dagger.Module;
|
||||
import dagger.Provides;
|
||||
|
||||
/**
|
||||
* Dagger Module providing Communal-related functionality.
|
||||
@@ -32,4 +36,11 @@ import dagger.Module;
|
||||
DreamOverlayComponent.class,
|
||||
})
|
||||
public interface DreamModule {
|
||||
/**
|
||||
* Provides an instance of the dream backend.
|
||||
*/
|
||||
@Provides
|
||||
static DreamBackend providesDreamBackend(Context context) {
|
||||
return DreamBackend.getInstance(context);
|
||||
}
|
||||
}
|
||||
@@ -22,7 +22,6 @@ import androidx.lifecycle.LifecycleOwner;
|
||||
import androidx.lifecycle.LifecycleRegistry;
|
||||
import androidx.lifecycle.ViewModelStore;
|
||||
|
||||
import com.android.settingslib.dream.DreamBackend;
|
||||
import com.android.systemui.dreams.DreamOverlayContainerViewController;
|
||||
import com.android.systemui.dreams.complication.Complication;
|
||||
import com.android.systemui.dreams.complication.dagger.ComplicationModule;
|
||||
@@ -69,7 +68,4 @@ public interface DreamOverlayComponent {
|
||||
|
||||
/** Builds a {@link DreamOverlayTouchMonitor} */
|
||||
DreamOverlayTouchMonitor getDreamOverlayTouchMonitor();
|
||||
|
||||
/** Builds a ${@link DreamBackend} */
|
||||
DreamBackend getDreamBackend();
|
||||
}
|
||||
|
||||
@@ -17,7 +17,6 @@
|
||||
package com.android.systemui.dreams.dagger;
|
||||
|
||||
import android.content.ContentResolver;
|
||||
import android.content.Context;
|
||||
import android.content.res.Resources;
|
||||
import android.os.Handler;
|
||||
import android.view.LayoutInflater;
|
||||
@@ -28,7 +27,6 @@ import androidx.lifecycle.LifecycleOwner;
|
||||
import androidx.lifecycle.LifecycleRegistry;
|
||||
|
||||
import com.android.internal.util.Preconditions;
|
||||
import com.android.settingslib.dream.DreamBackend;
|
||||
import com.android.systemui.R;
|
||||
import com.android.systemui.battery.BatteryMeterView;
|
||||
import com.android.systemui.battery.BatteryMeterViewController;
|
||||
@@ -149,10 +147,4 @@ public abstract class DreamOverlayModule {
|
||||
static Lifecycle providesLifecycle(LifecycleOwner lifecycleOwner) {
|
||||
return lifecycleOwner.getLifecycle();
|
||||
}
|
||||
|
||||
@Provides
|
||||
@DreamOverlayComponent.DreamOverlayScope
|
||||
static DreamBackend providesDreamBackend(Context context) {
|
||||
return DreamBackend.getInstance(context);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -37,9 +37,7 @@ import androidx.lifecycle.LifecycleRegistry;
|
||||
import androidx.test.filters.SmallTest;
|
||||
|
||||
import com.android.keyguard.KeyguardUpdateMonitor;
|
||||
import com.android.settingslib.dream.DreamBackend;
|
||||
import com.android.systemui.SysuiTestCase;
|
||||
import com.android.systemui.dreams.complication.Complication;
|
||||
import com.android.systemui.dreams.dagger.DreamOverlayComponent;
|
||||
import com.android.systemui.dreams.touch.DreamOverlayTouchMonitor;
|
||||
import com.android.systemui.util.concurrency.FakeExecutor;
|
||||
@@ -53,10 +51,6 @@ import org.junit.runner.RunWith;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.MockitoAnnotations;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
@SmallTest
|
||||
@RunWith(AndroidTestingRunner.class)
|
||||
public class DreamOverlayServiceTest extends SysuiTestCase {
|
||||
@@ -101,9 +95,6 @@ public class DreamOverlayServiceTest extends SysuiTestCase {
|
||||
@Mock
|
||||
DreamOverlayStateController mStateController;
|
||||
|
||||
@Mock
|
||||
DreamBackend mDreamBackend;
|
||||
|
||||
DreamOverlayService mService;
|
||||
|
||||
@Before
|
||||
@@ -119,8 +110,6 @@ public class DreamOverlayServiceTest extends SysuiTestCase {
|
||||
.thenReturn(mLifecycleRegistry);
|
||||
when(mDreamOverlayComponent.getDreamOverlayTouchMonitor())
|
||||
.thenReturn(mDreamOverlayTouchMonitor);
|
||||
when(mDreamOverlayComponent.getDreamBackend())
|
||||
.thenReturn(mDreamBackend);
|
||||
when(mDreamOverlayComponentFactory
|
||||
.create(any(), any()))
|
||||
.thenReturn(mDreamOverlayComponent);
|
||||
@@ -173,26 +162,6 @@ public class DreamOverlayServiceTest extends SysuiTestCase {
|
||||
assertThat(mService.shouldShowComplications()).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSetAvailableComplicationTypes() throws Exception {
|
||||
final Set<Integer> enabledComplications = new HashSet<>(
|
||||
Arrays.asList(DreamBackend.COMPLICATION_TYPE_TIME,
|
||||
DreamBackend.COMPLICATION_TYPE_DATE,
|
||||
DreamBackend.COMPLICATION_TYPE_WEATHER));
|
||||
when(mDreamBackend.getEnabledComplications()).thenReturn(enabledComplications);
|
||||
|
||||
final IBinder proxy = mService.onBind(new Intent());
|
||||
final IDreamOverlay overlay = IDreamOverlay.Stub.asInterface(proxy);
|
||||
|
||||
overlay.startDream(mWindowParams, mDreamOverlayCallback);
|
||||
mMainExecutor.runAllReady();
|
||||
|
||||
final int expectedTypes =
|
||||
Complication.COMPLICATION_TYPE_TIME | Complication.COMPLICATION_TYPE_DATE
|
||||
| Complication.COMPLICATION_TYPE_WEATHER;
|
||||
verify(mStateController).setAvailableComplicationTypes(expectedTypes);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDestroy() {
|
||||
mService.onDestroy();
|
||||
|
||||
@@ -0,0 +1,113 @@
|
||||
/*
|
||||
* 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.systemui.dreams.complication;
|
||||
|
||||
import static org.mockito.ArgumentMatchers.anyInt;
|
||||
import static org.mockito.ArgumentMatchers.eq;
|
||||
import static org.mockito.Mockito.never;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import android.content.Context;
|
||||
import android.database.ContentObserver;
|
||||
import android.os.UserHandle;
|
||||
import android.provider.Settings;
|
||||
import android.testing.AndroidTestingRunner;
|
||||
|
||||
import androidx.test.filters.SmallTest;
|
||||
|
||||
import com.android.settingslib.dream.DreamBackend;
|
||||
import com.android.systemui.SysuiTestCase;
|
||||
import com.android.systemui.dreams.DreamOverlayStateController;
|
||||
import com.android.systemui.util.concurrency.FakeExecutor;
|
||||
import com.android.systemui.util.settings.SecureSettings;
|
||||
import com.android.systemui.util.time.FakeSystemClock;
|
||||
|
||||
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 java.util.Arrays;
|
||||
import java.util.HashSet;
|
||||
|
||||
@SmallTest
|
||||
@RunWith(AndroidTestingRunner.class)
|
||||
public class ComplicationTypesUpdaterTest extends SysuiTestCase {
|
||||
@Mock
|
||||
private Context mContext;
|
||||
@Mock
|
||||
private DreamBackend mDreamBackend;
|
||||
@Mock
|
||||
private SecureSettings mSecureSettings;
|
||||
@Mock
|
||||
private DreamOverlayStateController mDreamOverlayStateController;
|
||||
@Captor
|
||||
private ArgumentCaptor<ContentObserver> mSettingsObserverCaptor;
|
||||
|
||||
private final FakeExecutor mExecutor = new FakeExecutor(new FakeSystemClock());
|
||||
|
||||
private ComplicationTypesUpdater mController;
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
MockitoAnnotations.initMocks(this);
|
||||
when(mDreamBackend.getEnabledComplications()).thenReturn(new HashSet<>());
|
||||
|
||||
mController = new ComplicationTypesUpdater(mContext, mDreamBackend, mExecutor,
|
||||
mSecureSettings, mDreamOverlayStateController);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testPushUpdateToDreamOverlayStateControllerImmediatelyOnStart() {
|
||||
// DreamOverlayStateController shouldn't be updated before start().
|
||||
verify(mDreamOverlayStateController, never()).setAvailableComplicationTypes(anyInt());
|
||||
|
||||
mController.start();
|
||||
mExecutor.runAllReady();
|
||||
|
||||
// DreamOverlayStateController updated immediately on start().
|
||||
verify(mDreamOverlayStateController).setAvailableComplicationTypes(anyInt());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testPushUpdateToDreamOverlayStateControllerOnChange() {
|
||||
mController.start();
|
||||
mExecutor.runAllReady();
|
||||
|
||||
when(mDreamBackend.getEnabledComplications()).thenReturn(new HashSet<>(Arrays.asList(
|
||||
DreamBackend.COMPLICATION_TYPE_TIME, DreamBackend.COMPLICATION_TYPE_WEATHER,
|
||||
DreamBackend.COMPLICATION_TYPE_AIR_QUALITY)));
|
||||
final ContentObserver settingsObserver = captureSettingsObserver();
|
||||
settingsObserver.onChange(false);
|
||||
mExecutor.runAllReady();
|
||||
|
||||
verify(mDreamOverlayStateController).setAvailableComplicationTypes(
|
||||
Complication.COMPLICATION_TYPE_TIME | Complication.COMPLICATION_TYPE_WEATHER
|
||||
| Complication.COMPLICATION_TYPE_AIR_QUALITY);
|
||||
}
|
||||
|
||||
private ContentObserver captureSettingsObserver() {
|
||||
verify(mSecureSettings).registerContentObserverForUser(
|
||||
eq(Settings.Secure.SCREENSAVER_ENABLED_COMPLICATIONS),
|
||||
mSettingsObserverCaptor.capture(), eq(UserHandle.myUserId()));
|
||||
return mSettingsObserverCaptor.getValue();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user