Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit c1c24a6a authored by Caitlin Shkuratov's avatar Caitlin Shkuratov
Browse files

[SB Refactor] Define WifiUiAdapter to interface between the new data

pipeline and the old UI.

When the new data pipeline detects a valid wifi icon, it will notify
StatusBarIconController to inflate a wifi icon if necessary.
This matches the pattern of MobileUiAdapter.

Bug: 238425913
Test: verify old wifi icon still works as expected
Test: verify new wifi icon still works as expected
Test: atest ModernStatusBarWifiViewTest StatusBarIconControllerTest
Change-Id: Id6a26bd00ee661a28e89585ea7b1293282a50c4d
parent b0b34d3e
Loading
Loading
Loading
Loading
+57 −30
Original line number Original line Diff line number Diff line
@@ -18,6 +18,7 @@ import static com.android.systemui.statusbar.phone.StatusBarIconHolder.TYPE_ICON
import static com.android.systemui.statusbar.phone.StatusBarIconHolder.TYPE_MOBILE;
import static com.android.systemui.statusbar.phone.StatusBarIconHolder.TYPE_MOBILE;
import static com.android.systemui.statusbar.phone.StatusBarIconHolder.TYPE_MOBILE_NEW;
import static com.android.systemui.statusbar.phone.StatusBarIconHolder.TYPE_MOBILE_NEW;
import static com.android.systemui.statusbar.phone.StatusBarIconHolder.TYPE_WIFI;
import static com.android.systemui.statusbar.phone.StatusBarIconHolder.TYPE_WIFI;
import static com.android.systemui.statusbar.phone.StatusBarIconHolder.TYPE_WIFI_NEW;


import android.annotation.Nullable;
import android.annotation.Nullable;
import android.content.Context;
import android.content.Context;
@@ -53,8 +54,9 @@ import com.android.systemui.statusbar.pipeline.mobile.ui.MobileUiAdapter;
import com.android.systemui.statusbar.pipeline.mobile.ui.binder.MobileIconsBinder;
import com.android.systemui.statusbar.pipeline.mobile.ui.binder.MobileIconsBinder;
import com.android.systemui.statusbar.pipeline.mobile.ui.view.ModernStatusBarMobileView;
import com.android.systemui.statusbar.pipeline.mobile.ui.view.ModernStatusBarMobileView;
import com.android.systemui.statusbar.pipeline.mobile.ui.viewmodel.MobileIconsViewModel;
import com.android.systemui.statusbar.pipeline.mobile.ui.viewmodel.MobileIconsViewModel;
import com.android.systemui.statusbar.pipeline.wifi.ui.WifiUiAdapter;
import com.android.systemui.statusbar.pipeline.wifi.ui.view.ModernStatusBarWifiView;
import com.android.systemui.statusbar.pipeline.wifi.ui.view.ModernStatusBarWifiView;
import com.android.systemui.statusbar.pipeline.wifi.ui.viewmodel.WifiViewModel;
import com.android.systemui.statusbar.pipeline.wifi.ui.viewmodel.LocationBasedWifiViewModel;
import com.android.systemui.util.Assert;
import com.android.systemui.util.Assert;


import java.util.ArrayList;
import java.util.ArrayList;
@@ -84,7 +86,18 @@ public interface StatusBarIconController {
    /** */
    /** */
    void setIcon(String slot, StatusBarIcon icon);
    void setIcon(String slot, StatusBarIcon icon);
    /** */
    /** */
    void setSignalIcon(String slot, WifiIconState state);
    void setWifiIcon(String slot, WifiIconState state);

    /**
     * Sets up a wifi icon using the new data pipeline. No effect if the wifi icon has already been
     * set up (inflated and added to the view hierarchy).
     *
     * This method completely replaces {@link #setWifiIcon} with the information from the new wifi
     * data pipeline. Icons will automatically keep their state up to date, so we don't have to
     * worry about funneling state objects through anymore.
     */
    void setNewWifiIcon();

    /** */
    /** */
    void setMobileIcons(String slot, List<MobileIconState> states);
    void setMobileIcons(String slot, List<MobileIconState> states);


@@ -151,14 +164,14 @@ public interface StatusBarIconController {
                LinearLayout linearLayout,
                LinearLayout linearLayout,
                StatusBarLocation location,
                StatusBarLocation location,
                StatusBarPipelineFlags statusBarPipelineFlags,
                StatusBarPipelineFlags statusBarPipelineFlags,
                WifiViewModel wifiViewModel,
                WifiUiAdapter wifiUiAdapter,
                MobileUiAdapter mobileUiAdapter,
                MobileUiAdapter mobileUiAdapter,
                MobileContextProvider mobileContextProvider,
                MobileContextProvider mobileContextProvider,
                DarkIconDispatcher darkIconDispatcher) {
                DarkIconDispatcher darkIconDispatcher) {
            super(linearLayout,
            super(linearLayout,
                    location,
                    location,
                    statusBarPipelineFlags,
                    statusBarPipelineFlags,
                    wifiViewModel,
                    wifiUiAdapter,
                    mobileUiAdapter,
                    mobileUiAdapter,
                    mobileContextProvider);
                    mobileContextProvider);
            mIconHPadding = mContext.getResources().getDimensionPixelSize(
            mIconHPadding = mContext.getResources().getDimensionPixelSize(
@@ -218,7 +231,7 @@ public interface StatusBarIconController {
        @SysUISingleton
        @SysUISingleton
        public static class Factory {
        public static class Factory {
            private final StatusBarPipelineFlags mStatusBarPipelineFlags;
            private final StatusBarPipelineFlags mStatusBarPipelineFlags;
            private final WifiViewModel mWifiViewModel;
            private final WifiUiAdapter mWifiUiAdapter;
            private final MobileContextProvider mMobileContextProvider;
            private final MobileContextProvider mMobileContextProvider;
            private final MobileUiAdapter mMobileUiAdapter;
            private final MobileUiAdapter mMobileUiAdapter;
            private final DarkIconDispatcher mDarkIconDispatcher;
            private final DarkIconDispatcher mDarkIconDispatcher;
@@ -226,12 +239,12 @@ public interface StatusBarIconController {
            @Inject
            @Inject
            public Factory(
            public Factory(
                    StatusBarPipelineFlags statusBarPipelineFlags,
                    StatusBarPipelineFlags statusBarPipelineFlags,
                    WifiViewModel wifiViewModel,
                    WifiUiAdapter wifiUiAdapter,
                    MobileContextProvider mobileContextProvider,
                    MobileContextProvider mobileContextProvider,
                    MobileUiAdapter mobileUiAdapter,
                    MobileUiAdapter mobileUiAdapter,
                    DarkIconDispatcher darkIconDispatcher) {
                    DarkIconDispatcher darkIconDispatcher) {
                mStatusBarPipelineFlags = statusBarPipelineFlags;
                mStatusBarPipelineFlags = statusBarPipelineFlags;
                mWifiViewModel = wifiViewModel;
                mWifiUiAdapter = wifiUiAdapter;
                mMobileContextProvider = mobileContextProvider;
                mMobileContextProvider = mobileContextProvider;
                mMobileUiAdapter = mobileUiAdapter;
                mMobileUiAdapter = mobileUiAdapter;
                mDarkIconDispatcher = darkIconDispatcher;
                mDarkIconDispatcher = darkIconDispatcher;
@@ -242,7 +255,7 @@ public interface StatusBarIconController {
                        group,
                        group,
                        location,
                        location,
                        mStatusBarPipelineFlags,
                        mStatusBarPipelineFlags,
                        mWifiViewModel,
                        mWifiUiAdapter,
                        mMobileUiAdapter,
                        mMobileUiAdapter,
                        mMobileContextProvider,
                        mMobileContextProvider,
                        mDarkIconDispatcher);
                        mDarkIconDispatcher);
@@ -260,14 +273,14 @@ public interface StatusBarIconController {
                ViewGroup group,
                ViewGroup group,
                StatusBarLocation location,
                StatusBarLocation location,
                StatusBarPipelineFlags statusBarPipelineFlags,
                StatusBarPipelineFlags statusBarPipelineFlags,
                WifiViewModel wifiViewModel,
                WifiUiAdapter wifiUiAdapter,
                MobileUiAdapter mobileUiAdapter,
                MobileUiAdapter mobileUiAdapter,
                MobileContextProvider mobileContextProvider
                MobileContextProvider mobileContextProvider
        ) {
        ) {
            super(group,
            super(group,
                    location,
                    location,
                    statusBarPipelineFlags,
                    statusBarPipelineFlags,
                    wifiViewModel,
                    wifiUiAdapter,
                    mobileUiAdapter,
                    mobileUiAdapter,
                    mobileContextProvider);
                    mobileContextProvider);
        }
        }
@@ -302,19 +315,19 @@ public interface StatusBarIconController {
        @SysUISingleton
        @SysUISingleton
        public static class Factory {
        public static class Factory {
            private final StatusBarPipelineFlags mStatusBarPipelineFlags;
            private final StatusBarPipelineFlags mStatusBarPipelineFlags;
            private final WifiViewModel mWifiViewModel;
            private final WifiUiAdapter mWifiUiAdapter;
            private final MobileContextProvider mMobileContextProvider;
            private final MobileContextProvider mMobileContextProvider;
            private final MobileUiAdapter mMobileUiAdapter;
            private final MobileUiAdapter mMobileUiAdapter;


            @Inject
            @Inject
            public Factory(
            public Factory(
                    StatusBarPipelineFlags statusBarPipelineFlags,
                    StatusBarPipelineFlags statusBarPipelineFlags,
                    WifiViewModel wifiViewModel,
                    WifiUiAdapter wifiUiAdapter,
                    MobileUiAdapter mobileUiAdapter,
                    MobileUiAdapter mobileUiAdapter,
                    MobileContextProvider mobileContextProvider
                    MobileContextProvider mobileContextProvider
            ) {
            ) {
                mStatusBarPipelineFlags = statusBarPipelineFlags;
                mStatusBarPipelineFlags = statusBarPipelineFlags;
                mWifiViewModel = wifiViewModel;
                mWifiUiAdapter = wifiUiAdapter;
                mMobileUiAdapter = mobileUiAdapter;
                mMobileUiAdapter = mobileUiAdapter;
                mMobileContextProvider = mobileContextProvider;
                mMobileContextProvider = mobileContextProvider;
            }
            }
@@ -324,7 +337,7 @@ public interface StatusBarIconController {
                        group,
                        group,
                        location,
                        location,
                        mStatusBarPipelineFlags,
                        mStatusBarPipelineFlags,
                        mWifiViewModel,
                        mWifiUiAdapter,
                        mMobileUiAdapter,
                        mMobileUiAdapter,
                        mMobileContextProvider);
                        mMobileContextProvider);
            }
            }
@@ -336,10 +349,9 @@ public interface StatusBarIconController {
     */
     */
    class IconManager implements DemoModeCommandReceiver {
    class IconManager implements DemoModeCommandReceiver {
        protected final ViewGroup mGroup;
        protected final ViewGroup mGroup;
        private final StatusBarLocation mLocation;
        private final StatusBarPipelineFlags mStatusBarPipelineFlags;
        private final StatusBarPipelineFlags mStatusBarPipelineFlags;
        private final WifiViewModel mWifiViewModel;
        private final MobileContextProvider mMobileContextProvider;
        private final MobileContextProvider mMobileContextProvider;
        private final LocationBasedWifiViewModel mWifiViewModel;
        private final MobileIconsViewModel mMobileIconsViewModel;
        private final MobileIconsViewModel mMobileIconsViewModel;


        protected final Context mContext;
        protected final Context mContext;
@@ -359,14 +371,12 @@ public interface StatusBarIconController {
                ViewGroup group,
                ViewGroup group,
                StatusBarLocation location,
                StatusBarLocation location,
                StatusBarPipelineFlags statusBarPipelineFlags,
                StatusBarPipelineFlags statusBarPipelineFlags,
                WifiViewModel wifiViewModel,
                WifiUiAdapter wifiUiAdapter,
                MobileUiAdapter mobileUiAdapter,
                MobileUiAdapter mobileUiAdapter,
                MobileContextProvider mobileContextProvider
                MobileContextProvider mobileContextProvider
        ) {
        ) {
            mGroup = group;
            mGroup = group;
            mLocation = location;
            mStatusBarPipelineFlags = statusBarPipelineFlags;
            mStatusBarPipelineFlags = statusBarPipelineFlags;
            mWifiViewModel = wifiViewModel;
            mMobileContextProvider = mobileContextProvider;
            mMobileContextProvider = mobileContextProvider;
            mContext = group.getContext();
            mContext = group.getContext();
            mIconSize = mContext.getResources().getDimensionPixelSize(
            mIconSize = mContext.getResources().getDimensionPixelSize(
@@ -379,6 +389,12 @@ public interface StatusBarIconController {
            } else {
            } else {
                mMobileIconsViewModel = null;
                mMobileIconsViewModel = null;
            }
            }

            if (statusBarPipelineFlags.useNewWifiIcon()) {
                mWifiViewModel = wifiUiAdapter.bindGroup(mGroup, location);
            } else {
                mWifiViewModel = null;
            }
        }
        }


        public boolean isDemoable() {
        public boolean isDemoable() {
@@ -429,6 +445,9 @@ public interface StatusBarIconController {
                case TYPE_WIFI:
                case TYPE_WIFI:
                    return addWifiIcon(index, slot, holder.getWifiState());
                    return addWifiIcon(index, slot, holder.getWifiState());


                case TYPE_WIFI_NEW:
                    return addNewWifiIcon(index, slot);

                case TYPE_MOBILE:
                case TYPE_MOBILE:
                    return addMobileIcon(index, slot, holder.getMobileState());
                    return addMobileIcon(index, slot, holder.getMobileState());


@@ -450,16 +469,13 @@ public interface StatusBarIconController {


        @VisibleForTesting
        @VisibleForTesting
        protected StatusIconDisplayable addWifiIcon(int index, String slot, WifiIconState state) {
        protected StatusIconDisplayable addWifiIcon(int index, String slot, WifiIconState state) {
            final BaseStatusBarFrameLayout view;
            if (mStatusBarPipelineFlags.useNewWifiIcon()) {
            if (mStatusBarPipelineFlags.useNewWifiIcon()) {
                view = onCreateModernStatusBarWifiView(slot);
                throw new IllegalStateException("Attempting to add a mobile icon while the new "
                // When [ModernStatusBarWifiView] is created, it will automatically apply the
                        + "icons are enabled is not supported");
                // correct view state so we don't need to call applyWifiState.
            } else {
                StatusBarWifiView wifiView = onCreateStatusBarWifiView(slot);
                wifiView.applyWifiState(state);
                view = wifiView;
            }
            }

            final StatusBarWifiView view = onCreateStatusBarWifiView(slot);
            view.applyWifiState(state);
            mGroup.addView(view, index, onCreateLayoutParams());
            mGroup.addView(view, index, onCreateLayoutParams());


            if (mIsInDemoMode) {
            if (mIsInDemoMode) {
@@ -468,6 +484,17 @@ public interface StatusBarIconController {
            return view;
            return view;
        }
        }


        protected StatusIconDisplayable addNewWifiIcon(int index, String slot) {
            if (!mStatusBarPipelineFlags.useNewWifiIcon()) {
                throw new IllegalStateException("Attempting to add a wifi icon using the new"
                        + "pipeline, but the enabled flag is false.");
            }

            ModernStatusBarWifiView view = onCreateModernStatusBarWifiView(slot);
            mGroup.addView(view, index, onCreateLayoutParams());
            return view;
        }

        @VisibleForTesting
        @VisibleForTesting
        protected StatusIconDisplayable addMobileIcon(
        protected StatusIconDisplayable addMobileIcon(
                int index,
                int index,
@@ -523,8 +550,7 @@ public interface StatusBarIconController {
        }
        }


        private ModernStatusBarWifiView onCreateModernStatusBarWifiView(String slot) {
        private ModernStatusBarWifiView onCreateModernStatusBarWifiView(String slot) {
            return ModernStatusBarWifiView.constructAndBind(
            return ModernStatusBarWifiView.constructAndBind(mContext, slot, mWifiViewModel);
                    mContext, slot, mWifiViewModel, mLocation);
        }
        }


        private StatusBarMobileView onCreateStatusBarMobileView(int subId, String slot) {
        private StatusBarMobileView onCreateStatusBarMobileView(int subId, String slot) {
@@ -600,7 +626,8 @@ public interface StatusBarIconController {
                    onSetMobileIcon(viewIndex, holder.getMobileState());
                    onSetMobileIcon(viewIndex, holder.getMobileState());
                    return;
                    return;
                case TYPE_MOBILE_NEW:
                case TYPE_MOBILE_NEW:
                    // Nothing, the icon updates itself now
                case TYPE_WIFI_NEW:
                    // Nothing, the new icons update themselves
                    return;
                    return;
                default:
                default:
                    break;
                    break;
+29 −9
Original line number Original line Diff line number Diff line
@@ -195,12 +195,13 @@ public class StatusBarIconControllerImpl implements Tunable,
        }
        }
    }
    }


    /**
     * Signal icons need to be handled differently, because they can be
     * composite views
     */
    @Override
    @Override
    public void setSignalIcon(String slot, WifiIconState state) {
    public void setWifiIcon(String slot, WifiIconState state) {
        if (mStatusBarPipelineFlags.useNewWifiIcon()) {
            Log.d(TAG, "ignoring old pipeline callback because the new wifi icon is enabled");
            return;
        }

        if (state == null) {
        if (state == null) {
            removeIcon(slot, 0);
            removeIcon(slot, 0);
            return;
            return;
@@ -216,6 +217,24 @@ public class StatusBarIconControllerImpl implements Tunable,
        }
        }
    }
    }



    @Override
    public void setNewWifiIcon() {
        if (!mStatusBarPipelineFlags.useNewWifiIcon()) {
            Log.d(TAG, "ignoring new pipeline callback because the new wifi icon is disabled");
            return;
        }

        String slot = mContext.getString(com.android.internal.R.string.status_bar_wifi);
        StatusBarIconHolder holder = mStatusBarIconList.getIconHolder(slot, /* tag= */ 0);
        if (holder == null) {
            holder = StatusBarIconHolder.forNewWifiIcon();
            setIcon(slot, holder);
        } else {
            // Don't have to do anything in the new world
        }
    }

    /**
    /**
     * Accept a list of MobileIconStates, which all live in the same slot(?!), and then are sorted
     * Accept a list of MobileIconStates, which all live in the same slot(?!), and then are sorted
     * by subId. Don't worry this definitely makes sense and works.
     * by subId. Don't worry this definitely makes sense and works.
@@ -225,7 +244,7 @@ public class StatusBarIconControllerImpl implements Tunable,
    @Override
    @Override
    public void setMobileIcons(String slot, List<MobileIconState> iconStates) {
    public void setMobileIcons(String slot, List<MobileIconState> iconStates) {
        if (mStatusBarPipelineFlags.useNewMobileIcons()) {
        if (mStatusBarPipelineFlags.useNewMobileIcons()) {
            Log.d(TAG, "ignoring old pipeline callbacks, because the new "
            Log.d(TAG, "ignoring old pipeline callbacks, because the new mobile "
                    + "icons are enabled");
                    + "icons are enabled");
            return;
            return;
        }
        }
@@ -251,10 +270,11 @@ public class StatusBarIconControllerImpl implements Tunable,
    public void setNewMobileIconSubIds(List<Integer> subIds) {
    public void setNewMobileIconSubIds(List<Integer> subIds) {
        if (!mStatusBarPipelineFlags.useNewMobileIcons()) {
        if (!mStatusBarPipelineFlags.useNewMobileIcons()) {
            Log.d(TAG, "ignoring new pipeline callback, "
            Log.d(TAG, "ignoring new pipeline callback, "
                    + "since the new icons are disabled");
                    + "since the new mobile icons are disabled");
            return;
            return;
        }
        }
        Slot mobileSlot = mStatusBarIconList.getSlot("mobile");
        String slotName = mContext.getString(com.android.internal.R.string.status_bar_mobile);
        Slot mobileSlot = mStatusBarIconList.getSlot(slotName);


        Collections.reverse(subIds);
        Collections.reverse(subIds);


@@ -262,7 +282,7 @@ public class StatusBarIconControllerImpl implements Tunable,
            StatusBarIconHolder holder = mobileSlot.getHolderForTag(subId);
            StatusBarIconHolder holder = mobileSlot.getHolderForTag(subId);
            if (holder == null) {
            if (holder == null) {
                holder = StatusBarIconHolder.fromSubIdForModernMobileIcon(subId);
                holder = StatusBarIconHolder.fromSubIdForModernMobileIcon(subId);
                setIcon("mobile", holder);
                setIcon(slotName, holder);
            } else {
            } else {
                // Don't have to do anything in the new world
                // Don't have to do anything in the new world
            }
            }
+27 −4
Original line number Original line Diff line number Diff line
@@ -51,11 +51,24 @@ public class StatusBarIconHolder {
    @Deprecated
    @Deprecated
    public static final int TYPE_MOBILE_NEW = 3;
    public static final int TYPE_MOBILE_NEW = 3;


    /**
     * TODO (b/238425913): address this once the new pipeline is in place
     * This type exists so that the new wifi pipeline can be used to inform the old view system
     * about the existence of the wifi icon. The design of the new pipeline should allow for removal
     * of this icon holder type, and obsolete the need for this entire class.
     *
     * @deprecated This field only exists so the new status bar pipeline can interface with the
     * view holder system.
     */
    @Deprecated
    public static final int TYPE_WIFI_NEW = 4;

    @IntDef({
    @IntDef({
            TYPE_ICON,
            TYPE_ICON,
            TYPE_WIFI,
            TYPE_WIFI,
            TYPE_MOBILE,
            TYPE_MOBILE,
            TYPE_MOBILE_NEW
            TYPE_MOBILE_NEW,
            TYPE_WIFI_NEW
    })
    })
    @Retention(RetentionPolicy.SOURCE)
    @Retention(RetentionPolicy.SOURCE)
    @interface IconType {}
    @interface IconType {}
@@ -95,6 +108,13 @@ public class StatusBarIconHolder {
        return holder;
        return holder;
    }
    }


    /** Creates a new holder with for the new wifi icon. */
    public static StatusBarIconHolder forNewWifiIcon() {
        StatusBarIconHolder holder = new StatusBarIconHolder();
        holder.mType = TYPE_WIFI_NEW;
        return holder;
    }

    /** */
    /** */
    public static StatusBarIconHolder fromMobileIconState(MobileIconState state) {
    public static StatusBarIconHolder fromMobileIconState(MobileIconState state) {
        StatusBarIconHolder holder = new StatusBarIconHolder();
        StatusBarIconHolder holder = new StatusBarIconHolder();
@@ -172,9 +192,10 @@ public class StatusBarIconHolder {
            case TYPE_MOBILE:
            case TYPE_MOBILE:
                return mMobileState.visible;
                return mMobileState.visible;
            case TYPE_MOBILE_NEW:
            case TYPE_MOBILE_NEW:
                //TODO (b/249790733), the new pipeline can control visibility via the ViewModel
            case TYPE_WIFI_NEW:
                // The new pipeline controls visibilities via the view model and view binder, so
                // this is effectively an unused return value.
                return true;
                return true;

            default:
            default:
                return true;
                return true;
        }
        }
@@ -199,7 +220,9 @@ public class StatusBarIconHolder {
                break;
                break;


            case TYPE_MOBILE_NEW:
            case TYPE_MOBILE_NEW:
                //TODO (b/249790733), the new pipeline can control visibility via the ViewModel
            case TYPE_WIFI_NEW:
                // The new pipeline controls visibilities via the view model and view binder, so
                // ignore setVisible.
                break;
                break;
        }
        }
    }
    }
+1 −1
Original line number Original line Diff line number Diff line
@@ -212,7 +212,7 @@ public class StatusBarSignalPolicy implements SignalCallback,
    private void updateWifiIconWithState(WifiIconState state) {
    private void updateWifiIconWithState(WifiIconState state) {
        if (DEBUG) Log.d(TAG, "WifiIconState: " + state == null ? "" : state.toString());
        if (DEBUG) Log.d(TAG, "WifiIconState: " + state == null ? "" : state.toString());
        if (state.visible && state.resId > 0) {
        if (state.visible && state.resId > 0) {
            mIconController.setSignalIcon(mSlotWifi, state);
            mIconController.setWifiIcon(mSlotWifi, state);
            mIconController.setIconVisibility(mSlotWifi, true);
            mIconController.setIconVisibility(mSlotWifi, true);
        } else {
        } else {
            mIconController.setIconVisibility(mSlotWifi, false);
            mIconController.setIconVisibility(mSlotWifi, false);
+80 −0
Original line number Original line Diff line number Diff line
/*
 * 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

import android.view.ViewGroup
import androidx.lifecycle.Lifecycle
import androidx.lifecycle.repeatOnLifecycle
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.lifecycle.repeatWhenAttached
import com.android.systemui.statusbar.phone.StatusBarIconController
import com.android.systemui.statusbar.phone.StatusBarLocation
import com.android.systemui.statusbar.pipeline.wifi.ui.viewmodel.LocationBasedWifiViewModel
import com.android.systemui.statusbar.pipeline.wifi.ui.viewmodel.WifiViewModel
import javax.inject.Inject
import kotlinx.coroutines.flow.collect
import kotlinx.coroutines.launch

/**
 * This class serves as a bridge between the old UI classes and the new data pipeline.
 *
 * Once the new pipeline notifies [wifiViewModel] that the wifi icon should be visible, this class
 * notifies [iconController] to inflate the wifi icon (if needed). After that, the [wifiViewModel]
 * has sole responsibility for updating the wifi icon drawable, visibility, etc. and the
 * [iconController] will not do any updates to the icon.
 */
@SysUISingleton
class WifiUiAdapter
@Inject
constructor(
    private val iconController: StatusBarIconController,
    private val wifiViewModel: WifiViewModel,
) {
    /**
     * Binds the container for all the status bar icons to a view model, so that we inflate the wifi
     * view once we receive a valid icon from the data pipeline.
     *
     * NOTE: This should go away as we better integrate the data pipeline with the UI.
     *
     * @return the view model used for this particular group in the given [location].
     */
    fun bindGroup(
        statusBarIconGroup: ViewGroup,
        location: StatusBarLocation,
    ): LocationBasedWifiViewModel {
        val locationViewModel =
            when (location) {
                StatusBarLocation.HOME -> wifiViewModel.home
                StatusBarLocation.KEYGUARD -> wifiViewModel.keyguard
                StatusBarLocation.QS -> wifiViewModel.qs
            }

        statusBarIconGroup.repeatWhenAttached {
            repeatOnLifecycle(Lifecycle.State.STARTED) {
                launch {
                    locationViewModel.wifiIcon.collect { wifiIcon ->
                        if (wifiIcon != null) {
                            iconController.setNewWifiIcon()
                        }
                    }
                }
            }
        }

        return locationViewModel
    }
}
Loading