summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Bryce Lee <brycelee@google.com> 2022-12-13 23:05:33 +0000
committer Android (Google) Code Review <android-gerrit@google.com> 2022-12-13 23:05:33 +0000
commite6cf58ac7cb981fa0c2315d93c27725b6282a88c (patch)
tree1866bd6fb9ce9720b3f696bafee553483ac0d8a7
parenta942c6c9d8b255877327f22d68b6edf3095eabde (diff)
parent1a33563df31a1fbb4573915d3d666aa35cfc1f1c (diff)
Merge changes I81879e60,Ief02e781
* changes: Move Complication logic out of DreamOverlay. Do not specify root view in TouchInsetManager.
-rw-r--r--packages/SystemUI/src/com/android/systemui/dreams/DreamOverlayService.java20
-rw-r--r--packages/SystemUI/src/com/android/systemui/dreams/complication/ComplicationLayoutEngine.java4
-rw-r--r--packages/SystemUI/src/com/android/systemui/dreams/complication/dagger/ComplicationComponent.kt21
-rw-r--r--packages/SystemUI/src/com/android/systemui/dreams/complication/dagger/ComplicationHostViewModule.java12
-rw-r--r--packages/SystemUI/src/com/android/systemui/dreams/complication/dagger/ComplicationModule.java17
-rw-r--r--packages/SystemUI/src/com/android/systemui/dreams/dagger/DreamOverlayComponent.java10
-rw-r--r--packages/SystemUI/src/com/android/systemui/dreams/dagger/DreamOverlayModule.java27
-rw-r--r--packages/SystemUI/src/com/android/systemui/touch/TouchInsetManager.java153
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/dreams/DreamOverlayServiceTest.java39
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/touch/TouchInsetManagerTest.java93
10 files changed, 249 insertions, 147 deletions
diff --git a/packages/SystemUI/src/com/android/systemui/dreams/DreamOverlayService.java b/packages/SystemUI/src/com/android/systemui/dreams/DreamOverlayService.java
index 8fdcb0df6900..16b4f99da894 100644
--- a/packages/SystemUI/src/com/android/systemui/dreams/DreamOverlayService.java
+++ b/packages/SystemUI/src/com/android/systemui/dreams/DreamOverlayService.java
@@ -45,7 +45,10 @@ import com.android.systemui.dreams.complication.Complication;
import com.android.systemui.dreams.complication.dagger.ComplicationComponent;
import com.android.systemui.dreams.dagger.DreamOverlayComponent;
import com.android.systemui.dreams.touch.DreamOverlayTouchMonitor;
+import com.android.systemui.touch.TouchInsetManager;
+import java.util.Arrays;
+import java.util.HashSet;
import java.util.concurrent.Executor;
import javax.inject.Inject;
@@ -84,6 +87,9 @@ public class DreamOverlayService extends android.service.dreams.DreamOverlayServ
private final ComplicationComponent mComplicationComponent;
+ private final com.android.systemui.dreams.dreamcomplication.dagger.ComplicationComponent
+ mDreamComplicationComponent;
+
private final DreamOverlayComponent mDreamOverlayComponent;
private final DreamOverlayLifecycleOwner mLifecycleOwner;
@@ -135,10 +141,13 @@ public class DreamOverlayService extends android.service.dreams.DreamOverlayServ
DreamOverlayLifecycleOwner lifecycleOwner,
WindowManager windowManager,
ComplicationComponent.Factory complicationComponentFactory,
+ com.android.systemui.dreams.dreamcomplication.dagger.ComplicationComponent.Factory
+ dreamComplicationComponentFactory,
DreamOverlayComponent.Factory dreamOverlayComponentFactory,
DreamOverlayStateController stateController,
KeyguardUpdateMonitor keyguardUpdateMonitor,
UiEventLogger uiEventLogger,
+ TouchInsetManager touchInsetManager,
@Nullable @Named(LowLightDreamModule.LOW_LIGHT_DREAM_COMPONENT)
ComponentName lowLightDreamComponent) {
mContext = context;
@@ -154,9 +163,14 @@ public class DreamOverlayService extends android.service.dreams.DreamOverlayServ
final Complication.Host host =
() -> mExecutor.execute(DreamOverlayService.this::requestExit);
- mComplicationComponent = complicationComponentFactory.create();
- mDreamOverlayComponent =
- dreamOverlayComponentFactory.create(lifecycleOwner, viewModelStore, host, null);
+ mComplicationComponent = complicationComponentFactory.create(lifecycleOwner, host,
+ viewModelStore, touchInsetManager);
+ mDreamComplicationComponent = dreamComplicationComponentFactory.create(
+ mComplicationComponent.getVisibilityController(), touchInsetManager);
+ mDreamOverlayComponent = dreamOverlayComponentFactory.create(lifecycleOwner,
+ mComplicationComponent.getComplicationHostViewController(), touchInsetManager,
+ new HashSet<>(Arrays.asList(
+ mDreamComplicationComponent.getHideComplicationTouchHandler())));
mLifecycleOwner = lifecycleOwner;
mLifecycleRegistry = mLifecycleOwner.getRegistry();
diff --git a/packages/SystemUI/src/com/android/systemui/dreams/complication/ComplicationLayoutEngine.java b/packages/SystemUI/src/com/android/systemui/dreams/complication/ComplicationLayoutEngine.java
index 46ce7a90f5a3..3e9b0103470c 100644
--- a/packages/SystemUI/src/com/android/systemui/dreams/complication/ComplicationLayoutEngine.java
+++ b/packages/SystemUI/src/com/android/systemui/dreams/complication/ComplicationLayoutEngine.java
@@ -30,7 +30,7 @@ import androidx.constraintlayout.widget.Constraints;
import com.android.systemui.R;
import com.android.systemui.dreams.complication.ComplicationLayoutParams.Position;
-import com.android.systemui.dreams.dagger.DreamOverlayComponent;
+import com.android.systemui.dreams.complication.dagger.ComplicationModule;
import com.android.systemui.statusbar.CrossFadeHelper;
import com.android.systemui.touch.TouchInsetManager;
@@ -50,7 +50,7 @@ import javax.inject.Named;
* their layout parameters and attributes. The management of this set is done by
* {@link ComplicationHostViewController}.
*/
-@DreamOverlayComponent.DreamOverlayScope
+@ComplicationModule.ComplicationScope
public class ComplicationLayoutEngine implements Complication.VisibilityController {
public static final String TAG = "ComplicationLayoutEng";
diff --git a/packages/SystemUI/src/com/android/systemui/dreams/complication/dagger/ComplicationComponent.kt b/packages/SystemUI/src/com/android/systemui/dreams/complication/dagger/ComplicationComponent.kt
index 89497098f8ae..8d133bd25275 100644
--- a/packages/SystemUI/src/com/android/systemui/dreams/complication/dagger/ComplicationComponent.kt
+++ b/packages/SystemUI/src/com/android/systemui/dreams/complication/dagger/ComplicationComponent.kt
@@ -1,12 +1,29 @@
package com.android.systemui.dreams.complication.dagger
+import androidx.lifecycle.LifecycleOwner
+import androidx.lifecycle.ViewModelStore
+import com.android.systemui.dreams.complication.Complication
+import com.android.systemui.dreams.complication.ComplicationHostViewController
+import com.android.systemui.dreams.complication.ComplicationLayoutEngine
+import com.android.systemui.touch.TouchInsetManager
+import dagger.BindsInstance
import dagger.Subcomponent
-@Subcomponent
+@Subcomponent(modules = [ComplicationModule::class])
+@ComplicationModule.ComplicationScope
interface ComplicationComponent {
/** Factory for generating [ComplicationComponent]. */
@Subcomponent.Factory
interface Factory {
- fun create(): ComplicationComponent
+ fun create(
+ @BindsInstance lifecycleOwner: LifecycleOwner,
+ @BindsInstance host: Complication.Host,
+ @BindsInstance viewModelStore: ViewModelStore,
+ @BindsInstance touchInsetManager: TouchInsetManager
+ ): ComplicationComponent
}
+
+ fun getComplicationHostViewController(): ComplicationHostViewController
+
+ fun getVisibilityController(): ComplicationLayoutEngine
}
diff --git a/packages/SystemUI/src/com/android/systemui/dreams/complication/dagger/ComplicationHostViewModule.java b/packages/SystemUI/src/com/android/systemui/dreams/complication/dagger/ComplicationHostViewModule.java
index 09cc7c51ccf4..797906fbaf8e 100644
--- a/packages/SystemUI/src/com/android/systemui/dreams/complication/dagger/ComplicationHostViewModule.java
+++ b/packages/SystemUI/src/com/android/systemui/dreams/complication/dagger/ComplicationHostViewModule.java
@@ -24,13 +24,12 @@ import androidx.constraintlayout.widget.ConstraintLayout;
import com.android.internal.util.Preconditions;
import com.android.systemui.R;
import com.android.systemui.dagger.qualifiers.Main;
-import com.android.systemui.dreams.dagger.DreamOverlayComponent;
-
-import javax.inject.Named;
import dagger.Module;
import dagger.Provides;
+import javax.inject.Named;
+
/**
* Module for providing a scoped host view.
*/
@@ -49,7 +48,7 @@ public abstract class ComplicationHostViewModule {
*/
@Provides
@Named(SCOPED_COMPLICATIONS_LAYOUT)
- @DreamOverlayComponent.DreamOverlayScope
+ @ComplicationModule.ComplicationScope
static ConstraintLayout providesComplicationHostView(
LayoutInflater layoutInflater) {
return Preconditions.checkNotNull((ConstraintLayout)
@@ -60,7 +59,6 @@ public abstract class ComplicationHostViewModule {
@Provides
@Named(COMPLICATION_MARGIN_DEFAULT)
- @DreamOverlayComponent.DreamOverlayScope
static int providesComplicationPadding(@Main Resources resources) {
return resources.getDimensionPixelSize(R.dimen.dream_overlay_complication_margin);
}
@@ -70,7 +68,6 @@ public abstract class ComplicationHostViewModule {
*/
@Provides
@Named(COMPLICATIONS_FADE_OUT_DURATION)
- @DreamOverlayComponent.DreamOverlayScope
static int providesComplicationsFadeOutDuration(@Main Resources resources) {
return resources.getInteger(R.integer.complicationFadeOutMs);
}
@@ -80,7 +77,6 @@ public abstract class ComplicationHostViewModule {
*/
@Provides
@Named(COMPLICATIONS_FADE_OUT_DELAY)
- @DreamOverlayComponent.DreamOverlayScope
static int providesComplicationsFadeOutDelay(@Main Resources resources) {
return resources.getInteger(R.integer.complicationFadeOutDelayMs);
}
@@ -90,7 +86,6 @@ public abstract class ComplicationHostViewModule {
*/
@Provides
@Named(COMPLICATIONS_FADE_IN_DURATION)
- @DreamOverlayComponent.DreamOverlayScope
static int providesComplicationsFadeInDuration(@Main Resources resources) {
return resources.getInteger(R.integer.complicationFadeInMs);
}
@@ -100,7 +95,6 @@ public abstract class ComplicationHostViewModule {
*/
@Provides
@Named(COMPLICATIONS_RESTORE_TIMEOUT)
- @DreamOverlayComponent.DreamOverlayScope
static int providesComplicationsRestoreTimeout(@Main Resources resources) {
return resources.getInteger(R.integer.complicationRestoreMs);
}
diff --git a/packages/SystemUI/src/com/android/systemui/dreams/complication/dagger/ComplicationModule.java b/packages/SystemUI/src/com/android/systemui/dreams/complication/dagger/ComplicationModule.java
index 5c2fdf5c9af4..dbf5ab000a8a 100644
--- a/packages/SystemUI/src/com/android/systemui/dreams/complication/dagger/ComplicationModule.java
+++ b/packages/SystemUI/src/com/android/systemui/dreams/complication/dagger/ComplicationModule.java
@@ -24,16 +24,16 @@ import androidx.lifecycle.ViewModelStore;
import com.android.systemui.dreams.complication.Complication;
import com.android.systemui.dreams.complication.ComplicationCollectionViewModel;
import com.android.systemui.dreams.complication.ComplicationLayoutEngine;
+import com.android.systemui.touch.TouchInsetManager;
+
+import dagger.Module;
+import dagger.Provides;
import java.lang.annotation.Documented;
import java.lang.annotation.Retention;
import javax.inject.Named;
import javax.inject.Scope;
-
-import dagger.Module;
-import dagger.Provides;
-
/**
* Module for housing components related to rendering complications.
*/
@@ -73,4 +73,13 @@ public interface ComplicationModule {
ComplicationLayoutEngine engine) {
return engine;
}
+
+ /**
+ * Provides a new touch inset session instance for complication logic.
+ */
+ @Provides
+ static TouchInsetManager.TouchInsetSession providesTouchInsetSession(
+ TouchInsetManager manager) {
+ return manager.createSession();
+ }
}
diff --git a/packages/SystemUI/src/com/android/systemui/dreams/dagger/DreamOverlayComponent.java b/packages/SystemUI/src/com/android/systemui/dreams/dagger/DreamOverlayComponent.java
index 584829074cf4..0332f888c866 100644
--- a/packages/SystemUI/src/com/android/systemui/dreams/dagger/DreamOverlayComponent.java
+++ b/packages/SystemUI/src/com/android/systemui/dreams/dagger/DreamOverlayComponent.java
@@ -23,14 +23,13 @@ import static java.lang.annotation.RetentionPolicy.RUNTIME;
import android.annotation.Nullable;
import androidx.lifecycle.LifecycleOwner;
-import androidx.lifecycle.ViewModelStore;
import com.android.systemui.dreams.DreamOverlayContainerViewController;
-import com.android.systemui.dreams.complication.Complication;
-import com.android.systemui.dreams.complication.dagger.ComplicationModule;
+import com.android.systemui.dreams.complication.ComplicationHostViewController;
import com.android.systemui.dreams.touch.DreamOverlayTouchMonitor;
import com.android.systemui.dreams.touch.DreamTouchHandler;
import com.android.systemui.dreams.touch.dagger.DreamTouchModule;
+import com.android.systemui.touch.TouchInsetManager;
import dagger.BindsInstance;
import dagger.Subcomponent;
@@ -48,7 +47,6 @@ import javax.inject.Scope;
@Subcomponent(modules = {
DreamTouchModule.class,
DreamOverlayModule.class,
- ComplicationModule.class,
})
@DreamOverlayComponent.DreamOverlayScope
public interface DreamOverlayComponent {
@@ -57,8 +55,8 @@ public interface DreamOverlayComponent {
interface Factory {
DreamOverlayComponent create(
@BindsInstance LifecycleOwner lifecycleOwner,
- @BindsInstance ViewModelStore store,
- @BindsInstance Complication.Host host,
+ @BindsInstance ComplicationHostViewController complicationHostViewController,
+ @BindsInstance TouchInsetManager touchInsetManager,
@BindsInstance @Named(DREAM_TOUCH_HANDLERS) @Nullable
Set<DreamTouchHandler> dreamTouchHandlers);
}
diff --git a/packages/SystemUI/src/com/android/systemui/dreams/dagger/DreamOverlayModule.java b/packages/SystemUI/src/com/android/systemui/dreams/dagger/DreamOverlayModule.java
index 67e25713987f..448538193eaf 100644
--- a/packages/SystemUI/src/com/android/systemui/dreams/dagger/DreamOverlayModule.java
+++ b/packages/SystemUI/src/com/android/systemui/dreams/dagger/DreamOverlayModule.java
@@ -29,20 +29,15 @@ import com.android.systemui.R;
import com.android.systemui.dagger.qualifiers.Main;
import com.android.systemui.dreams.DreamOverlayContainerView;
import com.android.systemui.dreams.DreamOverlayStatusBarView;
-import com.android.systemui.dreams.complication.Complication;
-import com.android.systemui.dreams.dreamcomplication.HideComplicationTouchHandler;
-import com.android.systemui.dreams.dreamcomplication.dagger.ComplicationComponent;
import com.android.systemui.dreams.touch.DreamTouchHandler;
import com.android.systemui.touch.TouchInsetManager;
import dagger.Module;
import dagger.Provides;
import dagger.multibindings.ElementsIntoSet;
-import dagger.multibindings.IntoSet;
import java.util.HashSet;
import java.util.Set;
-import java.util.concurrent.Executor;
import javax.inject.Named;
@@ -109,14 +104,6 @@ public abstract class DreamOverlayModule {
/** */
@Provides
@DreamOverlayComponent.DreamOverlayScope
- public static TouchInsetManager providesTouchInsetManager(@Main Executor executor,
- DreamOverlayContainerView view) {
- return new TouchInsetManager(executor, view);
- }
-
- /** */
- @Provides
- @DreamOverlayComponent.DreamOverlayScope
public static DreamOverlayStatusBarView providesDreamOverlayStatusBarView(
DreamOverlayContainerView view) {
return Preconditions.checkNotNull(view.findViewById(R.id.dream_overlay_status_bar),
@@ -264,18 +251,4 @@ public abstract class DreamOverlayModule {
@Named(DREAM_TOUCH_HANDLERS) @Nullable Set<DreamTouchHandler> touchHandlers) {
return touchHandlers != null ? touchHandlers : new HashSet<>();
}
-
- /**
- * Provides {@link HideComplicationTouchHandler} for inclusion in touch handling over the dream.
- */
- @Provides
- @IntoSet
- public static DreamTouchHandler providesHideComplicationTouchHandler(
- ComplicationComponent.Factory componentFactory,
- Complication.VisibilityController visibilityController,
- TouchInsetManager touchInsetManager) {
- ComplicationComponent component =
- componentFactory.create(visibilityController, touchInsetManager);
- return component.getHideComplicationTouchHandler();
- }
}
diff --git a/packages/SystemUI/src/com/android/systemui/touch/TouchInsetManager.java b/packages/SystemUI/src/com/android/systemui/touch/TouchInsetManager.java
index 3d07491283c5..166ac9e737f3 100644
--- a/packages/SystemUI/src/com/android/systemui/touch/TouchInsetManager.java
+++ b/packages/SystemUI/src/com/android/systemui/touch/TouchInsetManager.java
@@ -18,41 +18,58 @@ package com.android.systemui.touch;
import android.graphics.Rect;
import android.graphics.Region;
+import android.util.Log;
+import android.view.AttachedSurfaceControl;
import android.view.View;
-import android.view.ViewRootImpl;
import androidx.concurrent.futures.CallbackToFutureAdapter;
+import com.android.systemui.dagger.qualifiers.Main;
+
import com.google.common.util.concurrent.ListenableFuture;
import java.util.HashMap;
import java.util.HashSet;
import java.util.concurrent.Executor;
+import javax.inject.Inject;
+
/**
* {@link TouchInsetManager} handles setting the touchable inset regions for a given View. This
* is useful for passing through touch events for all but select areas.
*/
public class TouchInsetManager {
+ private static final String TAG = "TouchInsetManager";
/**
* {@link TouchInsetSession} provides an individualized session with the
* {@link TouchInsetManager}, linking any action to the client.
*/
public static class TouchInsetSession {
private final TouchInsetManager mManager;
-
private final HashSet<View> mTrackedViews;
private final Executor mExecutor;
private final View.OnLayoutChangeListener mOnLayoutChangeListener =
(v, left, top, right, bottom, oldLeft, oldTop, oldRight, oldBottom)
- -> updateTouchRegion();
+ -> updateTouchRegions();
+
+ private final View.OnAttachStateChangeListener mAttachListener =
+ new View.OnAttachStateChangeListener() {
+ @Override
+ public void onViewAttachedToWindow(View v) {
+ updateTouchRegions();
+ }
+
+ @Override
+ public void onViewDetachedFromWindow(View v) {
+ updateTouchRegions();
+ }
+ };
/**
* Default constructor
* @param manager The parent {@link TouchInsetManager} which will be affected by actions on
* this session.
- * @param rootView The parent of views that will be tracked.
* @param executor An executor for marshalling operations.
*/
TouchInsetSession(TouchInsetManager manager, Executor executor) {
@@ -68,8 +85,9 @@ public class TouchInsetManager {
public void addViewToTracking(View view) {
mExecutor.execute(() -> {
mTrackedViews.add(view);
+ view.addOnAttachStateChangeListener(mAttachListener);
view.addOnLayoutChangeListener(mOnLayoutChangeListener);
- updateTouchRegion();
+ updateTouchRegions();
});
}
@@ -81,22 +99,30 @@ public class TouchInsetManager {
mExecutor.execute(() -> {
mTrackedViews.remove(view);
view.removeOnLayoutChangeListener(mOnLayoutChangeListener);
- updateTouchRegion();
+ view.removeOnAttachStateChangeListener(mAttachListener);
+ updateTouchRegions();
});
}
- private void updateTouchRegion() {
- final Region cumulativeRegion = Region.obtain();
-
- mTrackedViews.stream().forEach(view -> {
- final Rect boundaries = new Rect();
- view.getBoundsOnScreen(boundaries);
- cumulativeRegion.op(boundaries, Region.Op.UNION);
+ private void updateTouchRegions() {
+ mExecutor.execute(() -> {
+ final HashMap<AttachedSurfaceControl, Region> affectedSurfaces = new HashMap<>();
+ mTrackedViews.stream().forEach(view -> {
+ if (!view.isAttachedToWindow()) {
+ return;
+ }
+
+ final AttachedSurfaceControl surface = view.getRootSurfaceControl();
+
+ if (!affectedSurfaces.containsKey(surface)) {
+ affectedSurfaces.put(surface, Region.obtain());
+ }
+ final Rect boundaries = new Rect();
+ view.getBoundsOnScreen(boundaries);
+ affectedSurfaces.get(surface).op(boundaries, Region.Op.UNION);
+ });
+ mManager.setTouchRegions(this, affectedSurfaces);
});
-
- mManager.setTouchRegion(this, cumulativeRegion);
-
- cumulativeRegion.recycle();
}
/**
@@ -110,32 +136,18 @@ public class TouchInsetManager {
}
}
- private final HashMap<TouchInsetSession, Region> mDefinedRegions = new HashMap<>();
+ private final HashMap<TouchInsetSession, HashMap<AttachedSurfaceControl, Region>>
+ mSessionRegions = new HashMap<>();
+ private final HashMap<AttachedSurfaceControl, Region> mLastAffectedSurfaces = new HashMap();
private final Executor mExecutor;
- private final View mRootView;
-
- private final View.OnAttachStateChangeListener mAttachListener =
- new View.OnAttachStateChangeListener() {
- @Override
- public void onViewAttachedToWindow(View v) {
- updateTouchInset();
- }
-
- @Override
- public void onViewDetachedFromWindow(View v) {
- }
- };
/**
* Default constructor.
* @param executor An {@link Executor} to marshal all operations on.
- * @param rootView The root {@link View} for all views in sessions.
*/
- public TouchInsetManager(Executor executor, View rootView) {
+ @Inject
+ public TouchInsetManager(@Main Executor executor) {
mExecutor = executor;
- mRootView = rootView;
- mRootView.addOnAttachStateChangeListener(mAttachListener);
-
}
/**
@@ -151,47 +163,68 @@ public class TouchInsetManager {
public ListenableFuture<Boolean> checkWithinTouchRegion(int x, int y) {
return CallbackToFutureAdapter.getFuture(completer -> {
mExecutor.execute(() -> completer.set(
- mDefinedRegions.values().stream().anyMatch(region -> region.contains(x, y))));
+ mLastAffectedSurfaces.values().stream().anyMatch(
+ region -> region.contains(x, y))));
return "DreamOverlayTouchMonitor::checkWithinTouchRegion";
});
}
- private void updateTouchInset() {
- final ViewRootImpl viewRootImpl = mRootView.getViewRootImpl();
-
- if (viewRootImpl == null) {
- return;
- }
+ private void updateTouchInsets() {
+ // Get affected
+ final HashMap<AttachedSurfaceControl, Region> affectedSurfaces = new HashMap<>();
+ mSessionRegions.values().stream().forEach(regionMapping -> {
+ regionMapping.entrySet().stream().forEach(entry -> {
+ final AttachedSurfaceControl surface = entry.getKey();
+ if (!affectedSurfaces.containsKey(surface)) {
+ affectedSurfaces.put(surface, Region.obtain());
+ }
- final Region aggregateRegion = Region.obtain();
+ affectedSurfaces.get(surface).op(entry.getValue(), Region.Op.UNION);
+ });
+ });
- for (Region region : mDefinedRegions.values()) {
- aggregateRegion.op(region, Region.Op.UNION);
- }
+ affectedSurfaces.entrySet().stream().forEach(entry -> {
+ entry.getKey().setTouchableRegion(entry.getValue());
+ });
- viewRootImpl.setTouchableRegion(aggregateRegion);
+ mLastAffectedSurfaces.entrySet().forEach(entry -> {
+ final AttachedSurfaceControl surface = entry.getKey();
+ if (!affectedSurfaces.containsKey(surface)) {
+ surface.setTouchableRegion(null);
+ }
+ entry.getValue().recycle();
+ });
- aggregateRegion.recycle();
+ mLastAffectedSurfaces.clear();
+ mLastAffectedSurfaces.putAll(affectedSurfaces);
}
- protected void setTouchRegion(TouchInsetSession session, Region region) {
- final Region introducedRegion = Region.obtain(region);
+ protected void setTouchRegions(TouchInsetSession session,
+ HashMap<AttachedSurfaceControl, Region> regions) {
mExecutor.execute(() -> {
- mDefinedRegions.put(session, introducedRegion);
- updateTouchInset();
+ recycleRegions(session);
+ mSessionRegions.put(session, regions);
+ updateTouchInsets();
});
}
- private void clearRegion(TouchInsetSession session) {
- mExecutor.execute(() -> {
- final Region storedRegion = mDefinedRegions.remove(session);
+ private void recycleRegions(TouchInsetSession session) {
+ if (!mSessionRegions.containsKey(session)) {
+ Log.w(TAG, "Removing a session with no regions:" + session);
+ return;
+ }
- if (storedRegion != null) {
- storedRegion.recycle();
- }
+ for (Region region : mSessionRegions.get(session).values()) {
+ region.recycle();
+ }
+ }
- updateTouchInset();
+ private void clearRegion(TouchInsetSession session) {
+ mExecutor.execute(() -> {
+ recycleRegions(session);
+ mSessionRegions.remove(session);
+ updateTouchInsets();
});
}
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/dreams/DreamOverlayServiceTest.java b/packages/SystemUI/tests/src/com/android/systemui/dreams/DreamOverlayServiceTest.java
index 67cf2fcfd1a4..430575c1d0c5 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/dreams/DreamOverlayServiceTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/dreams/DreamOverlayServiceTest.java
@@ -19,7 +19,6 @@ package com.android.systemui.dreams;
import static com.google.common.truth.Truth.assertThat;
import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.ArgumentMatchers.isNull;
import static org.mockito.Mockito.clearInvocations;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
@@ -45,9 +44,12 @@ import androidx.test.filters.SmallTest;
import com.android.internal.logging.UiEventLogger;
import com.android.keyguard.KeyguardUpdateMonitor;
import com.android.systemui.SysuiTestCase;
+import com.android.systemui.dreams.complication.ComplicationLayoutEngine;
import com.android.systemui.dreams.complication.dagger.ComplicationComponent;
import com.android.systemui.dreams.dagger.DreamOverlayComponent;
+import com.android.systemui.dreams.dreamcomplication.HideComplicationTouchHandler;
import com.android.systemui.dreams.touch.DreamOverlayTouchMonitor;
+import com.android.systemui.touch.TouchInsetManager;
import com.android.systemui.util.concurrency.FakeExecutor;
import com.android.systemui.util.time.FakeSystemClock;
import com.android.systemui.utils.leaks.LeakCheckedTest;
@@ -94,6 +96,20 @@ public class DreamOverlayServiceTest extends SysuiTestCase {
ComplicationComponent mComplicationComponent;
@Mock
+ ComplicationLayoutEngine mComplicationVisibilityController;
+
+ @Mock
+ com.android.systemui.dreams.dreamcomplication.dagger.ComplicationComponent.Factory
+ mDreamComplicationComponentFactory;
+
+ @Mock
+ com.android.systemui.dreams.dreamcomplication.dagger.ComplicationComponent
+ mDreamComplicationComponent;
+
+ @Mock
+ HideComplicationTouchHandler mHideComplicationTouchHandler;
+
+ @Mock
DreamOverlayComponent.Factory mDreamOverlayComponentFactory;
@Mock
@@ -118,6 +134,9 @@ public class DreamOverlayServiceTest extends SysuiTestCase {
ViewGroup mDreamOverlayContainerViewParent;
@Mock
+ TouchInsetManager mTouchInsetManager;
+
+ @Mock
UiEventLogger mUiEventLogger;
@Captor
@@ -136,25 +155,33 @@ public class DreamOverlayServiceTest extends SysuiTestCase {
when(mDreamOverlayComponent.getDreamOverlayTouchMonitor())
.thenReturn(mDreamOverlayTouchMonitor);
when(mComplicationComponentFactory
- .create())
+ .create(any(), any(), any(), any()))
.thenReturn(mComplicationComponent);
- // TODO(b/261781069): A touch handler should be passed in from the complication component
- // when the complication component is introduced.
+ when(mComplicationComponent.getVisibilityController())
+ .thenReturn(mComplicationVisibilityController);
+ when(mDreamComplicationComponent.getHideComplicationTouchHandler())
+ .thenReturn(mHideComplicationTouchHandler);
+ when(mDreamComplicationComponentFactory
+ .create(any(), any()))
+ .thenReturn(mDreamComplicationComponent);
when(mDreamOverlayComponentFactory
- .create(any(), any(), any(), isNull()))
+ .create(any(), any(), any(), any()))
.thenReturn(mDreamOverlayComponent);
when(mDreamOverlayContainerViewController.getContainerView())
.thenReturn(mDreamOverlayContainerView);
- mService = new DreamOverlayService(mContext,
+ mService = new DreamOverlayService(
+ mContext,
mMainExecutor,
mLifecycleOwner,
mWindowManager,
mComplicationComponentFactory,
+ mDreamComplicationComponentFactory,
mDreamOverlayComponentFactory,
mStateController,
mKeyguardUpdateMonitor,
mUiEventLogger,
+ mTouchInsetManager,
LOW_LIGHT_COMPONENT);
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/touch/TouchInsetManagerTest.java b/packages/SystemUI/tests/src/com/android/systemui/touch/TouchInsetManagerTest.java
index 14b9bfb1393f..a7072225baa7 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/touch/TouchInsetManagerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/touch/TouchInsetManagerTest.java
@@ -26,8 +26,8 @@ import static org.mockito.Mockito.when;
import android.graphics.Rect;
import android.graphics.Region;
import android.testing.AndroidTestingRunner;
+import android.view.AttachedSurfaceControl;
import android.view.View;
-import android.view.ViewRootImpl;
import androidx.test.filters.SmallTest;
@@ -47,41 +47,78 @@ import org.mockito.MockitoAnnotations;
@RunWith(AndroidTestingRunner.class)
public class TouchInsetManagerTest extends SysuiTestCase {
@Mock
- private View mRootView;
-
- @Mock
- private ViewRootImpl mRootViewImpl;
+ private AttachedSurfaceControl mAttachedSurfaceControl;
private FakeExecutor mFakeExecutor = new FakeExecutor(new FakeSystemClock());
@Before
public void setup() {
MockitoAnnotations.initMocks(this);
- when(mRootView.getViewRootImpl()).thenReturn(mRootViewImpl);
}
@Test
- public void testRootViewOnAttachedHandling() {
+ public void testViewOnAttachedHandling() {
// Create inset manager
- final TouchInsetManager insetManager = new TouchInsetManager(mFakeExecutor,
- mRootView);
+ final TouchInsetManager insetManager = new TouchInsetManager(mFakeExecutor);
final ArgumentCaptor<View.OnAttachStateChangeListener> listener =
ArgumentCaptor.forClass(View.OnAttachStateChangeListener.class);
+ final View view = createView(new Rect(0, 0, 0, 0));
+ when(view.isAttachedToWindow()).thenReturn(false);
+
+
+ // Create session
+ final TouchInsetManager.TouchInsetSession session = insetManager.createSession();
+ session.addViewToTracking(view);
+ mFakeExecutor.runAllReady();
// Ensure manager has registered to listen to attached state of root view.
- verify(mRootView).addOnAttachStateChangeListener(listener.capture());
+ verify(view).addOnAttachStateChangeListener(listener.capture());
+
+ clearInvocations(mAttachedSurfaceControl);
+ when(view.isAttachedToWindow()).thenReturn(true);
// Trigger attachment and verify touchable region is set.
- listener.getValue().onViewAttachedToWindow(mRootView);
- verify(mRootViewImpl).setTouchableRegion(any());
+ listener.getValue().onViewAttachedToWindow(view);
+
+ mFakeExecutor.runAllReady();
+
+ verify(mAttachedSurfaceControl).setTouchableRegion(any());
+ }
+
+ @Test
+ public void testViewOnDetachedHandling() {
+ // Create inset manager
+ final TouchInsetManager insetManager = new TouchInsetManager(mFakeExecutor);
+
+ final ArgumentCaptor<View.OnAttachStateChangeListener> listener =
+ ArgumentCaptor.forClass(View.OnAttachStateChangeListener.class);
+ final View view = createView(new Rect(0, 0, 0, 0));
+ when(view.isAttachedToWindow()).thenReturn(true);
+
+ // Create session
+ final TouchInsetManager.TouchInsetSession session = insetManager.createSession();
+ session.addViewToTracking(view);
+
+ mFakeExecutor.runAllReady();
+ // Ensure manager has registered to listen to attached state of root view.
+ verify(view).addOnAttachStateChangeListener(listener.capture());
+
+ clearInvocations(mAttachedSurfaceControl);
+ when(view.isAttachedToWindow()).thenReturn(false);
+
+ // Trigger detachment and verify touchable region is set.
+ listener.getValue().onViewDetachedFromWindow(view);
+
+ mFakeExecutor.runAllReady();
+
+ verify(mAttachedSurfaceControl).setTouchableRegion(any());
}
@Test
public void testInsetRegionPropagation() {
// Create inset manager
- final TouchInsetManager insetManager = new TouchInsetManager(mFakeExecutor,
- mRootView);
+ final TouchInsetManager insetManager = new TouchInsetManager(mFakeExecutor);
// Create session
final TouchInsetManager.TouchInsetSession session = insetManager.createSession();
@@ -95,14 +132,13 @@ public class TouchInsetManagerTest extends SysuiTestCase {
// Check to see if view was properly accounted for.
final Region expectedRegion = Region.obtain();
expectedRegion.op(rect, Region.Op.UNION);
- verify(mRootViewImpl).setTouchableRegion(eq(expectedRegion));
+ verify(mAttachedSurfaceControl).setTouchableRegion(eq(expectedRegion));
}
@Test
public void testMultipleRegions() {
// Create inset manager
- final TouchInsetManager insetManager = new TouchInsetManager(mFakeExecutor,
- mRootView);
+ final TouchInsetManager insetManager = new TouchInsetManager(mFakeExecutor);
// Create session
final TouchInsetManager.TouchInsetSession session = insetManager.createSession();
@@ -112,7 +148,7 @@ public class TouchInsetManagerTest extends SysuiTestCase {
session.addViewToTracking(createView(firstBounds));
mFakeExecutor.runAllReady();
- clearInvocations(mRootViewImpl);
+ clearInvocations(mAttachedSurfaceControl);
// Create second session
final TouchInsetManager.TouchInsetSession secondSession = insetManager.createSession();
@@ -128,27 +164,26 @@ public class TouchInsetManagerTest extends SysuiTestCase {
final Region expectedRegion = Region.obtain();
expectedRegion.op(firstBounds, Region.Op.UNION);
expectedRegion.op(secondBounds, Region.Op.UNION);
- verify(mRootViewImpl).setTouchableRegion(eq(expectedRegion));
+ verify(mAttachedSurfaceControl).setTouchableRegion(eq(expectedRegion));
}
- clearInvocations(mRootViewImpl);
+ clearInvocations(mAttachedSurfaceControl);
// clear first session, ensure second session is still reflected.
session.clear();
mFakeExecutor.runAllReady();
{
final Region expectedRegion = Region.obtain();
- expectedRegion.op(firstBounds, Region.Op.UNION);
- verify(mRootViewImpl).setTouchableRegion(eq(expectedRegion));
+ expectedRegion.op(secondBounds, Region.Op.UNION);
+ verify(mAttachedSurfaceControl).setTouchableRegion(eq(expectedRegion));
}
}
@Test
public void testMultipleViews() {
// Create inset manager
- final TouchInsetManager insetManager = new TouchInsetManager(mFakeExecutor,
- mRootView);
+ final TouchInsetManager insetManager = new TouchInsetManager(mFakeExecutor);
// Create session
final TouchInsetManager.TouchInsetSession session = insetManager.createSession();
@@ -159,7 +194,7 @@ public class TouchInsetManagerTest extends SysuiTestCase {
// only capture second invocation.
mFakeExecutor.runAllReady();
- clearInvocations(mRootViewImpl);
+ clearInvocations(mAttachedSurfaceControl);
// Add a second view to the session
final Rect secondViewBounds = new Rect(4, 4, 9, 10);
@@ -173,20 +208,20 @@ public class TouchInsetManagerTest extends SysuiTestCase {
final Region expectedRegion = Region.obtain();
expectedRegion.op(firstViewBounds, Region.Op.UNION);
expectedRegion.op(secondViewBounds, Region.Op.UNION);
- verify(mRootViewImpl).setTouchableRegion(eq(expectedRegion));
+ verify(mAttachedSurfaceControl).setTouchableRegion(eq(expectedRegion));
}
// Remove second view.
session.removeViewFromTracking(secondView);
- clearInvocations(mRootViewImpl);
+ clearInvocations(mAttachedSurfaceControl);
mFakeExecutor.runAllReady();
// Ensure first view still reflected in touch region.
{
final Region expectedRegion = Region.obtain();
expectedRegion.op(firstViewBounds, Region.Op.UNION);
- verify(mRootViewImpl).setTouchableRegion(eq(expectedRegion));
+ verify(mAttachedSurfaceControl).setTouchableRegion(eq(expectedRegion));
}
}
@@ -197,6 +232,8 @@ public class TouchInsetManagerTest extends SysuiTestCase {
((Rect) invocation.getArgument(0)).set(rect);
return null;
}).when(view).getBoundsOnScreen(any());
+ when(view.isAttachedToWindow()).thenReturn(true);
+ when(view.getRootSurfaceControl()).thenReturn(mAttachedSurfaceControl);
return view;
}