Merge "[SB Refactor] Define a new status bar wifi view that can be swapped in/out with the old view. Define a skeleton ViewBinder for the new view." into tm-qpr-dev

This commit is contained in:
Caitlin Shkuratov
2022-08-23 16:27:46 +00:00
committed by Android (Google) Code Review
26 changed files with 560 additions and 118 deletions

View File

@@ -0,0 +1,28 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
**
** Copyright 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.
*/
-->
<com.android.systemui.statusbar.pipeline.wifi.ui.view.ModernStatusBarWifiView
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/wifi_combo"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:gravity="center_vertical" >
<include layout="@layout/status_bar_wifi_group_inner" />
</com.android.systemui.statusbar.pipeline.wifi.ui.view.ModernStatusBarWifiView>

View File

@@ -18,70 +18,11 @@
--> -->
<com.android.systemui.statusbar.StatusBarWifiView <com.android.systemui.statusbar.StatusBarWifiView
xmlns:android="http://schemas.android.com/apk/res/android" xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:systemui="http://schemas.android.com/apk/res-auto"
android:id="@+id/wifi_combo" android:id="@+id/wifi_combo"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="match_parent" android:layout_height="match_parent"
android:gravity="center_vertical" > android:gravity="center_vertical" >
<com.android.keyguard.AlphaOptimizedLinearLayout <include layout="@layout/status_bar_wifi_group_inner" />
android:id="@+id/wifi_group"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:gravity="center_vertical"
android:layout_marginStart="2.5dp"
>
<FrameLayout
android:id="@+id/inout_container"
android:layout_height="17dp"
android:layout_width="wrap_content"
android:gravity="center_vertical" >
<ImageView
android:id="@+id/wifi_in"
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:src="@drawable/ic_activity_down"
android:visibility="gone"
android:paddingEnd="2dp"
/>
<ImageView
android:id="@+id/wifi_out"
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:src="@drawable/ic_activity_up"
android:paddingEnd="2dp"
android:visibility="gone"
/>
</FrameLayout>
<FrameLayout
android:id="@+id/wifi_combo"
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:gravity="center_vertical" >
<com.android.systemui.statusbar.AlphaOptimizedImageView
android:id="@+id/wifi_signal"
android:layout_height="@dimen/status_bar_wifi_signal_size"
android:layout_width="@dimen/status_bar_wifi_signal_size" />
</FrameLayout>
<View
android:id="@+id/wifi_signal_spacer"
android:layout_width="@dimen/status_bar_wifi_signal_spacer_width"
android:layout_height="4dp"
android:visibility="gone" />
<!-- Looks like CarStatusBar uses this... -->
<ViewStub
android:id="@+id/connected_device_signals_stub"
android:layout="@layout/connected_device_signal"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<View
android:id="@+id/wifi_airplane_spacer"
android:layout_width="@dimen/status_bar_airplane_spacer_width"
android:layout_height="4dp"
android:visibility="gone"
/>
</com.android.keyguard.AlphaOptimizedLinearLayout>
</com.android.systemui.statusbar.StatusBarWifiView> </com.android.systemui.statusbar.StatusBarWifiView>

View File

@@ -0,0 +1,82 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
**
** Copyright 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.
*/
-->
<merge xmlns:android="http://schemas.android.com/apk/res/android">
<com.android.keyguard.AlphaOptimizedLinearLayout
android:id="@+id/wifi_group"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:gravity="center_vertical"
android:layout_marginStart="2.5dp"
>
<FrameLayout
android:id="@+id/inout_container"
android:layout_height="17dp"
android:layout_width="wrap_content"
android:gravity="center_vertical" >
<ImageView
android:id="@+id/wifi_in"
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:src="@drawable/ic_activity_down"
android:visibility="gone"
android:paddingEnd="2dp"
/>
<ImageView
android:id="@+id/wifi_out"
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:src="@drawable/ic_activity_up"
android:paddingEnd="2dp"
android:visibility="gone"
/>
</FrameLayout>
<FrameLayout
android:id="@+id/wifi_combo"
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:gravity="center_vertical" >
<com.android.systemui.statusbar.AlphaOptimizedImageView
android:id="@+id/wifi_signal"
android:layout_height="@dimen/status_bar_wifi_signal_size"
android:layout_width="@dimen/status_bar_wifi_signal_size" />
</FrameLayout>
<View
android:id="@+id/wifi_signal_spacer"
android:layout_width="@dimen/status_bar_wifi_signal_spacer_width"
android:layout_height="4dp"
android:visibility="gone" />
<!-- Looks like CarStatusBar uses this... -->
<ViewStub
android:id="@+id/connected_device_signals_stub"
android:layout="@layout/connected_device_signal"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<View
android:id="@+id/wifi_airplane_spacer"
android:layout_width="@dimen/status_bar_airplane_spacer_width"
android:layout_height="4dp"
android:visibility="gone"
/>
</com.android.keyguard.AlphaOptimizedLinearLayout>
</merge>

View File

@@ -155,7 +155,11 @@ public class Flags {
public static final ReleasedFlag STATUS_BAR_LETTERBOX_APPEARANCE = public static final ReleasedFlag STATUS_BAR_LETTERBOX_APPEARANCE =
new ReleasedFlag(603, false); new ReleasedFlag(603, false);
public static final UnreleasedFlag NEW_STATUS_BAR_PIPELINE = new UnreleasedFlag(604, true); public static final UnreleasedFlag NEW_STATUS_BAR_PIPELINE_BACKEND =
new UnreleasedFlag(604, true);
public static final UnreleasedFlag NEW_STATUS_BAR_PIPELINE_FRONTEND =
new UnreleasedFlag(605, true);
/***************************************/ /***************************************/
// 700 - dialer/calls // 700 - dialer/calls

View File

@@ -80,7 +80,8 @@ class QuickStatusBarHeaderController extends ViewController<QuickStatusBarHeader
FeatureFlags featureFlags, FeatureFlags featureFlags,
VariableDateViewController.Factory variableDateViewControllerFactory, VariableDateViewController.Factory variableDateViewControllerFactory,
BatteryMeterViewController batteryMeterViewController, BatteryMeterViewController batteryMeterViewController,
StatusBarContentInsetsProvider statusBarContentInsetsProvider) { StatusBarContentInsetsProvider statusBarContentInsetsProvider,
StatusBarIconController.TintedIconManager.Factory tintedIconManagerFactory) {
super(view); super(view);
mPrivacyIconsController = headerPrivacyIconsController; mPrivacyIconsController = headerPrivacyIconsController;
mStatusBarIconController = statusBarIconController; mStatusBarIconController = statusBarIconController;
@@ -103,7 +104,7 @@ class QuickStatusBarHeaderController extends ViewController<QuickStatusBarHeader
mView.requireViewById(R.id.date_clock) mView.requireViewById(R.id.date_clock)
); );
mIconManager = new StatusBarIconController.TintedIconManager(mIconContainer, featureFlags); mIconManager = tintedIconManagerFactory.create(mIconContainer);
mDemoModeReceiver = new ClockDemoModeReceiver(mClockView); mDemoModeReceiver = new ClockDemoModeReceiver(mClockView);
mColorExtractor = colorExtractor; mColorExtractor = colorExtractor;
mOnColorsChangedListener = (extractor, which) -> { mOnColorsChangedListener = (extractor, which) -> {

View File

@@ -77,6 +77,7 @@ import javax.inject.Named
class LargeScreenShadeHeaderController @Inject constructor( class LargeScreenShadeHeaderController @Inject constructor(
@Named(LARGE_SCREEN_SHADE_HEADER) private val header: View, @Named(LARGE_SCREEN_SHADE_HEADER) private val header: View,
private val statusBarIconController: StatusBarIconController, private val statusBarIconController: StatusBarIconController,
private val tintedIconManagerFactory: StatusBarIconController.TintedIconManager.Factory,
private val privacyIconsController: HeaderPrivacyIconsController, private val privacyIconsController: HeaderPrivacyIconsController,
private val insetsProvider: StatusBarContentInsetsProvider, private val insetsProvider: StatusBarContentInsetsProvider,
private val configurationController: ConfigurationController, private val configurationController: ConfigurationController,
@@ -259,7 +260,7 @@ class LargeScreenShadeHeaderController @Inject constructor(
batteryMeterViewController.ignoreTunerUpdates() batteryMeterViewController.ignoreTunerUpdates()
batteryIcon.setPercentShowMode(BatteryMeterView.MODE_ESTIMATE) batteryIcon.setPercentShowMode(BatteryMeterView.MODE_ESTIMATE)
iconManager = StatusBarIconController.TintedIconManager(iconContainer, featureFlags) iconManager = tintedIconManagerFactory.create(iconContainer)
iconManager.setTint( iconManager.setTint(
Utils.getColorAttrDefaultColor(header.context, android.R.attr.textColorPrimary) Utils.getColorAttrDefaultColor(header.context, android.R.attr.textColorPrimary)
) )

View File

@@ -0,0 +1,34 @@
/*
* 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
import android.content.Context
import android.util.AttributeSet
import android.widget.FrameLayout
/**
* A temporary base class that's shared between our old status bar wifi view implementation
* ([StatusBarWifiView]) and our new status bar wifi view implementation
* ([ModernStatusBarWifiView]).
*
* Once our refactor is over, we should be able to delete this go-between class and the old view
* class.
*/
abstract class BaseStatusBarWifiView @JvmOverloads constructor(
context: Context,
attrs: AttributeSet? = null,
defStyleAttrs: Int = 0,
) : FrameLayout(context, attrs, defStyleAttrs), StatusIconDisplayable

View File

@@ -28,7 +28,6 @@ import android.util.AttributeSet;
import android.view.Gravity; import android.view.Gravity;
import android.view.LayoutInflater; import android.view.LayoutInflater;
import android.view.View; import android.view.View;
import android.widget.FrameLayout;
import android.widget.ImageView; import android.widget.ImageView;
import android.widget.LinearLayout; import android.widget.LinearLayout;
@@ -41,8 +40,7 @@ import java.util.ArrayList;
/** /**
* Start small: StatusBarWifiView will be able to layout from a WifiIconState * Start small: StatusBarWifiView will be able to layout from a WifiIconState
*/ */
public class StatusBarWifiView extends FrameLayout implements DarkReceiver, public class StatusBarWifiView extends BaseStatusBarWifiView implements DarkReceiver {
StatusIconDisplayable {
private static final String TAG = "StatusBarWifiView"; private static final String TAG = "StatusBarWifiView";
/// Used to show etc dots /// Used to show etc dots
@@ -80,11 +78,6 @@ public class StatusBarWifiView extends FrameLayout implements DarkReceiver,
super(context, attrs, defStyleAttr); super(context, attrs, defStyleAttr);
} }
public StatusBarWifiView(Context context, AttributeSet attrs, int defStyleAttr,
int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
}
public void setSlot(String slot) { public void setSlot(String slot) {
mSlot = slot; mSlot = slot;
} }

View File

@@ -23,7 +23,7 @@ import com.android.settingslib.SignalIcon.IconGroup;
/** */ /** */
public class WifiIcons { public class WifiIcons {
static final int[] WIFI_FULL_ICONS = { public static final int[] WIFI_FULL_ICONS = {
com.android.internal.R.drawable.ic_wifi_signal_0, com.android.internal.R.drawable.ic_wifi_signal_0,
com.android.internal.R.drawable.ic_wifi_signal_1, com.android.internal.R.drawable.ic_wifi_signal_1,
com.android.internal.R.drawable.ic_wifi_signal_2, com.android.internal.R.drawable.ic_wifi_signal_2,

View File

@@ -225,6 +225,7 @@ public class DemoStatusIcons extends StatusIconContainer implements DemoMode, Da
public void addDemoWifiView(WifiIconState state) { public void addDemoWifiView(WifiIconState state) {
Log.d(TAG, "addDemoWifiView: "); Log.d(TAG, "addDemoWifiView: ");
// TODO(b/238425913): Migrate this view to {@code ModernStatusBarWifiView}.
StatusBarWifiView view = StatusBarWifiView.fromContext(mContext, state.slot); StatusBarWifiView view = StatusBarWifiView.fromContext(mContext, state.slot);
int viewIndex = getChildCount(); int viewIndex = getChildCount();

View File

@@ -40,6 +40,7 @@ import com.android.systemui.demomode.DemoModeCommandReceiver;
import com.android.systemui.flags.FeatureFlags; import com.android.systemui.flags.FeatureFlags;
import com.android.systemui.plugins.DarkIconDispatcher; import com.android.systemui.plugins.DarkIconDispatcher;
import com.android.systemui.plugins.DarkIconDispatcher.DarkReceiver; import com.android.systemui.plugins.DarkIconDispatcher.DarkReceiver;
import com.android.systemui.statusbar.BaseStatusBarWifiView;
import com.android.systemui.statusbar.StatusBarIconView; import com.android.systemui.statusbar.StatusBarIconView;
import com.android.systemui.statusbar.StatusBarMobileView; import com.android.systemui.statusbar.StatusBarMobileView;
import com.android.systemui.statusbar.StatusBarWifiView; import com.android.systemui.statusbar.StatusBarWifiView;
@@ -47,12 +48,16 @@ import com.android.systemui.statusbar.StatusIconDisplayable;
import com.android.systemui.statusbar.phone.StatusBarSignalPolicy.CallIndicatorIconState; import com.android.systemui.statusbar.phone.StatusBarSignalPolicy.CallIndicatorIconState;
import com.android.systemui.statusbar.phone.StatusBarSignalPolicy.MobileIconState; import com.android.systemui.statusbar.phone.StatusBarSignalPolicy.MobileIconState;
import com.android.systemui.statusbar.phone.StatusBarSignalPolicy.WifiIconState; import com.android.systemui.statusbar.phone.StatusBarSignalPolicy.WifiIconState;
import com.android.systemui.statusbar.pipeline.StatusBarPipelineFlags;
import com.android.systemui.statusbar.pipeline.wifi.ui.view.ModernStatusBarWifiView;
import com.android.systemui.statusbar.pipeline.wifi.ui.viewmodel.WifiViewModel;
import com.android.systemui.util.Assert; import com.android.systemui.util.Assert;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import javax.inject.Inject; import javax.inject.Inject;
import javax.inject.Provider;
public interface StatusBarIconController { public interface StatusBarIconController {
@@ -128,8 +133,12 @@ public interface StatusBarIconController {
private final DarkIconDispatcher mDarkIconDispatcher; private final DarkIconDispatcher mDarkIconDispatcher;
private int mIconHPadding; private int mIconHPadding;
public DarkIconManager(LinearLayout linearLayout, FeatureFlags featureFlags) { public DarkIconManager(
super(linearLayout, featureFlags); LinearLayout linearLayout,
FeatureFlags featureFlags,
StatusBarPipelineFlags statusBarPipelineFlags,
Provider<WifiViewModel> wifiViewModelProvider) {
super(linearLayout, featureFlags, statusBarPipelineFlags, wifiViewModelProvider);
mIconHPadding = mContext.getResources().getDimensionPixelSize( mIconHPadding = mContext.getResources().getDimensionPixelSize(
R.dimen.status_bar_icon_padding); R.dimen.status_bar_icon_padding);
mDarkIconDispatcher = Dependency.get(DarkIconDispatcher.class); mDarkIconDispatcher = Dependency.get(DarkIconDispatcher.class);
@@ -183,14 +192,40 @@ public interface StatusBarIconController {
mDarkIconDispatcher.removeDarkReceiver(mDemoStatusIcons); mDarkIconDispatcher.removeDarkReceiver(mDemoStatusIcons);
super.exitDemoMode(); super.exitDemoMode();
} }
@SysUISingleton
public static class Factory {
private final FeatureFlags mFeatureFlags;
private final StatusBarPipelineFlags mStatusBarPipelineFlags;
private final Provider<WifiViewModel> mWifiViewModelProvider;
@Inject
public Factory(
FeatureFlags featureFlags,
StatusBarPipelineFlags statusBarPipelineFlags,
Provider<WifiViewModel> wifiViewModelProvider) {
mFeatureFlags = featureFlags;
mStatusBarPipelineFlags = statusBarPipelineFlags;
mWifiViewModelProvider = wifiViewModelProvider;
}
public DarkIconManager create(LinearLayout group) {
return new DarkIconManager(
group, mFeatureFlags, mStatusBarPipelineFlags, mWifiViewModelProvider);
}
}
} }
/** */ /** */
class TintedIconManager extends IconManager { class TintedIconManager extends IconManager {
private int mColor; private int mColor;
public TintedIconManager(ViewGroup group, FeatureFlags featureFlags) { public TintedIconManager(
super(group, featureFlags); ViewGroup group,
FeatureFlags featureFlags,
StatusBarPipelineFlags statusBarPipelineFlags,
Provider<WifiViewModel> wifiViewModelProvider) {
super(group, featureFlags, statusBarPipelineFlags, wifiViewModelProvider);
} }
@Override @Override
@@ -223,14 +258,22 @@ public interface StatusBarIconController {
@SysUISingleton @SysUISingleton
public static class Factory { public static class Factory {
private final FeatureFlags mFeatureFlags; private final FeatureFlags mFeatureFlags;
private final StatusBarPipelineFlags mStatusBarPipelineFlags;
private final Provider<WifiViewModel> mWifiViewModelProvider;
@Inject @Inject
public Factory(FeatureFlags featureFlags) { public Factory(
FeatureFlags featureFlags,
StatusBarPipelineFlags statusBarPipelineFlags,
Provider<WifiViewModel> wifiViewModelProvider) {
mFeatureFlags = featureFlags; mFeatureFlags = featureFlags;
mStatusBarPipelineFlags = statusBarPipelineFlags;
mWifiViewModelProvider = wifiViewModelProvider;
} }
public TintedIconManager create(ViewGroup group) { public TintedIconManager create(ViewGroup group) {
return new TintedIconManager(group, mFeatureFlags); return new TintedIconManager(
group, mFeatureFlags, mStatusBarPipelineFlags, mWifiViewModelProvider);
} }
} }
} }
@@ -239,8 +282,10 @@ public interface StatusBarIconController {
* Turns info from StatusBarIconController into ImageViews in a ViewGroup. * Turns info from StatusBarIconController into ImageViews in a ViewGroup.
*/ */
class IconManager implements DemoModeCommandReceiver { class IconManager implements DemoModeCommandReceiver {
private final FeatureFlags mFeatureFlags;
protected final ViewGroup mGroup; protected final ViewGroup mGroup;
private final FeatureFlags mFeatureFlags;
private final StatusBarPipelineFlags mStatusBarPipelineFlags;
private final Provider<WifiViewModel> mWifiViewModelProvider;
protected final Context mContext; protected final Context mContext;
protected final int mIconSize; protected final int mIconSize;
// Whether or not these icons show up in dumpsys // Whether or not these icons show up in dumpsys
@@ -254,9 +299,15 @@ public interface StatusBarIconController {
protected ArrayList<String> mBlockList = new ArrayList<>(); protected ArrayList<String> mBlockList = new ArrayList<>();
public IconManager(ViewGroup group, FeatureFlags featureFlags) { public IconManager(
mFeatureFlags = featureFlags; ViewGroup group,
FeatureFlags featureFlags,
StatusBarPipelineFlags statusBarPipelineFlags,
Provider<WifiViewModel> wifiViewModelProvider) {
mGroup = group; mGroup = group;
mFeatureFlags = featureFlags;
mStatusBarPipelineFlags = statusBarPipelineFlags;
mWifiViewModelProvider = wifiViewModelProvider;
mContext = group.getContext(); mContext = group.getContext();
mIconSize = mContext.getResources().getDimensionPixelSize( mIconSize = mContext.getResources().getDimensionPixelSize(
com.android.internal.R.dimen.status_bar_icon_size); com.android.internal.R.dimen.status_bar_icon_size);
@@ -308,7 +359,7 @@ public interface StatusBarIconController {
return addIcon(index, slot, blocked, holder.getIcon()); return addIcon(index, slot, blocked, holder.getIcon());
case TYPE_WIFI: case TYPE_WIFI:
return addSignalIcon(index, slot, holder.getWifiState()); return addWifiIcon(index, slot, holder.getWifiState());
case TYPE_MOBILE: case TYPE_MOBILE:
return addMobileIcon(index, slot, holder.getMobileState()); return addMobileIcon(index, slot, holder.getMobileState());
@@ -327,9 +378,17 @@ public interface StatusBarIconController {
} }
@VisibleForTesting @VisibleForTesting
protected StatusBarWifiView addSignalIcon(int index, String slot, WifiIconState state) { protected StatusIconDisplayable addWifiIcon(int index, String slot, WifiIconState state) {
StatusBarWifiView view = onCreateStatusBarWifiView(slot); final BaseStatusBarWifiView view;
view.applyWifiState(state); if (mStatusBarPipelineFlags.isNewPipelineFrontendEnabled()) {
view = onCreateModernStatusBarWifiView(slot);
// When [ModernStatusBarWifiView] is created, it will automatically apply the
// correct view state so we don't need to call applyWifiState.
} else {
StatusBarWifiView wifiView = onCreateStatusBarWifiView(slot);
wifiView.applyWifiState(state);
view = wifiView;
}
mGroup.addView(view, index, onCreateLayoutParams()); mGroup.addView(view, index, onCreateLayoutParams());
if (mIsInDemoMode) { if (mIsInDemoMode) {
@@ -359,6 +418,11 @@ public interface StatusBarIconController {
return view; return view;
} }
private ModernStatusBarWifiView onCreateModernStatusBarWifiView(String slot) {
return ModernStatusBarWifiView.constructAndBind(
mContext, slot, mWifiViewModelProvider.get());
}
private StatusBarMobileView onCreateStatusBarMobileView(String slot) { private StatusBarMobileView onCreateStatusBarMobileView(String slot) {
StatusBarMobileView view = StatusBarMobileView.fromContext(mContext, slot); StatusBarMobileView view = StatusBarMobileView.fromContext(mContext, slot);
return view; return view;
@@ -415,9 +479,8 @@ public interface StatusBarIconController {
onSetIcon(viewIndex, holder.getIcon()); onSetIcon(viewIndex, holder.getIcon());
return; return;
case TYPE_WIFI: case TYPE_WIFI:
onSetSignalIcon(viewIndex, holder.getWifiState()); onSetWifiIcon(viewIndex, holder.getWifiState());
return; return;
case TYPE_MOBILE: case TYPE_MOBILE:
onSetMobileIcon(viewIndex, holder.getMobileState()); onSetMobileIcon(viewIndex, holder.getMobileState());
default: default:
@@ -425,10 +488,16 @@ public interface StatusBarIconController {
} }
} }
public void onSetSignalIcon(int viewIndex, WifiIconState state) { public void onSetWifiIcon(int viewIndex, WifiIconState state) {
StatusBarWifiView wifiView = (StatusBarWifiView) mGroup.getChildAt(viewIndex); View view = mGroup.getChildAt(viewIndex);
if (wifiView != null) { if (view instanceof StatusBarWifiView) {
wifiView.applyWifiState(state); ((StatusBarWifiView) view).applyWifiState(state);
} else if (view instanceof ModernStatusBarWifiView) {
// ModernStatusBarWifiView will automatically apply state based on its callbacks, so
// we don't need to call applyWifiState.
} else {
throw new IllegalStateException("View at " + viewIndex + " must be of type "
+ "StatusBarWifiView or ModernStatusBarWifiView");
} }
if (mIsInDemoMode) { if (mIsInDemoMode) {

View File

@@ -287,6 +287,7 @@ public abstract class StatusBarViewModule {
PanelExpansionStateManager panelExpansionStateManager, PanelExpansionStateManager panelExpansionStateManager,
FeatureFlags featureFlags, FeatureFlags featureFlags,
StatusBarIconController statusBarIconController, StatusBarIconController statusBarIconController,
StatusBarIconController.DarkIconManager.Factory darkIconManagerFactory,
StatusBarHideIconsForBouncerManager statusBarHideIconsForBouncerManager, StatusBarHideIconsForBouncerManager statusBarHideIconsForBouncerManager,
KeyguardStateController keyguardStateController, KeyguardStateController keyguardStateController,
NotificationPanelViewController notificationPanelViewController, NotificationPanelViewController notificationPanelViewController,
@@ -308,6 +309,7 @@ public abstract class StatusBarViewModule {
panelExpansionStateManager, panelExpansionStateManager,
featureFlags, featureFlags,
statusBarIconController, statusBarIconController,
darkIconManagerFactory,
statusBarHideIconsForBouncerManager, statusBarHideIconsForBouncerManager,
keyguardStateController, keyguardStateController,
notificationPanelViewController, notificationPanelViewController,

View File

@@ -130,6 +130,7 @@ public class CollapsedStatusBarFragment extends Fragment implements CommandQueue
private final StatusBarIconController mStatusBarIconController; private final StatusBarIconController mStatusBarIconController;
private final CarrierConfigTracker mCarrierConfigTracker; private final CarrierConfigTracker mCarrierConfigTracker;
private final StatusBarHideIconsForBouncerManager mStatusBarHideIconsForBouncerManager; private final StatusBarHideIconsForBouncerManager mStatusBarHideIconsForBouncerManager;
private final StatusBarIconController.DarkIconManager.Factory mDarkIconManagerFactory;
private final SecureSettings mSecureSettings; private final SecureSettings mSecureSettings;
private final Executor mMainExecutor; private final Executor mMainExecutor;
private final DumpManager mDumpManager; private final DumpManager mDumpManager;
@@ -185,6 +186,7 @@ public class CollapsedStatusBarFragment extends Fragment implements CommandQueue
PanelExpansionStateManager panelExpansionStateManager, PanelExpansionStateManager panelExpansionStateManager,
FeatureFlags featureFlags, FeatureFlags featureFlags,
StatusBarIconController statusBarIconController, StatusBarIconController statusBarIconController,
StatusBarIconController.DarkIconManager.Factory darkIconManagerFactory,
StatusBarHideIconsForBouncerManager statusBarHideIconsForBouncerManager, StatusBarHideIconsForBouncerManager statusBarHideIconsForBouncerManager,
KeyguardStateController keyguardStateController, KeyguardStateController keyguardStateController,
NotificationPanelViewController notificationPanelViewController, NotificationPanelViewController notificationPanelViewController,
@@ -207,6 +209,7 @@ public class CollapsedStatusBarFragment extends Fragment implements CommandQueue
mFeatureFlags = featureFlags; mFeatureFlags = featureFlags;
mStatusBarIconController = statusBarIconController; mStatusBarIconController = statusBarIconController;
mStatusBarHideIconsForBouncerManager = statusBarHideIconsForBouncerManager; mStatusBarHideIconsForBouncerManager = statusBarHideIconsForBouncerManager;
mDarkIconManagerFactory = darkIconManagerFactory;
mKeyguardStateController = keyguardStateController; mKeyguardStateController = keyguardStateController;
mNotificationPanelViewController = notificationPanelViewController; mNotificationPanelViewController = notificationPanelViewController;
mNetworkController = networkController; mNetworkController = networkController;
@@ -247,7 +250,7 @@ public class CollapsedStatusBarFragment extends Fragment implements CommandQueue
mStatusBar.restoreHierarchyState( mStatusBar.restoreHierarchyState(
savedInstanceState.getSparseParcelableArray(EXTRA_PANEL_STATE)); savedInstanceState.getSparseParcelableArray(EXTRA_PANEL_STATE));
} }
mDarkIconManager = new DarkIconManager(view.findViewById(R.id.statusIcons), mFeatureFlags); mDarkIconManager = mDarkIconManagerFactory.create(view.findViewById(R.id.statusIcons));
mDarkIconManager.setShouldLog(true); mDarkIconManager.setShouldLog(true);
updateBlockedIcons(); updateBlockedIcons();
mStatusBarIconController.addIconGroup(mDarkIconManager); mStatusBarIconController.addIconGroup(mDarkIconManager);

View File

@@ -43,7 +43,7 @@ class ConnectivityInfoProcessor @Inject constructor(
private val wifiViewModelProvider: Provider<WifiViewModel>, private val wifiViewModelProvider: Provider<WifiViewModel>,
) : CoreStartable(context) { ) : CoreStartable(context) {
override fun start() { override fun start() {
if (!statusBarPipelineFlags.isNewPipelineEnabled()) { if (!statusBarPipelineFlags.isNewPipelineBackendEnabled()) {
return return
} }
// TODO(b/238425913): The view binder should do this instead. For now, do it here so we can // TODO(b/238425913): The view binder should do this instead. For now, do it here so we can

View File

@@ -25,13 +25,28 @@ import javax.inject.Inject
@SysUISingleton @SysUISingleton
class StatusBarPipelineFlags @Inject constructor(private val featureFlags: FeatureFlags) { class StatusBarPipelineFlags @Inject constructor(private val featureFlags: FeatureFlags) {
/** /**
* Returns true if we should run the new pipeline. * Returns true if we should run the new pipeline backend.
* *
* TODO(b/238425913): We may want to split this out into: * The new pipeline backend hooks up to all our external callbacks, logs those callback inputs,
* (1) isNewPipelineLoggingEnabled(), where the new pipeline runs and logs its decisions but * and logs the output state.
* doesn't change the UI at all.
* (2) isNewPipelineEnabled(), where the new pipeline runs and does change the UI (and the old
* pipeline doesn't change the UI).
*/ */
fun isNewPipelineEnabled(): Boolean = featureFlags.isEnabled(Flags.NEW_STATUS_BAR_PIPELINE) fun isNewPipelineBackendEnabled(): Boolean =
featureFlags.isEnabled(Flags.NEW_STATUS_BAR_PIPELINE_BACKEND)
/**
* Returns true if we should run the new pipeline frontend *and* backend.
*
* The new pipeline frontend will use the outputted state from the new backend and will make the
* correct changes to the UI.
*/
fun isNewPipelineFrontendEnabled(): Boolean =
isNewPipelineBackendEnabled() &&
featureFlags.isEnabled(Flags.NEW_STATUS_BAR_PIPELINE_FRONTEND)
/**
* Returns true if we should apply some coloring to icons that were rendered with the new
* pipeline to help with debugging.
*/
// For now, just always apply the debug coloring if we've enabled frontend rendering.
fun useNewPipelineDebugColoring(): Boolean = isNewPipelineFrontendEnabled()
} }

View File

@@ -0,0 +1,67 @@
/*
* 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.pipeline.wifi.ui.binder
import android.content.res.ColorStateList
import android.view.View
import android.view.ViewGroup
import android.widget.ImageView
import androidx.core.view.isVisible
import androidx.lifecycle.Lifecycle
import androidx.lifecycle.repeatOnLifecycle
import com.android.systemui.R
import com.android.systemui.lifecycle.repeatWhenAttached
import com.android.systemui.statusbar.connectivity.WifiIcons.WIFI_FULL_ICONS
import com.android.systemui.statusbar.pipeline.wifi.ui.viewmodel.WifiViewModel
import kotlinx.coroutines.InternalCoroutinesApi
import kotlinx.coroutines.flow.collect
import kotlinx.coroutines.launch
/**
* Binds a wifi icon in the status bar to its view-model.
*
* To use this properly, users should maintain a one-to-one relationship between the [View] and the
* view-binding, binding each view only once. It is okay and expected for the same instance of the
* view-model to be reused for multiple view/view-binder bindings.
*/
@OptIn(InternalCoroutinesApi::class)
object WifiViewBinder {
/** Binds the view to the view-model, continuing to update the former based on the latter. */
@JvmStatic
fun bind(
view: ViewGroup,
viewModel: WifiViewModel,
) {
val iconView = view.requireViewById<ImageView>(R.id.wifi_signal)
view.isVisible = true
iconView.isVisible = true
iconView.setImageDrawable(view.context.getDrawable(WIFI_FULL_ICONS[2]))
view.repeatWhenAttached {
repeatOnLifecycle(Lifecycle.State.STARTED) {
launch {
viewModel.tint.collect { tint ->
iconView.imageTintList = ColorStateList.valueOf(tint)
}
}
}
}
// TODO(b/238425913): Hook up to [viewModel] to render actual changes to the wifi icon.
}
}

View File

@@ -0,0 +1,93 @@
/*
* 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.pipeline.wifi.ui.view
import android.content.Context
import android.graphics.Rect
import android.util.AttributeSet
import android.view.LayoutInflater
import com.android.systemui.R
import com.android.systemui.statusbar.BaseStatusBarWifiView
import com.android.systemui.statusbar.StatusBarIconView.STATE_ICON
import com.android.systemui.statusbar.pipeline.wifi.ui.binder.WifiViewBinder
import com.android.systemui.statusbar.pipeline.wifi.ui.viewmodel.WifiViewModel
/**
* A new and more modern implementation of [com.android.systemui.statusbar.StatusBarWifiView] that
* is updated by [WifiViewBinder].
*/
class ModernStatusBarWifiView(
context: Context,
attrs: AttributeSet?
) : BaseStatusBarWifiView(context, attrs) {
private lateinit var slot: String
override fun onDarkChanged(areas: ArrayList<Rect>?, darkIntensity: Float, tint: Int) {
// TODO(b/238425913)
}
override fun getSlot() = slot
override fun setStaticDrawableColor(color: Int) {
// TODO(b/238425913)
}
override fun setDecorColor(color: Int) {
// TODO(b/238425913)
}
override fun setVisibleState(state: Int, animate: Boolean) {
// TODO(b/238425913)
}
override fun getVisibleState(): Int {
// TODO(b/238425913)
return STATE_ICON
}
override fun isIconVisible(): Boolean {
// TODO(b/238425913)
return true
}
/** Set the slot name for this view. */
private fun setSlot(slotName: String) {
this.slot = slotName
}
companion object {
/**
* Inflates a new instance of [ModernStatusBarWifiView], binds it to [viewModel], and
* returns it.
*/
@JvmStatic
fun constructAndBind(
context: Context,
slot: String,
viewModel: WifiViewModel,
): ModernStatusBarWifiView {
return (
LayoutInflater.from(context).inflate(R.layout.new_status_bar_wifi_group, null)
as ModernStatusBarWifiView
).also {
it.setSlot(slot)
WifiViewBinder.bind(it, viewModel)
}
}
}
}

View File

@@ -16,12 +16,15 @@
package com.android.systemui.statusbar.pipeline.wifi.ui.viewmodel package com.android.systemui.statusbar.pipeline.wifi.ui.viewmodel
import android.graphics.Color
import com.android.systemui.statusbar.pipeline.StatusBarPipelineFlags
import com.android.systemui.statusbar.pipeline.shared.ConnectivityPipelineLogger import com.android.systemui.statusbar.pipeline.shared.ConnectivityPipelineLogger
import com.android.systemui.statusbar.pipeline.shared.ConnectivityPipelineLogger.Companion.logOutputChange import com.android.systemui.statusbar.pipeline.shared.ConnectivityPipelineLogger.Companion.logOutputChange
import com.android.systemui.statusbar.pipeline.wifi.domain.interactor.WifiInteractor import com.android.systemui.statusbar.pipeline.wifi.domain.interactor.WifiInteractor
import com.android.systemui.statusbar.pipeline.wifi.shared.WifiConstants import com.android.systemui.statusbar.pipeline.wifi.shared.WifiConstants
import javax.inject.Inject import javax.inject.Inject
import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.emptyFlow
import kotlinx.coroutines.flow.flowOf import kotlinx.coroutines.flow.flowOf
/** /**
@@ -30,9 +33,10 @@ import kotlinx.coroutines.flow.flowOf
* TODO(b/238425913): Hook this up to the real status bar wifi view using a view binder. * TODO(b/238425913): Hook this up to the real status bar wifi view using a view binder.
*/ */
class WifiViewModel @Inject constructor( class WifiViewModel @Inject constructor(
private val constants: WifiConstants, statusBarPipelineFlags: StatusBarPipelineFlags,
private val logger: ConnectivityPipelineLogger, private val constants: WifiConstants,
private val interactor: WifiInteractor, private val logger: ConnectivityPipelineLogger,
private val interactor: WifiInteractor,
) { ) {
val isActivityInVisible: Flow<Boolean> val isActivityInVisible: Flow<Boolean>
get() = get() =
@@ -42,4 +46,11 @@ class WifiViewModel @Inject constructor(
interactor.hasActivityIn interactor.hasActivityIn
} }
.logOutputChange(logger, "activityInVisible") .logOutputChange(logger, "activityInVisible")
/** The tint that should be applied to the icon. */
val tint: Flow<Int> = if (!statusBarPipelineFlags.useNewPipelineDebugColoring()) {
emptyFlow()
} else {
flowOf(Color.CYAN)
}
} }

View File

@@ -93,6 +93,10 @@ class QuickStatusBarHeaderControllerTest : SysuiTestCase() {
private lateinit var featureFlags: FeatureFlags private lateinit var featureFlags: FeatureFlags
@Mock @Mock
private lateinit var insetsProvider: StatusBarContentInsetsProvider private lateinit var insetsProvider: StatusBarContentInsetsProvider
@Mock
private lateinit var iconManagerFactory: StatusBarIconController.TintedIconManager.Factory
@Mock
private lateinit var iconManager: StatusBarIconController.TintedIconManager
private val qsExpansionPathInterpolator = QSExpansionPathInterpolator() private val qsExpansionPathInterpolator = QSExpansionPathInterpolator()
@@ -106,6 +110,7 @@ class QuickStatusBarHeaderControllerTest : SysuiTestCase() {
`when`(qsCarrierGroupControllerBuilder.build()).thenReturn(qsCarrierGroupController) `when`(qsCarrierGroupControllerBuilder.build()).thenReturn(qsCarrierGroupController)
`when`(variableDateViewControllerFactory.create(any())) `when`(variableDateViewControllerFactory.create(any()))
.thenReturn(variableDateViewController) .thenReturn(variableDateViewController)
`when`(iconManagerFactory.create(any())).thenReturn(iconManager)
`when`(view.resources).thenReturn(mContext.resources) `when`(view.resources).thenReturn(mContext.resources)
`when`(view.isAttachedToWindow).thenReturn(true) `when`(view.isAttachedToWindow).thenReturn(true)
`when`(view.context).thenReturn(context) `when`(view.context).thenReturn(context)
@@ -122,7 +127,8 @@ class QuickStatusBarHeaderControllerTest : SysuiTestCase() {
featureFlags, featureFlags,
variableDateViewControllerFactory, variableDateViewControllerFactory,
batteryMeterViewController, batteryMeterViewController,
insetsProvider insetsProvider,
iconManagerFactory,
) )
} }

View File

@@ -91,6 +91,10 @@ class LargeScreenShadeHeaderControllerCombinedTest : SysuiTestCase() {
@Mock @Mock
private lateinit var statusBarIconController: StatusBarIconController private lateinit var statusBarIconController: StatusBarIconController
@Mock @Mock
private lateinit var iconManagerFactory: StatusBarIconController.TintedIconManager.Factory
@Mock
private lateinit var iconManager: StatusBarIconController.TintedIconManager
@Mock
private lateinit var qsCarrierGroupController: QSCarrierGroupController private lateinit var qsCarrierGroupController: QSCarrierGroupController
@Mock @Mock
private lateinit var qsCarrierGroupControllerBuilder: QSCarrierGroupController.Builder private lateinit var qsCarrierGroupControllerBuilder: QSCarrierGroupController.Builder
@@ -169,6 +173,8 @@ class LargeScreenShadeHeaderControllerCombinedTest : SysuiTestCase() {
} }
whenever(view.visibility).thenAnswer { _ -> viewVisibility } whenever(view.visibility).thenAnswer { _ -> viewVisibility }
whenever(iconManagerFactory.create(any())).thenReturn(iconManager)
whenever(featureFlags.isEnabled(Flags.COMBINED_QS_HEADERS)).thenReturn(true) whenever(featureFlags.isEnabled(Flags.COMBINED_QS_HEADERS)).thenReturn(true)
whenever(featureFlags.isEnabled(Flags.NEW_HEADER)).thenReturn(true) whenever(featureFlags.isEnabled(Flags.NEW_HEADER)).thenReturn(true)
@@ -178,6 +184,7 @@ class LargeScreenShadeHeaderControllerCombinedTest : SysuiTestCase() {
controller = LargeScreenShadeHeaderController( controller = LargeScreenShadeHeaderController(
view, view,
statusBarIconController, statusBarIconController,
iconManagerFactory,
privacyIconsController, privacyIconsController,
insetsProvider, insetsProvider,
configurationController, configurationController,

View File

@@ -43,6 +43,8 @@ class LargeScreenShadeHeaderControllerTest : SysuiTestCase() {
@Mock private lateinit var view: View @Mock private lateinit var view: View
@Mock private lateinit var statusIcons: StatusIconContainer @Mock private lateinit var statusIcons: StatusIconContainer
@Mock private lateinit var statusBarIconController: StatusBarIconController @Mock private lateinit var statusBarIconController: StatusBarIconController
@Mock private lateinit var iconManagerFactory: StatusBarIconController.TintedIconManager.Factory
@Mock private lateinit var iconManager: StatusBarIconController.TintedIconManager
@Mock private lateinit var qsCarrierGroupController: QSCarrierGroupController @Mock private lateinit var qsCarrierGroupController: QSCarrierGroupController
@Mock private lateinit var qsCarrierGroupControllerBuilder: QSCarrierGroupController.Builder @Mock private lateinit var qsCarrierGroupControllerBuilder: QSCarrierGroupController.Builder
@Mock private lateinit var featureFlags: FeatureFlags @Mock private lateinit var featureFlags: FeatureFlags
@@ -91,10 +93,12 @@ class LargeScreenShadeHeaderControllerTest : SysuiTestCase() {
whenever(view.visibility).thenAnswer { _ -> viewVisibility } whenever(view.visibility).thenAnswer { _ -> viewVisibility }
whenever(variableDateViewControllerFactory.create(any())) whenever(variableDateViewControllerFactory.create(any()))
.thenReturn(variableDateViewController) .thenReturn(variableDateViewController)
whenever(iconManagerFactory.create(any())).thenReturn(iconManager)
whenever(featureFlags.isEnabled(Flags.COMBINED_QS_HEADERS)).thenReturn(false) whenever(featureFlags.isEnabled(Flags.COMBINED_QS_HEADERS)).thenReturn(false)
mLargeScreenShadeHeaderController = LargeScreenShadeHeaderController( mLargeScreenShadeHeaderController = LargeScreenShadeHeaderController(
view, view,
statusBarIconController, statusBarIconController,
iconManagerFactory,
privacyIconsController, privacyIconsController,
insetsProvider, insetsProvider,
configurationController, configurationController,

View File

@@ -47,7 +47,6 @@ import com.android.keyguard.KeyguardUpdateMonitorCallback;
import com.android.systemui.R; import com.android.systemui.R;
import com.android.systemui.SysuiTestCase; import com.android.systemui.SysuiTestCase;
import com.android.systemui.battery.BatteryMeterViewController; import com.android.systemui.battery.BatteryMeterViewController;
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;
import com.android.systemui.statusbar.SysuiStatusBarStateController; import com.android.systemui.statusbar.SysuiStatusBarStateController;
@@ -89,7 +88,9 @@ public class KeyguardStatusBarViewControllerTest extends SysuiTestCase {
@Mock @Mock
private StatusBarIconController mStatusBarIconController; private StatusBarIconController mStatusBarIconController;
@Mock @Mock
private FeatureFlags mFeatureFlags; private StatusBarIconController.TintedIconManager.Factory mIconManagerFactory;
@Mock
private StatusBarIconController.TintedIconManager mIconManager;
@Mock @Mock
private BatteryMeterViewController mBatteryMeterViewController; private BatteryMeterViewController mBatteryMeterViewController;
@Mock @Mock
@@ -129,6 +130,8 @@ public class KeyguardStatusBarViewControllerTest extends SysuiTestCase {
MockitoAnnotations.initMocks(this); MockitoAnnotations.initMocks(this);
when(mIconManagerFactory.create(any())).thenReturn(mIconManager);
allowTestableLooperAsMainThread(); allowTestableLooperAsMainThread();
TestableLooper.get(this).runWithLooper(() -> { TestableLooper.get(this).runWithLooper(() -> {
mKeyguardStatusBarView = mKeyguardStatusBarView =
@@ -148,7 +151,7 @@ public class KeyguardStatusBarViewControllerTest extends SysuiTestCase {
mBatteryController, mBatteryController,
mUserInfoController, mUserInfoController,
mStatusBarIconController, mStatusBarIconController,
new StatusBarIconController.TintedIconManager.Factory(mFeatureFlags), mIconManagerFactory,
mBatteryMeterViewController, mBatteryMeterViewController,
mNotificationPanelViewStateProvider, mNotificationPanelViewStateProvider,
mKeyguardStateController, mKeyguardStateController,

View File

@@ -40,12 +40,16 @@ import com.android.systemui.statusbar.phone.StatusBarIconController.DarkIconMana
import com.android.systemui.statusbar.phone.StatusBarIconController.IconManager; import com.android.systemui.statusbar.phone.StatusBarIconController.IconManager;
import com.android.systemui.statusbar.phone.StatusBarSignalPolicy.MobileIconState; import com.android.systemui.statusbar.phone.StatusBarSignalPolicy.MobileIconState;
import com.android.systemui.statusbar.phone.StatusBarSignalPolicy.WifiIconState; import com.android.systemui.statusbar.phone.StatusBarSignalPolicy.WifiIconState;
import com.android.systemui.statusbar.pipeline.StatusBarPipelineFlags;
import com.android.systemui.statusbar.pipeline.wifi.ui.viewmodel.WifiViewModel;
import com.android.systemui.utils.leaks.LeakCheckedTest; import com.android.systemui.utils.leaks.LeakCheckedTest;
import org.junit.Before; import org.junit.Before;
import org.junit.Test; import org.junit.Test;
import org.junit.runner.RunWith; import org.junit.runner.RunWith;
import javax.inject.Provider;
@RunWith(AndroidTestingRunner.class) @RunWith(AndroidTestingRunner.class)
@RunWithLooper @RunWithLooper
@SmallTest @SmallTest
@@ -67,7 +71,11 @@ public class StatusBarIconControllerTest extends LeakCheckedTest {
@Test @Test
public void testSetCalledOnAdd_DarkIconManager() { public void testSetCalledOnAdd_DarkIconManager() {
LinearLayout layout = new LinearLayout(mContext); LinearLayout layout = new LinearLayout(mContext);
TestDarkIconManager manager = new TestDarkIconManager(layout, mock(FeatureFlags.class)); TestDarkIconManager manager = new TestDarkIconManager(
layout,
mock(FeatureFlags.class),
mock(StatusBarPipelineFlags.class),
() -> mock(WifiViewModel.class));
testCallOnAdd_forManager(manager); testCallOnAdd_forManager(manager);
} }
@@ -104,8 +112,12 @@ public class StatusBarIconControllerTest extends LeakCheckedTest {
private static class TestDarkIconManager extends DarkIconManager private static class TestDarkIconManager extends DarkIconManager
implements TestableIconManager { implements TestableIconManager {
TestDarkIconManager(LinearLayout group, FeatureFlags featureFlags) { TestDarkIconManager(
super(group, featureFlags); LinearLayout group,
FeatureFlags featureFlags,
StatusBarPipelineFlags statusBarPipelineFlags,
Provider<WifiViewModel> wifiViewModelProvider) {
super(group, featureFlags, statusBarPipelineFlags, wifiViewModelProvider);
} }
@Override @Override
@@ -123,7 +135,7 @@ public class StatusBarIconControllerTest extends LeakCheckedTest {
} }
@Override @Override
protected StatusBarWifiView addSignalIcon(int index, String slot, WifiIconState state) { protected StatusBarWifiView addWifiIcon(int index, String slot, WifiIconState state) {
StatusBarWifiView mock = mock(StatusBarWifiView.class); StatusBarWifiView mock = mock(StatusBarWifiView.class);
mGroup.addView(mock, index); mGroup.addView(mock, index);
return mock; return mock;
@@ -140,7 +152,10 @@ public class StatusBarIconControllerTest extends LeakCheckedTest {
private static class TestIconManager extends IconManager implements TestableIconManager { private static class TestIconManager extends IconManager implements TestableIconManager {
TestIconManager(ViewGroup group) { TestIconManager(ViewGroup group) {
super(group, mock(FeatureFlags.class)); super(group,
mock(FeatureFlags.class),
mock(StatusBarPipelineFlags.class),
() -> mock(WifiViewModel.class));
} }
@Override @Override
@@ -158,7 +173,7 @@ public class StatusBarIconControllerTest extends LeakCheckedTest {
} }
@Override @Override
protected StatusBarWifiView addSignalIcon(int index, String slot, WifiIconState state) { protected StatusBarWifiView addWifiIcon(int index, String slot, WifiIconState state) {
StatusBarWifiView mock = mock(StatusBarWifiView.class); StatusBarWifiView mock = mock(StatusBarWifiView.class);
mGroup.addView(mock, index); mGroup.addView(mock, index);
return mock; return mock;

View File

@@ -113,6 +113,10 @@ public class CollapsedStatusBarFragmentTest extends SysuiBaseFragmentTest {
@Mock @Mock
private NotificationPanelViewController mNotificationPanelViewController; private NotificationPanelViewController mNotificationPanelViewController;
@Mock @Mock
private StatusBarIconController.DarkIconManager.Factory mIconManagerFactory;
@Mock
private StatusBarIconController.DarkIconManager mIconManager;
@Mock
private StatusBarHideIconsForBouncerManager mStatusBarHideIconsForBouncerManager; private StatusBarHideIconsForBouncerManager mStatusBarHideIconsForBouncerManager;
@Mock @Mock
private DumpManager mDumpManager; private DumpManager mDumpManager;
@@ -463,6 +467,7 @@ public class CollapsedStatusBarFragmentTest extends SysuiBaseFragmentTest {
mOperatorNameViewControllerFactory = mock(OperatorNameViewController.Factory.class); mOperatorNameViewControllerFactory = mock(OperatorNameViewController.Factory.class);
when(mOperatorNameViewControllerFactory.create(any())) when(mOperatorNameViewControllerFactory.create(any()))
.thenReturn(mOperatorNameViewController); .thenReturn(mOperatorNameViewController);
when(mIconManagerFactory.create(any())).thenReturn(mIconManager);
mSecureSettings = mock(SecureSettings.class); mSecureSettings = mock(SecureSettings.class);
setUpNotificationIconAreaController(); setUpNotificationIconAreaController();
@@ -475,6 +480,7 @@ public class CollapsedStatusBarFragmentTest extends SysuiBaseFragmentTest {
new PanelExpansionStateManager(), new PanelExpansionStateManager(),
mock(FeatureFlags.class), mock(FeatureFlags.class),
mStatusBarIconController, mStatusBarIconController,
mIconManagerFactory,
mStatusBarHideIconsForBouncerManager, mStatusBarHideIconsForBouncerManager,
mKeyguardStateController, mKeyguardStateController,
mNotificationPanelViewController, mNotificationPanelViewController,

View File

@@ -0,0 +1,53 @@
/*
* 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.pipeline.wifi.ui.view
import android.testing.TestableLooper.RunWithLooper
import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase
import com.android.systemui.lifecycle.InstantTaskExecutorRule
import com.android.systemui.util.Assert
import com.android.systemui.util.mockito.mock
import com.google.common.truth.Truth.assertThat
import org.junit.Before
import org.junit.Rule
import org.junit.Test
import org.junit.runner.RunWith
import org.junit.runners.JUnit4
@SmallTest
@RunWith(JUnit4::class)
@RunWithLooper
class ModernStatusBarWifiViewTest : SysuiTestCase() {
@JvmField @Rule
val instantTaskExecutor = InstantTaskExecutorRule()
@Before
fun setUp() {
Assert.setTestThread(Thread.currentThread())
}
@Test
fun constructAndBind_hasCorrectSlot() {
val view = ModernStatusBarWifiView.constructAndBind(
context, "slotName", mock()
)
assertThat(view.slot).isEqualTo("slotName")
}
}

View File

@@ -18,6 +18,7 @@ package com.android.systemui.statusbar.pipeline.wifi.ui.viewmodel
import androidx.test.filters.SmallTest import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase import com.android.systemui.SysuiTestCase
import com.android.systemui.statusbar.pipeline.StatusBarPipelineFlags
import com.android.systemui.statusbar.pipeline.shared.ConnectivityPipelineLogger import com.android.systemui.statusbar.pipeline.shared.ConnectivityPipelineLogger
import com.android.systemui.statusbar.pipeline.wifi.data.model.WifiActivityModel import com.android.systemui.statusbar.pipeline.wifi.data.model.WifiActivityModel
import com.android.systemui.statusbar.pipeline.wifi.data.model.WifiNetworkModel import com.android.systemui.statusbar.pipeline.wifi.data.model.WifiNetworkModel
@@ -43,6 +44,7 @@ class WifiViewModelTest : SysuiTestCase() {
private lateinit var underTest: WifiViewModel private lateinit var underTest: WifiViewModel
@Mock private lateinit var statusBarPipelineFlags: StatusBarPipelineFlags
@Mock private lateinit var logger: ConnectivityPipelineLogger @Mock private lateinit var logger: ConnectivityPipelineLogger
@Mock private lateinit var constants: WifiConstants @Mock private lateinit var constants: WifiConstants
private lateinit var repository: FakeWifiRepository private lateinit var repository: FakeWifiRepository
@@ -55,9 +57,10 @@ class WifiViewModelTest : SysuiTestCase() {
interactor = WifiInteractor(repository) interactor = WifiInteractor(repository)
underTest = WifiViewModel( underTest = WifiViewModel(
constants, statusBarPipelineFlags,
logger, constants,
interactor logger,
interactor
) )
// Set up with a valid SSID // Set up with a valid SSID