Merge "Do not allow complications when dream overlay is not enabled." into tm-qpr-dev am: ad91f3b29a
Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/base/+/20695279 Change-Id: I70b887f879b7be0cb52298b85d4a2271c12689d5 Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
This commit is contained in:
@@ -16,6 +16,8 @@
|
|||||||
|
|
||||||
package com.android.systemui.dreams;
|
package com.android.systemui.dreams;
|
||||||
|
|
||||||
|
import static com.android.systemui.dreams.dagger.DreamModule.DREAM_OVERLAY_SERVICE_COMPONENT;
|
||||||
|
|
||||||
import android.content.BroadcastReceiver;
|
import android.content.BroadcastReceiver;
|
||||||
import android.content.ComponentName;
|
import android.content.ComponentName;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
@@ -35,6 +37,7 @@ import com.android.systemui.CoreStartable;
|
|||||||
import com.android.systemui.dagger.qualifiers.Main;
|
import com.android.systemui.dagger.qualifiers.Main;
|
||||||
|
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
|
import javax.inject.Named;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* {@link DreamOverlayRegistrant} is responsible for telling system server that SystemUI should be
|
* {@link DreamOverlayRegistrant} is responsible for telling system server that SystemUI should be
|
||||||
@@ -98,12 +101,13 @@ public class DreamOverlayRegistrant implements CoreStartable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
public DreamOverlayRegistrant(Context context, @Main Resources resources) {
|
public DreamOverlayRegistrant(Context context, @Main Resources resources,
|
||||||
|
@Named(DREAM_OVERLAY_SERVICE_COMPONENT) ComponentName dreamOverlayServiceComponent) {
|
||||||
mContext = context;
|
mContext = context;
|
||||||
mResources = resources;
|
mResources = resources;
|
||||||
mDreamManager = IDreamManager.Stub.asInterface(
|
mDreamManager = IDreamManager.Stub.asInterface(
|
||||||
ServiceManager.getService(DreamService.DREAM_SERVICE));
|
ServiceManager.getService(DreamService.DREAM_SERVICE));
|
||||||
mOverlayServiceComponent = new ComponentName(mContext, DreamOverlayService.class);
|
mOverlayServiceComponent = dreamOverlayServiceComponent;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -16,6 +16,8 @@
|
|||||||
|
|
||||||
package com.android.systemui.dreams;
|
package com.android.systemui.dreams;
|
||||||
|
|
||||||
|
import static com.android.systemui.dreams.dagger.DreamModule.DREAM_OVERLAY_ENABLED;
|
||||||
|
|
||||||
import android.service.dreams.DreamService;
|
import android.service.dreams.DreamService;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
|
|
||||||
@@ -37,6 +39,7 @@ import java.util.function.Consumer;
|
|||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
|
import javax.inject.Named;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* {@link DreamOverlayStateController} is the source of truth for Dream overlay configurations and
|
* {@link DreamOverlayStateController} is the source of truth for Dream overlay configurations and
|
||||||
@@ -83,6 +86,7 @@ public class DreamOverlayStateController implements
|
|||||||
}
|
}
|
||||||
|
|
||||||
private final Executor mExecutor;
|
private final Executor mExecutor;
|
||||||
|
private final boolean mOverlayEnabled;
|
||||||
private final ArrayList<Callback> mCallbacks = new ArrayList<>();
|
private final ArrayList<Callback> mCallbacks = new ArrayList<>();
|
||||||
|
|
||||||
@Complication.ComplicationType
|
@Complication.ComplicationType
|
||||||
@@ -94,14 +98,27 @@ public class DreamOverlayStateController implements
|
|||||||
|
|
||||||
@VisibleForTesting
|
@VisibleForTesting
|
||||||
@Inject
|
@Inject
|
||||||
public DreamOverlayStateController(@Main Executor executor) {
|
public DreamOverlayStateController(@Main Executor executor,
|
||||||
|
@Named(DREAM_OVERLAY_ENABLED) boolean overlayEnabled) {
|
||||||
mExecutor = executor;
|
mExecutor = executor;
|
||||||
|
mOverlayEnabled = overlayEnabled;
|
||||||
|
if (DEBUG) {
|
||||||
|
Log.d(TAG, "Dream overlay enabled:" + mOverlayEnabled);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Adds a complication to be included on the dream overlay.
|
* Adds a complication to be included on the dream overlay.
|
||||||
*/
|
*/
|
||||||
public void addComplication(Complication complication) {
|
public void addComplication(Complication complication) {
|
||||||
|
if (!mOverlayEnabled) {
|
||||||
|
if (DEBUG) {
|
||||||
|
Log.d(TAG,
|
||||||
|
"Ignoring adding complication due to overlay disabled:" + complication);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
mExecutor.execute(() -> {
|
mExecutor.execute(() -> {
|
||||||
if (mComplications.add(complication)) {
|
if (mComplications.add(complication)) {
|
||||||
if (DEBUG) {
|
if (DEBUG) {
|
||||||
@@ -116,6 +133,14 @@ public class DreamOverlayStateController implements
|
|||||||
* Removes a complication from inclusion on the dream overlay.
|
* Removes a complication from inclusion on the dream overlay.
|
||||||
*/
|
*/
|
||||||
public void removeComplication(Complication complication) {
|
public void removeComplication(Complication complication) {
|
||||||
|
if (!mOverlayEnabled) {
|
||||||
|
if (DEBUG) {
|
||||||
|
Log.d(TAG,
|
||||||
|
"Ignoring removing complication due to overlay disabled:" + complication);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
mExecutor.execute(() -> {
|
mExecutor.execute(() -> {
|
||||||
if (mComplications.remove(complication)) {
|
if (mComplications.remove(complication)) {
|
||||||
if (DEBUG) {
|
if (DEBUG) {
|
||||||
@@ -193,7 +218,7 @@ public class DreamOverlayStateController implements
|
|||||||
* @return {@code true} if overlay is active, {@code false} otherwise.
|
* @return {@code true} if overlay is active, {@code false} otherwise.
|
||||||
*/
|
*/
|
||||||
public boolean isOverlayActive() {
|
public boolean isOverlayActive() {
|
||||||
return containsState(STATE_DREAM_OVERLAY_ACTIVE);
|
return mOverlayEnabled && containsState(STATE_DREAM_OVERLAY_ACTIVE);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -138,19 +138,27 @@ public class ComplicationHostViewController extends ViewController<ConstraintLay
|
|||||||
final ComplicationId id = complication.getId();
|
final ComplicationId id = complication.getId();
|
||||||
final Complication.ViewHolder viewHolder = complication.getComplication()
|
final Complication.ViewHolder viewHolder = complication.getComplication()
|
||||||
.createView(complication);
|
.createView(complication);
|
||||||
|
|
||||||
|
final View view = viewHolder.getView();
|
||||||
|
|
||||||
|
if (view == null) {
|
||||||
|
Log.e(TAG, "invalid complication view. null view supplied by ViewHolder");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// Complications to be added before dream entry animations are finished are set
|
// Complications to be added before dream entry animations are finished are set
|
||||||
// to invisible and are animated in.
|
// to invisible and are animated in.
|
||||||
if (!mEntryAnimationsFinished) {
|
if (!mEntryAnimationsFinished) {
|
||||||
viewHolder.getView().setVisibility(View.INVISIBLE);
|
view.setVisibility(View.INVISIBLE);
|
||||||
}
|
}
|
||||||
mComplications.put(id, viewHolder);
|
mComplications.put(id, viewHolder);
|
||||||
if (viewHolder.getView().getParent() != null) {
|
if (view.getParent() != null) {
|
||||||
Log.e(TAG, "View for complication "
|
Log.e(TAG, "View for complication "
|
||||||
+ complication.getComplication().getClass()
|
+ complication.getComplication().getClass()
|
||||||
+ " already has a parent. Make sure not to reuse complication "
|
+ " already has a parent. Make sure not to reuse complication "
|
||||||
+ "views!");
|
+ "views!");
|
||||||
}
|
}
|
||||||
mLayoutEngine.addComplication(id, viewHolder.getView(),
|
mLayoutEngine.addComplication(id, view,
|
||||||
viewHolder.getLayoutParams(), viewHolder.getCategory());
|
viewHolder.getLayoutParams(), viewHolder.getCategory());
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,7 +16,9 @@
|
|||||||
|
|
||||||
package com.android.systemui.dreams.dagger;
|
package com.android.systemui.dreams.dagger;
|
||||||
|
|
||||||
|
import android.content.ComponentName;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
|
import android.content.pm.PackageManager;
|
||||||
import android.content.res.Resources;
|
import android.content.res.Resources;
|
||||||
|
|
||||||
import com.android.dream.lowlight.dagger.LowLightDreamModule;
|
import com.android.dream.lowlight.dagger.LowLightDreamModule;
|
||||||
@@ -24,6 +26,7 @@ import com.android.settingslib.dream.DreamBackend;
|
|||||||
import com.android.systemui.dagger.SysUISingleton;
|
import com.android.systemui.dagger.SysUISingleton;
|
||||||
import com.android.systemui.dagger.qualifiers.Main;
|
import com.android.systemui.dagger.qualifiers.Main;
|
||||||
import com.android.systemui.dreams.DreamOverlayNotificationCountProvider;
|
import com.android.systemui.dreams.DreamOverlayNotificationCountProvider;
|
||||||
|
import com.android.systemui.dreams.DreamOverlayService;
|
||||||
import com.android.systemui.dreams.complication.dagger.RegisteredComplicationsModule;
|
import com.android.systemui.dreams.complication.dagger.RegisteredComplicationsModule;
|
||||||
|
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
@@ -45,9 +48,34 @@ import dagger.Provides;
|
|||||||
})
|
})
|
||||||
public interface DreamModule {
|
public interface DreamModule {
|
||||||
String DREAM_ONLY_ENABLED_FOR_DOCK_USER = "dream_only_enabled_for_dock_user";
|
String DREAM_ONLY_ENABLED_FOR_DOCK_USER = "dream_only_enabled_for_dock_user";
|
||||||
|
String DREAM_OVERLAY_SERVICE_COMPONENT = "dream_overlay_service_component";
|
||||||
|
String DREAM_OVERLAY_ENABLED = "dream_overlay_enabled";
|
||||||
|
|
||||||
String DREAM_SUPPORTED = "dream_supported";
|
String DREAM_SUPPORTED = "dream_supported";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Provides the dream component
|
||||||
|
*/
|
||||||
|
@Provides
|
||||||
|
@Named(DREAM_OVERLAY_SERVICE_COMPONENT)
|
||||||
|
static ComponentName providesDreamOverlayService(Context context) {
|
||||||
|
return new ComponentName(context, DreamOverlayService.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Provides whether dream overlay is enabled.
|
||||||
|
*/
|
||||||
|
@Provides
|
||||||
|
@Named(DREAM_OVERLAY_ENABLED)
|
||||||
|
static Boolean providesDreamOverlayEnabled(PackageManager packageManager,
|
||||||
|
@Named(DREAM_OVERLAY_SERVICE_COMPONENT) ComponentName component) {
|
||||||
|
try {
|
||||||
|
return packageManager.getServiceInfo(component, PackageManager.GET_META_DATA).enabled;
|
||||||
|
} catch (PackageManager.NameNotFoundException e) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Provides an instance of the dream backend.
|
* Provides an instance of the dream backend.
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -63,7 +63,7 @@ public class DreamOverlayStateControllerTest extends SysuiTestCase {
|
|||||||
@Test
|
@Test
|
||||||
public void testStateChange_overlayActive() {
|
public void testStateChange_overlayActive() {
|
||||||
final DreamOverlayStateController stateController = new DreamOverlayStateController(
|
final DreamOverlayStateController stateController = new DreamOverlayStateController(
|
||||||
mExecutor);
|
mExecutor, true);
|
||||||
stateController.addCallback(mCallback);
|
stateController.addCallback(mCallback);
|
||||||
stateController.setOverlayActive(true);
|
stateController.setOverlayActive(true);
|
||||||
mExecutor.runAllReady();
|
mExecutor.runAllReady();
|
||||||
@@ -85,7 +85,7 @@ public class DreamOverlayStateControllerTest extends SysuiTestCase {
|
|||||||
@Test
|
@Test
|
||||||
public void testCallback() {
|
public void testCallback() {
|
||||||
final DreamOverlayStateController stateController = new DreamOverlayStateController(
|
final DreamOverlayStateController stateController = new DreamOverlayStateController(
|
||||||
mExecutor);
|
mExecutor, true);
|
||||||
stateController.addCallback(mCallback);
|
stateController.addCallback(mCallback);
|
||||||
|
|
||||||
// Add complication and verify callback is notified.
|
// Add complication and verify callback is notified.
|
||||||
@@ -111,7 +111,7 @@ public class DreamOverlayStateControllerTest extends SysuiTestCase {
|
|||||||
@Test
|
@Test
|
||||||
public void testNotifyOnCallbackAdd() {
|
public void testNotifyOnCallbackAdd() {
|
||||||
final DreamOverlayStateController stateController =
|
final DreamOverlayStateController stateController =
|
||||||
new DreamOverlayStateController(mExecutor);
|
new DreamOverlayStateController(mExecutor, true);
|
||||||
|
|
||||||
stateController.addComplication(mComplication);
|
stateController.addComplication(mComplication);
|
||||||
mExecutor.runAllReady();
|
mExecutor.runAllReady();
|
||||||
@@ -122,10 +122,25 @@ public class DreamOverlayStateControllerTest extends SysuiTestCase {
|
|||||||
verify(mCallback, times(1)).onComplicationsChanged();
|
verify(mCallback, times(1)).onComplicationsChanged();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testNotifyOnCallbackAddOverlayDisabled() {
|
||||||
|
final DreamOverlayStateController stateController =
|
||||||
|
new DreamOverlayStateController(mExecutor, false);
|
||||||
|
|
||||||
|
stateController.addComplication(mComplication);
|
||||||
|
mExecutor.runAllReady();
|
||||||
|
|
||||||
|
// Verify callback occurs on add when an overlay is already present.
|
||||||
|
stateController.addCallback(mCallback);
|
||||||
|
mExecutor.runAllReady();
|
||||||
|
verify(mCallback, never()).onComplicationsChanged();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testComplicationFilteringWhenShouldShowComplications() {
|
public void testComplicationFilteringWhenShouldShowComplications() {
|
||||||
final DreamOverlayStateController stateController =
|
final DreamOverlayStateController stateController =
|
||||||
new DreamOverlayStateController(mExecutor);
|
new DreamOverlayStateController(mExecutor, true);
|
||||||
stateController.setShouldShowComplications(true);
|
stateController.setShouldShowComplications(true);
|
||||||
|
|
||||||
final Complication alwaysAvailableComplication = Mockito.mock(Complication.class);
|
final Complication alwaysAvailableComplication = Mockito.mock(Complication.class);
|
||||||
@@ -165,7 +180,7 @@ public class DreamOverlayStateControllerTest extends SysuiTestCase {
|
|||||||
@Test
|
@Test
|
||||||
public void testComplicationFilteringWhenShouldHideComplications() {
|
public void testComplicationFilteringWhenShouldHideComplications() {
|
||||||
final DreamOverlayStateController stateController =
|
final DreamOverlayStateController stateController =
|
||||||
new DreamOverlayStateController(mExecutor);
|
new DreamOverlayStateController(mExecutor, true);
|
||||||
stateController.setShouldShowComplications(true);
|
stateController.setShouldShowComplications(true);
|
||||||
|
|
||||||
final Complication alwaysAvailableComplication = Mockito.mock(Complication.class);
|
final Complication alwaysAvailableComplication = Mockito.mock(Complication.class);
|
||||||
@@ -212,7 +227,7 @@ public class DreamOverlayStateControllerTest extends SysuiTestCase {
|
|||||||
public void testComplicationWithNoTypeNotFiltered() {
|
public void testComplicationWithNoTypeNotFiltered() {
|
||||||
final Complication complication = Mockito.mock(Complication.class);
|
final Complication complication = Mockito.mock(Complication.class);
|
||||||
final DreamOverlayStateController stateController =
|
final DreamOverlayStateController stateController =
|
||||||
new DreamOverlayStateController(mExecutor);
|
new DreamOverlayStateController(mExecutor, true);
|
||||||
stateController.addComplication(complication);
|
stateController.addComplication(complication);
|
||||||
mExecutor.runAllReady();
|
mExecutor.runAllReady();
|
||||||
assertThat(stateController.getComplications(true).contains(complication))
|
assertThat(stateController.getComplications(true).contains(complication))
|
||||||
@@ -222,7 +237,7 @@ public class DreamOverlayStateControllerTest extends SysuiTestCase {
|
|||||||
@Test
|
@Test
|
||||||
public void testNotifyLowLightChanged() {
|
public void testNotifyLowLightChanged() {
|
||||||
final DreamOverlayStateController stateController =
|
final DreamOverlayStateController stateController =
|
||||||
new DreamOverlayStateController(mExecutor);
|
new DreamOverlayStateController(mExecutor, true);
|
||||||
|
|
||||||
stateController.addCallback(mCallback);
|
stateController.addCallback(mCallback);
|
||||||
mExecutor.runAllReady();
|
mExecutor.runAllReady();
|
||||||
@@ -238,7 +253,7 @@ public class DreamOverlayStateControllerTest extends SysuiTestCase {
|
|||||||
@Test
|
@Test
|
||||||
public void testNotifyEntryAnimationsFinishedChanged() {
|
public void testNotifyEntryAnimationsFinishedChanged() {
|
||||||
final DreamOverlayStateController stateController =
|
final DreamOverlayStateController stateController =
|
||||||
new DreamOverlayStateController(mExecutor);
|
new DreamOverlayStateController(mExecutor, true);
|
||||||
|
|
||||||
stateController.addCallback(mCallback);
|
stateController.addCallback(mCallback);
|
||||||
mExecutor.runAllReady();
|
mExecutor.runAllReady();
|
||||||
|
|||||||
@@ -15,6 +15,8 @@
|
|||||||
*/
|
*/
|
||||||
package com.android.systemui.dreams.complication;
|
package com.android.systemui.dreams.complication;
|
||||||
|
|
||||||
|
import static org.mockito.ArgumentMatchers.any;
|
||||||
|
import static org.mockito.ArgumentMatchers.anyInt;
|
||||||
import static org.mockito.ArgumentMatchers.eq;
|
import static org.mockito.ArgumentMatchers.eq;
|
||||||
import static org.mockito.Mockito.never;
|
import static org.mockito.Mockito.never;
|
||||||
import static org.mockito.Mockito.verify;
|
import static org.mockito.Mockito.verify;
|
||||||
@@ -138,6 +140,21 @@ public class ComplicationHostViewControllerTest extends SysuiTestCase {
|
|||||||
verify(mLayoutEngine).removeComplication(eq(mComplicationId));
|
verify(mLayoutEngine).removeComplication(eq(mComplicationId));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testMalformedComplicationAddition() {
|
||||||
|
final Observer<Collection<ComplicationViewModel>> observer =
|
||||||
|
captureComplicationViewModelsObserver();
|
||||||
|
|
||||||
|
// Add a complication and ensure it is added to the view.
|
||||||
|
final HashSet<ComplicationViewModel> complications = new HashSet<>(
|
||||||
|
Collections.singletonList(mComplicationViewModel));
|
||||||
|
when(mViewHolder.getView()).thenReturn(null);
|
||||||
|
observer.onChanged(complications);
|
||||||
|
|
||||||
|
verify(mLayoutEngine, never()).addComplication(any(), any(), any(), anyInt());
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testNewComplicationsBeforeEntryAnimationsFinishSetToInvisible() {
|
public void testNewComplicationsBeforeEntryAnimationsFinishSetToInvisible() {
|
||||||
final Observer<Collection<ComplicationViewModel>> observer =
|
final Observer<Collection<ComplicationViewModel>> observer =
|
||||||
|
|||||||
Reference in New Issue
Block a user