Merge "Create StatusBarBoundsProvider which provided bounds of the left and right side icons" into tm-qpr-dev

This commit is contained in:
TreeHugger Robot
2022-07-21 16:33:55 +00:00
committed by Android (Google) Code Review
9 changed files with 413 additions and 7 deletions

View File

@@ -0,0 +1,92 @@
/*
* 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.statusbar.phone
import android.graphics.Rect
import android.view.View
import com.android.systemui.statusbar.phone.fragment.dagger.StatusBarFragmentComponent
import com.android.systemui.statusbar.phone.fragment.dagger.StatusBarFragmentModule.END_SIDE_CONTENT
import com.android.systemui.statusbar.phone.fragment.dagger.StatusBarFragmentModule.START_SIDE_CONTENT
import com.android.systemui.statusbar.phone.fragment.dagger.StatusBarFragmentScope
import com.android.systemui.util.boundsOnScreen
import javax.inject.Inject
import javax.inject.Named
/** Provides various bounds within the status bar. */
@StatusBarFragmentScope
class StatusBarBoundsProvider
@Inject
constructor(
private val changeListeners: Set<@JvmSuppressWildcards BoundsChangeListener>,
@Named(START_SIDE_CONTENT) private val startSideContent: View,
@Named(END_SIDE_CONTENT) private val endSideContent: View,
) : StatusBarFragmentComponent.Startable {
interface BoundsChangeListener {
fun onStatusBarBoundsChanged()
}
private var previousBounds =
BoundsPair(start = startSideContent.boundsOnScreen, end = endSideContent.boundsOnScreen)
private val layoutListener =
View.OnLayoutChangeListener { _, _, _, _, _, _, _, _, _ ->
val newBounds = BoundsPair(start = visibleStartSideBounds, end = visibleEndSideBounds)
if (previousBounds != newBounds) {
previousBounds = newBounds
changeListeners.forEach { it.onStatusBarBoundsChanged() }
}
}
override fun start() {
startSideContent.addOnLayoutChangeListener(layoutListener)
endSideContent.addOnLayoutChangeListener(layoutListener)
}
override fun stop() {
startSideContent.removeOnLayoutChangeListener(layoutListener)
endSideContent.removeOnLayoutChangeListener(layoutListener)
}
/**
* Returns the bounds of the end side of the status bar that are visible to the user. The end
* side is right when in LTR and is left when in RTL.
*
* Note that even though the layout might be larger, here we only return the bounds for what is
* visible to the user.
*
* The end side of the status bar contains the multi-user switcher and status icons such as
* wi-fi, battery, etc
*/
val visibleEndSideBounds: Rect
get() = endSideContent.boundsOnScreen
/**
* Returns the bounds of the start side of the status bar that are visible to the user. The
* start side is left when in LTR and is right when in RTL.
*
* Note that even though the layout might be larger, here we only return the bounds for what is
* visible to the user.
*
* The start side of the status bar contains the operator name, clock, on-going call chip, and
* notifications.
*/
val visibleStartSideBounds: Rect
get() = startSideContent.boundsOnScreen
}
private data class BoundsPair(val start: Rect, val end: Rect)

View File

@@ -30,6 +30,7 @@ import com.android.systemui.battery.BatteryMeterViewController;
import com.android.systemui.biometrics.AuthRippleView; import com.android.systemui.biometrics.AuthRippleView;
import com.android.systemui.broadcast.BroadcastDispatcher; import com.android.systemui.broadcast.BroadcastDispatcher;
import com.android.systemui.dagger.qualifiers.Main; import com.android.systemui.dagger.qualifiers.Main;
import com.android.systemui.dump.DumpManager;
import com.android.systemui.flags.FeatureFlags; import com.android.systemui.flags.FeatureFlags;
import com.android.systemui.flags.Flags; import com.android.systemui.flags.Flags;
import com.android.systemui.plugins.statusbar.StatusBarStateController; import com.android.systemui.plugins.statusbar.StatusBarStateController;
@@ -269,7 +270,8 @@ public abstract class StatusBarViewModule {
CollapsedStatusBarFragmentLogger collapsedStatusBarFragmentLogger, CollapsedStatusBarFragmentLogger collapsedStatusBarFragmentLogger,
OperatorNameViewController.Factory operatorNameViewControllerFactory, OperatorNameViewController.Factory operatorNameViewControllerFactory,
SecureSettings secureSettings, SecureSettings secureSettings,
@Main Executor mainExecutor @Main Executor mainExecutor,
DumpManager dumpManager
) { ) {
return new CollapsedStatusBarFragment(statusBarFragmentComponentFactory, return new CollapsedStatusBarFragment(statusBarFragmentComponentFactory,
ongoingCallController, ongoingCallController,
@@ -289,7 +291,8 @@ public abstract class StatusBarViewModule {
collapsedStatusBarFragmentLogger, collapsedStatusBarFragmentLogger,
operatorNameViewControllerFactory, operatorNameViewControllerFactory,
secureSettings, secureSettings,
mainExecutor); mainExecutor,
dumpManager);
} }
/** /**

View File

@@ -34,6 +34,8 @@ import android.os.Parcelable;
import android.os.UserHandle; import android.os.UserHandle;
import android.provider.Settings; import android.provider.Settings;
import android.telephony.SubscriptionManager; import android.telephony.SubscriptionManager;
import android.util.ArrayMap;
import android.util.IndentingPrintWriter;
import android.util.SparseArray; import android.util.SparseArray;
import android.view.LayoutInflater; import android.view.LayoutInflater;
import android.view.View; import android.view.View;
@@ -43,9 +45,11 @@ import android.widget.LinearLayout;
import androidx.annotation.VisibleForTesting; import androidx.annotation.VisibleForTesting;
import com.android.systemui.Dumpable;
import com.android.systemui.R; import com.android.systemui.R;
import com.android.systemui.animation.Interpolators; import com.android.systemui.animation.Interpolators;
import com.android.systemui.dagger.qualifiers.Main; import com.android.systemui.dagger.qualifiers.Main;
import com.android.systemui.dump.DumpManager;
import com.android.systemui.flags.FeatureFlags; import com.android.systemui.flags.FeatureFlags;
import com.android.systemui.plugins.statusbar.StatusBarStateController; import com.android.systemui.plugins.statusbar.StatusBarStateController;
import com.android.systemui.shade.NotificationPanelViewController; import com.android.systemui.shade.NotificationPanelViewController;
@@ -66,6 +70,7 @@ import com.android.systemui.statusbar.phone.StatusBarIconController;
import com.android.systemui.statusbar.phone.StatusBarIconController.DarkIconManager; import com.android.systemui.statusbar.phone.StatusBarIconController.DarkIconManager;
import com.android.systemui.statusbar.phone.StatusBarLocationPublisher; import com.android.systemui.statusbar.phone.StatusBarLocationPublisher;
import com.android.systemui.statusbar.phone.fragment.dagger.StatusBarFragmentComponent; import com.android.systemui.statusbar.phone.fragment.dagger.StatusBarFragmentComponent;
import com.android.systemui.statusbar.phone.fragment.dagger.StatusBarFragmentComponent.Startable;
import com.android.systemui.statusbar.phone.ongoingcall.OngoingCallController; import com.android.systemui.statusbar.phone.ongoingcall.OngoingCallController;
import com.android.systemui.statusbar.phone.ongoingcall.OngoingCallListener; import com.android.systemui.statusbar.phone.ongoingcall.OngoingCallListener;
import com.android.systemui.statusbar.phone.panelstate.PanelExpansionStateManager; import com.android.systemui.statusbar.phone.panelstate.PanelExpansionStateManager;
@@ -76,9 +81,12 @@ import com.android.systemui.util.CarrierConfigTracker.CarrierConfigChangedListen
import com.android.systemui.util.CarrierConfigTracker.DefaultDataSubscriptionChangedListener; import com.android.systemui.util.CarrierConfigTracker.DefaultDataSubscriptionChangedListener;
import com.android.systemui.util.settings.SecureSettings; import com.android.systemui.util.settings.SecureSettings;
import java.io.PrintWriter;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.List; import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.Executor; import java.util.concurrent.Executor;
/** /**
@@ -89,7 +97,7 @@ import java.util.concurrent.Executor;
@SuppressLint("ValidFragment") @SuppressLint("ValidFragment")
public class CollapsedStatusBarFragment extends Fragment implements CommandQueue.Callbacks, public class CollapsedStatusBarFragment extends Fragment implements CommandQueue.Callbacks,
StatusBarStateController.StateListener, StatusBarStateController.StateListener,
SystemStatusAnimationCallback { SystemStatusAnimationCallback, Dumpable {
public static final String TAG = "CollapsedStatusBarFragment"; public static final String TAG = "CollapsedStatusBarFragment";
private static final String EXTRA_PANEL_STATE = "panel_state"; private static final String EXTRA_PANEL_STATE = "panel_state";
@@ -124,8 +132,10 @@ public class CollapsedStatusBarFragment extends Fragment implements CommandQueue
private final StatusBarHideIconsForBouncerManager mStatusBarHideIconsForBouncerManager; private final StatusBarHideIconsForBouncerManager mStatusBarHideIconsForBouncerManager;
private final SecureSettings mSecureSettings; private final SecureSettings mSecureSettings;
private final Executor mMainExecutor; private final Executor mMainExecutor;
private final DumpManager mDumpManager;
private List<String> mBlockedIcons = new ArrayList<>(); private List<String> mBlockedIcons = new ArrayList<>();
private Map<Startable, Startable.State> mStartableStates = new ArrayMap<>();
private SignalCallback mSignalCallback = new SignalCallback() { private SignalCallback mSignalCallback = new SignalCallback() {
@Override @Override
@@ -185,7 +195,8 @@ public class CollapsedStatusBarFragment extends Fragment implements CommandQueue
CollapsedStatusBarFragmentLogger collapsedStatusBarFragmentLogger, CollapsedStatusBarFragmentLogger collapsedStatusBarFragmentLogger,
OperatorNameViewController.Factory operatorNameViewControllerFactory, OperatorNameViewController.Factory operatorNameViewControllerFactory,
SecureSettings secureSettings, SecureSettings secureSettings,
@Main Executor mainExecutor @Main Executor mainExecutor,
DumpManager dumpManager
) { ) {
mStatusBarFragmentComponentFactory = statusBarFragmentComponentFactory; mStatusBarFragmentComponentFactory = statusBarFragmentComponentFactory;
mOngoingCallController = ongoingCallController; mOngoingCallController = ongoingCallController;
@@ -206,6 +217,7 @@ public class CollapsedStatusBarFragment extends Fragment implements CommandQueue
mOperatorNameViewControllerFactory = operatorNameViewControllerFactory; mOperatorNameViewControllerFactory = operatorNameViewControllerFactory;
mSecureSettings = secureSettings; mSecureSettings = secureSettings;
mMainExecutor = mainExecutor; mMainExecutor = mainExecutor;
mDumpManager = dumpManager;
} }
@Override @Override
@@ -217,8 +229,15 @@ public class CollapsedStatusBarFragment extends Fragment implements CommandQueue
@Override @Override
public void onViewCreated(View view, @Nullable Bundle savedInstanceState) { public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState); super.onViewCreated(view, savedInstanceState);
mDumpManager.registerDumpable(getClass().getSimpleName(), this);
mStatusBarFragmentComponent = mStatusBarFragmentComponentFactory.create(this); mStatusBarFragmentComponent = mStatusBarFragmentComponentFactory.create(this);
mStatusBarFragmentComponent.init(); mStatusBarFragmentComponent.init();
mStartableStates.clear();
for (Startable startable : mStatusBarFragmentComponent.getStartables()) {
mStartableStates.put(startable, Startable.State.STARTING);
startable.start();
mStartableStates.put(startable, Startable.State.STARTED);
}
mStatusBar = (PhoneStatusBarView) view; mStatusBar = (PhoneStatusBarView) view;
View contents = mStatusBar.findViewById(R.id.status_bar_contents); View contents = mStatusBar.findViewById(R.id.status_bar_contents);
@@ -321,6 +340,13 @@ public class CollapsedStatusBarFragment extends Fragment implements CommandQueue
} }
mCarrierConfigTracker.removeCallback(mCarrierConfigCallback); mCarrierConfigTracker.removeCallback(mCarrierConfigCallback);
mCarrierConfigTracker.removeDataSubscriptionChangedListener(mDefaultDataListener); mCarrierConfigTracker.removeDataSubscriptionChangedListener(mDefaultDataListener);
for (Startable startable : mStatusBarFragmentComponent.getStartables()) {
mStartableStates.put(startable, Startable.State.STOPPING);
startable.stop();
mStartableStates.put(startable, Startable.State.STOPPED);
}
mDumpManager.unregisterDumpable(getClass().getSimpleName());
} }
/** Initializes views related to the notification icon area. */ /** Initializes views related to the notification icon area. */
@@ -670,4 +696,23 @@ public class CollapsedStatusBarFragment extends Fragment implements CommandQueue
updateStatusBarLocation(left, right); updateStatusBarLocation(left, right);
} }
}; };
@Override
public void dump(PrintWriter printWriter, String[] args) {
IndentingPrintWriter pw = new IndentingPrintWriter(printWriter, /* singleIndent= */" ");
StatusBarFragmentComponent component = mStatusBarFragmentComponent;
if (component == null) {
pw.println("StatusBarFragmentComponent is null");
} else {
Set<Startable> startables = component.getStartables();
pw.println("Startables: " + startables.size());
pw.increaseIndent();
for (Startable startable : startables) {
Startable.State startableState = mStartableStates.getOrDefault(startable,
Startable.State.NONE);
pw.println(startable + ", state: " + startableState);
}
pw.decreaseIndent();
}
}
} }

View File

@@ -23,9 +23,12 @@ import com.android.systemui.statusbar.phone.LightsOutNotifController;
import com.android.systemui.statusbar.phone.PhoneStatusBarTransitions; import com.android.systemui.statusbar.phone.PhoneStatusBarTransitions;
import com.android.systemui.statusbar.phone.PhoneStatusBarView; import com.android.systemui.statusbar.phone.PhoneStatusBarView;
import com.android.systemui.statusbar.phone.PhoneStatusBarViewController; import com.android.systemui.statusbar.phone.PhoneStatusBarViewController;
import com.android.systemui.statusbar.phone.StatusBarBoundsProvider;
import com.android.systemui.statusbar.phone.StatusBarDemoMode; import com.android.systemui.statusbar.phone.StatusBarDemoMode;
import com.android.systemui.statusbar.phone.fragment.CollapsedStatusBarFragment; import com.android.systemui.statusbar.phone.fragment.CollapsedStatusBarFragment;
import java.util.Set;
import dagger.BindsInstance; import dagger.BindsInstance;
import dagger.Subcomponent; import dagger.Subcomponent;
@@ -41,7 +44,10 @@ import dagger.Subcomponent;
* should be included here or in {@link StatusBarFragmentModule}. * should be included here or in {@link StatusBarFragmentModule}.
*/ */
@Subcomponent(modules = {StatusBarFragmentModule.class}) @Subcomponent(modules = {
StatusBarFragmentModule.class,
StatusBarStartablesModule.class
})
@StatusBarFragmentScope @StatusBarFragmentScope
public interface StatusBarFragmentComponent { public interface StatusBarFragmentComponent {
/** Simple factory. */ /** Simple factory. */
@@ -51,6 +57,18 @@ public interface StatusBarFragmentComponent {
@BindsInstance CollapsedStatusBarFragment collapsedStatusBarFragment); @BindsInstance CollapsedStatusBarFragment collapsedStatusBarFragment);
} }
/**
* Performs initialization logic after {@link StatusBarFragmentComponent} has been constructed.
*/
interface Startable {
void start();
void stop();
enum State {
NONE, STARTING, STARTED, STOPPING, STOPPED
}
}
/** /**
* Initialize anything extra for the component. Must be called after the component is created. * Initialize anything extra for the component. Must be called after the component is created.
*/ */
@@ -92,4 +110,10 @@ public interface StatusBarFragmentComponent {
/** */ /** */
@StatusBarFragmentScope @StatusBarFragmentScope
PhoneStatusBarTransitions getPhoneStatusBarTransitions(); PhoneStatusBarTransitions getPhoneStatusBarTransitions();
/** */
Set<Startable> getStartables();
/** */
StatusBarBoundsProvider getBoundsProvider();
} }

View File

@@ -26,6 +26,7 @@ import com.android.systemui.statusbar.HeadsUpStatusBarView;
import com.android.systemui.statusbar.phone.PhoneStatusBarTransitions; import com.android.systemui.statusbar.phone.PhoneStatusBarTransitions;
import com.android.systemui.statusbar.phone.PhoneStatusBarView; import com.android.systemui.statusbar.phone.PhoneStatusBarView;
import com.android.systemui.statusbar.phone.PhoneStatusBarViewController; import com.android.systemui.statusbar.phone.PhoneStatusBarViewController;
import com.android.systemui.statusbar.phone.StatusBarBoundsProvider;
import com.android.systemui.statusbar.phone.fragment.CollapsedStatusBarFragment; import com.android.systemui.statusbar.phone.fragment.CollapsedStatusBarFragment;
import com.android.systemui.statusbar.phone.userswitcher.StatusBarUserSwitcherContainer; import com.android.systemui.statusbar.phone.userswitcher.StatusBarUserSwitcherContainer;
import com.android.systemui.statusbar.phone.userswitcher.StatusBarUserSwitcherController; import com.android.systemui.statusbar.phone.userswitcher.StatusBarUserSwitcherController;
@@ -34,12 +35,14 @@ import com.android.systemui.statusbar.policy.Clock;
import com.android.systemui.statusbar.window.StatusBarWindowController; import com.android.systemui.statusbar.window.StatusBarWindowController;
import java.util.Optional; import java.util.Optional;
import java.util.Set;
import javax.inject.Named; import javax.inject.Named;
import dagger.Binds; import dagger.Binds;
import dagger.Module; import dagger.Module;
import dagger.Provides; import dagger.Provides;
import dagger.multibindings.Multibinds;
/** Dagger module for {@link StatusBarFragmentComponent}. */ /** Dagger module for {@link StatusBarFragmentComponent}. */
@Module @Module
@@ -48,6 +51,8 @@ public interface StatusBarFragmentModule {
String LIGHTS_OUT_NOTIF_VIEW = "lights_out_notif_view"; String LIGHTS_OUT_NOTIF_VIEW = "lights_out_notif_view";
String OPERATOR_NAME_VIEW = "operator_name_view"; String OPERATOR_NAME_VIEW = "operator_name_view";
String OPERATOR_NAME_FRAME_VIEW = "operator_name_frame_view"; String OPERATOR_NAME_FRAME_VIEW = "operator_name_frame_view";
String START_SIDE_CONTENT = "start_side_content";
String END_SIDE_CONTENT = "end_side_content";
/** */ /** */
@Provides @Provides
@@ -65,6 +70,22 @@ public interface StatusBarFragmentModule {
return view.findViewById(R.id.battery); return view.findViewById(R.id.battery);
} }
/** */
@Provides
@StatusBarFragmentScope
@Named(START_SIDE_CONTENT)
static View startSideContent(@RootView PhoneStatusBarView view) {
return view.findViewById(R.id.status_bar_start_side_content);
}
/** */
@Provides
@StatusBarFragmentScope
@Named(END_SIDE_CONTENT)
static View endSideContent(@RootView PhoneStatusBarView view) {
return view.findViewById(R.id.status_bar_end_side_content);
}
/** */ /** */
@Provides @Provides
@StatusBarFragmentScope @StatusBarFragmentScope
@@ -138,4 +159,8 @@ public interface StatusBarFragmentModule {
static HeadsUpStatusBarView providesHeasdUpStatusBarView(@RootView PhoneStatusBarView view) { static HeadsUpStatusBarView providesHeasdUpStatusBarView(@RootView PhoneStatusBarView view) {
return view.findViewById(R.id.heads_up_status_bar_view); return view.findViewById(R.id.heads_up_status_bar_view);
} }
/** */
@Multibinds
Set<StatusBarBoundsProvider.BoundsChangeListener> boundsChangeListeners();
} }

View File

@@ -0,0 +1,32 @@
/*
* 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.statusbar.phone.fragment.dagger
import com.android.systemui.statusbar.phone.StatusBarBoundsProvider
import dagger.Binds
import dagger.Module
import dagger.multibindings.IntoSet
@Module
internal interface StatusBarStartablesModule {
@Binds
@IntoSet
fun statusBarBoundsCalculator(
statusBarBoundsProvider: StatusBarBoundsProvider
): StatusBarFragmentComponent.Startable
}

View File

@@ -16,7 +16,9 @@
package com.android.systemui.util package com.android.systemui.util
import android.graphics.Rect
import android.util.IndentingPrintWriter import android.util.IndentingPrintWriter
import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
import java.io.PrintWriter import java.io.PrintWriter
@@ -45,4 +47,12 @@ inline fun PrintWriter.indentIfPossible(block: PrintWriter.() -> Unit) {
if (this is IndentingPrintWriter) increaseIndent() if (this is IndentingPrintWriter) increaseIndent()
block() block()
if (this is IndentingPrintWriter) decreaseIndent() if (this is IndentingPrintWriter) decreaseIndent()
} }
/** Convenience extension property for [View.getBoundsOnScreen]. */
val View.boundsOnScreen: Rect
get() {
val bounds = Rect()
getBoundsOnScreen(bounds)
return bounds
}

View File

@@ -0,0 +1,171 @@
/*
* 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.statusbar.phone
import android.graphics.Rect
import android.testing.AndroidTestingRunner
import android.testing.TestableLooper.RunWithLooper
import android.view.View
import android.widget.FrameLayout
import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase
import com.android.systemui.statusbar.phone.StatusBarBoundsProvider.BoundsChangeListener
import com.google.common.truth.Truth.assertThat
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
import org.mockito.Mock
import org.mockito.Mockito.any
import org.mockito.Mockito.doAnswer
import org.mockito.Mockito.never
import org.mockito.Mockito.spy
import org.mockito.Mockito.verify
import org.mockito.MockitoAnnotations
@RunWith(AndroidTestingRunner::class)
@RunWithLooper(setAsMainLooper = true)
@SmallTest
class StatusBarBoundsProviderTest : SysuiTestCase() {
companion object {
private val START_SIDE_BOUNDS = Rect(50, 100, 150, 200)
private val END_SIDE_BOUNDS = Rect(250, 300, 350, 400)
}
@Mock private lateinit var boundsChangeListener: BoundsChangeListener
private lateinit var boundsProvider: StatusBarBoundsProvider
private lateinit var startSideContent: View
private lateinit var endSideContent: View
@Before
fun setUp() {
MockitoAnnotations.initMocks(this)
startSideContent = spy(FrameLayout(context)).apply { setBoundsOnScreen(START_SIDE_BOUNDS) }
endSideContent = spy(FrameLayout(context)).apply { setBoundsOnScreen(END_SIDE_BOUNDS) }
boundsProvider =
StatusBarBoundsProvider(setOf(boundsChangeListener), startSideContent, endSideContent)
}
@Test
fun visibleStartSideBounds_returnsBoundsFromStartSideContentView() {
assertThat(boundsProvider.visibleStartSideBounds).isEqualTo(START_SIDE_BOUNDS)
}
@Test
fun visibleEndSideBounds_returnsBoundsFromEndSideContentView() {
assertThat(boundsProvider.visibleEndSideBounds).isEqualTo(END_SIDE_BOUNDS)
}
@Test
fun startBoundsChange_afterStart_notifiesListener() {
boundsProvider.start()
val newBounds = Rect(START_SIDE_BOUNDS).apply { left += 1 }
startSideContent.setBoundsOnScreen(newBounds)
verify(boundsChangeListener).onStatusBarBoundsChanged()
}
@Test
fun startBoundsChange_beforeStart_doesNotNotifyListener() {
val newBounds = Rect(START_SIDE_BOUNDS).apply { left += 1 }
startSideContent.setBoundsOnScreen(newBounds)
verify(boundsChangeListener, never()).onStatusBarBoundsChanged()
}
@Test
fun startBoundsChange_afterStop_doesNotNotifyListener() {
boundsProvider.start()
boundsProvider.stop()
val newBounds = Rect(START_SIDE_BOUNDS).apply { left += 1 }
startSideContent.setBoundsOnScreen(newBounds)
verify(boundsChangeListener, never()).onStatusBarBoundsChanged()
}
@Test
fun startLayoutChange_afterStart_boundsOnScreenSame_doesNotNotifyListener() {
boundsProvider.start()
val newBounds = Rect(START_SIDE_BOUNDS).apply { left += 1 }
startSideContent.layout(newBounds)
verify(boundsChangeListener, never()).onStatusBarBoundsChanged()
}
@Test
fun endBoundsChange_afterStart_notifiesListener() {
boundsProvider.start()
val newBounds = Rect(START_SIDE_BOUNDS).apply { right += 1 }
endSideContent.setBoundsOnScreen(newBounds)
verify(boundsChangeListener).onStatusBarBoundsChanged()
}
@Test
fun endBoundsChange_beforeStart_doesNotNotifyListener() {
val newBounds = Rect(START_SIDE_BOUNDS).apply { right += 1 }
endSideContent.setBoundsOnScreen(newBounds)
verify(boundsChangeListener, never()).onStatusBarBoundsChanged()
}
@Test
fun endBoundsChange_afterStop_doesNotNotifyListener() {
boundsProvider.start()
boundsProvider.stop()
val newBounds = Rect(START_SIDE_BOUNDS).apply { right += 1 }
endSideContent.setBoundsOnScreen(newBounds)
verify(boundsChangeListener, never()).onStatusBarBoundsChanged()
}
@Test
fun endLayoutChange_afterStart_boundsOnScreenSame_doesNotNotifyListener() {
boundsProvider.start()
val newBounds = Rect(START_SIDE_BOUNDS).apply { right += 1 }
endSideContent.layout(newBounds)
verify(boundsChangeListener, never()).onStatusBarBoundsChanged()
}
}
private fun View.setBoundsOnScreen(bounds: Rect) {
doAnswer { invocation ->
val boundsOutput = invocation.arguments[0] as Rect
boundsOutput.set(bounds)
return@doAnswer Unit
}
.`when`(this)
.getBoundsOnScreen(any())
layout(bounds.left, bounds.top, bounds.right, bounds.bottom)
}
private fun View.layout(rect: Rect) {
layout(rect.left, rect.top, rect.right, rect.bottom)
}

View File

@@ -41,6 +41,7 @@ import androidx.test.filters.SmallTest;
import com.android.systemui.R; import com.android.systemui.R;
import com.android.systemui.SysuiBaseFragmentTest; import com.android.systemui.SysuiBaseFragmentTest;
import com.android.systemui.dump.DumpManager;
import com.android.systemui.flags.FeatureFlags; import com.android.systemui.flags.FeatureFlags;
import com.android.systemui.log.LogBuffer; import com.android.systemui.log.LogBuffer;
import com.android.systemui.log.LogcatEchoTracker; import com.android.systemui.log.LogcatEchoTracker;
@@ -107,6 +108,8 @@ public class CollapsedStatusBarFragmentTest extends SysuiBaseFragmentTest {
private NotificationPanelViewController mNotificationPanelViewController; private NotificationPanelViewController mNotificationPanelViewController;
@Mock @Mock
private StatusBarHideIconsForBouncerManager mStatusBarHideIconsForBouncerManager; private StatusBarHideIconsForBouncerManager mStatusBarHideIconsForBouncerManager;
@Mock
private DumpManager mDumpManager;
public CollapsedStatusBarFragmentTest() { public CollapsedStatusBarFragmentTest() {
super(CollapsedStatusBarFragment.class); super(CollapsedStatusBarFragment.class);
@@ -386,7 +389,8 @@ public class CollapsedStatusBarFragmentTest extends SysuiBaseFragmentTest {
), ),
mOperatorNameViewControllerFactory, mOperatorNameViewControllerFactory,
mSecureSettings, mSecureSettings,
mExecutor); mExecutor,
mDumpManager);
} }
private void setUpDaggerComponent() { private void setUpDaggerComponent() {