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

Commit 0ee361bf authored by Evan Laird's avatar Evan Laird Committed by Android (Google) Code Review
Browse files

Merge changes from topics "icon-interactor", "wifi-networks" into udc-qpr-dev

* changes:
  [QS] Add flag-protected InternetTile backed by new data pipeline
  [Sb refactor] Add network scan results to wifi repo
  [Sb refactor] WIP - InternetTileViewModel
  [Sb refactor] switch broadcast off of BroadcastDispatcher
  [Sb refactor] Add WifiIcon.fromModel for use in QS
  [Sb refactor] EthernetInteractor to support QS tiles
  [Sb refactor] Convert CastTile to use WifiRepository
  [Sb refactor] flag for deprecation of SignalCallback
  [Sb refactor] Remove some unused fields from MobileIconInteractor
  [Sb refactor] Move icon to the interactor
parents 97c11a93 5ab3abb4
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
@@ -375,6 +375,9 @@ object Flags {

    // 600- status bar

    // TODO(b/291315866): Tracking Bug
    @JvmField val SIGNAL_CALLBACK_DEPRECATION = unreleasedFlag("signal_callback_deprecation")

    // TODO(b/265892345): Tracking Bug
    val PLUG_IN_STATUS_BAR_CHIP = releasedFlag("plug_in_status_bar_chip")

+48 −17
Original line number Diff line number Diff line
@@ -18,6 +18,8 @@ package com.android.systemui.qs.tiles;

import static android.media.MediaRouter.ROUTE_TYPE_REMOTE_DISPLAY;

import static com.android.systemui.flags.Flags.SIGNAL_CALLBACK_DEPRECATION;

import android.annotation.NonNull;
import android.app.Dialog;
import android.content.Intent;
@@ -42,6 +44,7 @@ import com.android.systemui.animation.DialogCuj;
import com.android.systemui.animation.DialogLaunchAnimator;
import com.android.systemui.dagger.qualifiers.Background;
import com.android.systemui.dagger.qualifiers.Main;
import com.android.systemui.flags.FeatureFlags;
import com.android.systemui.plugins.ActivityStarter;
import com.android.systemui.plugins.FalsingManager;
import com.android.systemui.plugins.qs.QSTile.BooleanState;
@@ -54,6 +57,8 @@ import com.android.systemui.statusbar.connectivity.NetworkController;
import com.android.systemui.statusbar.connectivity.SignalCallback;
import com.android.systemui.statusbar.connectivity.WifiIndicators;
import com.android.systemui.statusbar.phone.SystemUIDialog;
import com.android.systemui.statusbar.pipeline.wifi.domain.interactor.WifiInteractor;
import com.android.systemui.statusbar.pipeline.wifi.shared.model.WifiNetworkModel;
import com.android.systemui.statusbar.policy.CastController;
import com.android.systemui.statusbar.policy.CastController.CastDevice;
import com.android.systemui.statusbar.policy.HotspotController;
@@ -61,6 +66,7 @@ import com.android.systemui.statusbar.policy.KeyguardStateController;

import java.util.ArrayList;
import java.util.List;
import java.util.function.Consumer;

import javax.inject.Inject;

@@ -79,6 +85,9 @@ public class CastTile extends QSTileImpl<BooleanState> {
    private final NetworkController mNetworkController;
    private final DialogLaunchAnimator mDialogLaunchAnimator;
    private final Callback mCallback = new Callback();
    private final WifiInteractor mWifiInteractor;
    private final TileJavaAdapter mJavaAdapter;
    private final FeatureFlags mFeatureFlags;
    private boolean mWifiConnected;
    private boolean mHotspotConnected;

@@ -97,7 +106,10 @@ public class CastTile extends QSTileImpl<BooleanState> {
            KeyguardStateController keyguardStateController,
            NetworkController networkController,
            HotspotController hotspotController,
            DialogLaunchAnimator dialogLaunchAnimator
            DialogLaunchAnimator dialogLaunchAnimator,
            WifiInteractor wifiInteractor,
            TileJavaAdapter javaAdapter,
            FeatureFlags featureFlags
    ) {
        super(host, uiEventLogger, backgroundLooper, mainHandler, falsingManager, metricsLogger,
                statusBarStateController, activityStarter, qsLogger);
@@ -105,9 +117,16 @@ public class CastTile extends QSTileImpl<BooleanState> {
        mKeyguard = keyguardStateController;
        mNetworkController = networkController;
        mDialogLaunchAnimator = dialogLaunchAnimator;
        mWifiInteractor = wifiInteractor;
        mJavaAdapter = javaAdapter;
        mFeatureFlags = featureFlags;
        mController.observe(this, mCallback);
        mKeyguard.observe(this, mCallback);
        if (!mFeatureFlags.isEnabled(SIGNAL_CALLBACK_DEPRECATION)) {
            mNetworkController.observe(this, mSignalCallback);
        } else {
            mJavaAdapter.bind(this, mWifiInteractor.getWifiNetwork(), mNetworkModelConsumer);
        }
        hotspotController.observe(this, mHotspotCallback);
    }

@@ -293,20 +312,38 @@ public class CastTile extends QSTileImpl<BooleanState> {
        return mWifiConnected || mHotspotConnected;
    }

    private final SignalCallback mSignalCallback = new SignalCallback() {
                @Override
                public void setWifiIndicators(@NonNull WifiIndicators indicators) {
                    // statusIcon.visible has the connected status information
                    boolean enabledAndConnected = indicators.enabled
                            && (indicators.qsIcon == null ? false : indicators.qsIcon.visible);
                    if (enabledAndConnected != mWifiConnected) {
                        mWifiConnected = enabledAndConnected;
    private void setWifiConnected(boolean connected) {
        if (connected != mWifiConnected) {
            mWifiConnected = connected;
            // Hotspot is not connected, so changes here should update
            if (!mHotspotConnected) {
                refreshState();
            }
        }
    }

    private void setHotspotConnected(boolean connected) {
        if (connected != mHotspotConnected) {
            mHotspotConnected = connected;
            // Wifi is not connected, so changes here should update
            if (!mWifiConnected) {
                refreshState();
            }
        }
    }

    private final Consumer<WifiNetworkModel> mNetworkModelConsumer = (model) -> {
        setWifiConnected(model instanceof WifiNetworkModel.Active);
    };

    private final SignalCallback mSignalCallback = new SignalCallback() {
                @Override
                public void setWifiIndicators(@NonNull WifiIndicators indicators) {
                    // statusIcon.visible has the connected status information
                    boolean enabledAndConnected = indicators.enabled
                            && (indicators.qsIcon != null && indicators.qsIcon.visible);
                    setWifiConnected(enabledAndConnected);
                }
            };

    private final HotspotController.Callback mHotspotCallback =
@@ -314,13 +351,7 @@ public class CastTile extends QSTileImpl<BooleanState> {
                @Override
                public void onHotspotChanged(boolean enabled, int numDevices) {
                    boolean enabledAndConnected = enabled && numDevices > 0;
                    if (enabledAndConnected != mHotspotConnected) {
                        mHotspotConnected = enabledAndConnected;
                        // Wifi is not connected, so changes here should update
                        if (!mWifiConnected) {
                            refreshState();
                        }
                    }
                    setHotspotConnected(enabledAndConnected);
                }
            };

+114 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2023 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.qs.tiles

import android.content.Context
import android.content.Intent
import android.os.Handler
import android.os.Looper
import android.provider.Settings
import android.view.View
import com.android.internal.logging.MetricsLogger
import com.android.systemui.R
import com.android.systemui.dagger.qualifiers.Background
import com.android.systemui.dagger.qualifiers.Main
import com.android.systemui.plugins.ActivityStarter
import com.android.systemui.plugins.FalsingManager
import com.android.systemui.plugins.qs.QSIconView
import com.android.systemui.plugins.qs.QSTile
import com.android.systemui.plugins.statusbar.StatusBarStateController
import com.android.systemui.qs.AlphaControlledSignalTileView
import com.android.systemui.qs.QSHost
import com.android.systemui.qs.QsEventLogger
import com.android.systemui.qs.logging.QSLogger
import com.android.systemui.qs.tileimpl.QSTileImpl
import com.android.systemui.qs.tiles.dialog.InternetDialogFactory
import com.android.systemui.statusbar.connectivity.AccessPointController
import com.android.systemui.statusbar.pipeline.shared.ui.binder.InternetTileBinder
import com.android.systemui.statusbar.pipeline.shared.ui.model.InternetTileModel
import com.android.systemui.statusbar.pipeline.shared.ui.viewmodel.InternetTileViewModel
import javax.inject.Inject

class InternetTileNewImpl
@Inject
constructor(
    host: QSHost,
    uiEventLogger: QsEventLogger,
    @Background backgroundLooper: Looper,
    @Main private val mainHandler: Handler,
    falsingManager: FalsingManager,
    metricsLogger: MetricsLogger,
    statusBarStateController: StatusBarStateController,
    activityStarter: ActivityStarter,
    qsLogger: QSLogger,
    viewModel: InternetTileViewModel,
    private val internetDialogFactory: InternetDialogFactory,
    private val accessPointController: AccessPointController,
) :
    QSTileImpl<QSTile.SignalState>(
        host,
        uiEventLogger,
        backgroundLooper,
        mainHandler,
        falsingManager,
        metricsLogger,
        statusBarStateController,
        activityStarter,
        qsLogger
    ) {
    private var model: InternetTileModel = viewModel.tileModel.value

    init {
        InternetTileBinder.bind(lifecycle, viewModel.tileModel) { newModel ->
            model = newModel
            refreshState()
        }
    }

    override fun createTileView(context: Context): QSIconView =
        AlphaControlledSignalTileView(context)

    override fun getTileLabel(): CharSequence =
        mContext.getString(R.string.quick_settings_internet_label)

    override fun newTileState(): QSTile.SignalState {
        return QSTile.SignalState().also { it.forceExpandIcon = true }
    }

    override fun handleClick(view: View?) {
        mainHandler.post {
            internetDialogFactory.create(
                aboveStatusBar = true,
                accessPointController.canConfigMobileData(),
                accessPointController.canConfigWifi(),
                view,
            )
        }
    }

    override fun handleUpdateState(state: QSTile.SignalState, arg: Any?) {
        state.label = mContext.resources.getString(R.string.quick_settings_internet_label)

        model.applyTo(state, mContext)
    }

    override fun getLongClickIntent(): Intent = WIFI_SETTINGS

    companion object {
        private val WIFI_SETTINGS = Intent(Settings.ACTION_WIFI_SETTINGS)
    }
}
+47 −0
Original line number Diff line number Diff line
/*
 *  Copyright (C) 2023 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.qs.tiles

import androidx.lifecycle.Lifecycle
import androidx.lifecycle.LifecycleOwner
import androidx.lifecycle.lifecycleScope
import androidx.lifecycle.repeatOnLifecycle
import com.android.systemui.dagger.SysUISingleton
import java.util.function.Consumer
import javax.inject.Inject
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.collect
import kotlinx.coroutines.launch

/**
 * Utility for binding tiles to kotlin flows. Similar to [JavaAdapter] and usable for QS tiles. We
 * use [Lifecycle.State.RESUMED] here to match the implementation of [CallbackController.observe]
 */
@SysUISingleton
class TileJavaAdapter @Inject constructor() {
    fun <T> bind(
        lifecycleOwner: LifecycleOwner,
        flow: Flow<T>,
        consumer: Consumer<T>,
    ) {
        lifecycleOwner.lifecycleScope.launch {
            lifecycleOwner.repeatOnLifecycle(Lifecycle.State.RESUMED) {
                flow.collect { consumer.accept(it) }
            }
        }
    }
}
+21 −6
Original line number Diff line number Diff line
@@ -16,6 +16,8 @@

package com.android.systemui.statusbar.connectivity

import com.android.systemui.flags.FeatureFlags
import com.android.systemui.flags.Flags.SIGNAL_CALLBACK_DEPRECATION
import com.android.systemui.qs.tileimpl.QSTileImpl
import com.android.systemui.qs.tiles.AirplaneModeTile
import com.android.systemui.qs.tiles.BluetoothTile
@@ -23,21 +25,17 @@ import com.android.systemui.qs.tiles.CastTile
import com.android.systemui.qs.tiles.DataSaverTile
import com.android.systemui.qs.tiles.HotspotTile
import com.android.systemui.qs.tiles.InternetTile
import com.android.systemui.qs.tiles.InternetTileNewImpl
import com.android.systemui.qs.tiles.NfcTile
import dagger.Binds
import dagger.Module
import dagger.Provides
import dagger.multibindings.IntoMap
import dagger.multibindings.StringKey

@Module
interface ConnectivityModule {

    /** Inject InternetTile into tileMap in QSModule */
    @Binds
    @IntoMap
    @StringKey(InternetTile.TILE_SPEC)
    fun bindInternetTile(internetTile: InternetTile): QSTileImpl<*>

    /** Inject BluetoothTile into tileMap in QSModule */
    @Binds
    @IntoMap
@@ -70,4 +68,21 @@ interface ConnectivityModule {

    /** Inject NfcTile into tileMap in QSModule */
    @Binds @IntoMap @StringKey(NfcTile.TILE_SPEC) fun bindNfcTile(nfcTile: NfcTile): QSTileImpl<*>

    companion object {
        /** Inject InternetTile or InternetTileNewImpl into tileMap in QSModule */
        @Provides
        @IntoMap
        @StringKey(InternetTile.TILE_SPEC)
        fun bindInternetTile(
            internetTile: InternetTile,
            newInternetTile: InternetTileNewImpl,
            featureFlags: FeatureFlags,
        ): QSTileImpl<*> =
            if (featureFlags.isEnabled(SIGNAL_CALLBACK_DEPRECATION)) {
                newInternetTile
            } else {
                internetTile
            }
    }
}
Loading