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

Commit 70d5d0cd authored by Liana Kazanova (xWF)'s avatar Liana Kazanova (xWF) Committed by Android (Google) Code Review
Browse files

Merge "Revert "CastDetailsView: Create CastDetailsViewModel and CastDetailsViewContent"" into main

parents 164a30ba 6cb15e7f
Loading
Loading
Loading
Loading
+2 −31
Original line number Diff line number Diff line
@@ -50,7 +50,6 @@ import com.android.systemui.plugins.statusbar.StatusBarStateController;
import com.android.systemui.qs.QSHost;
import com.android.systemui.qs.QsEventLogger;
import com.android.systemui.qs.logging.QSLogger;
import com.android.systemui.qs.tiles.dialog.CastDetailsViewModel;
import com.android.systemui.shade.domain.interactor.FakeShadeDialogContextInteractor;
import com.android.systemui.shade.domain.interactor.ShadeDialogContextInteractor;
import com.android.systemui.statusbar.connectivity.IconState;
@@ -64,7 +63,6 @@ import com.android.systemui.statusbar.policy.HotspotController;
import com.android.systemui.statusbar.policy.KeyguardStateController;

import org.junit.After;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -106,8 +104,6 @@ public class CastTileTest extends SysuiTestCase {
    private DialogTransitionAnimator mDialogTransitionAnimator;
    @Mock
    private QsEventLogger mUiEventLogger;
    @Mock
    private CastDetailsViewModel.Factory mCastDetailsViewModelFactory;

    private final TileJavaAdapter mJavaAdapter = new TileJavaAdapter();
    private final FakeConnectivityRepository mConnectivityRepository =
@@ -521,29 +517,6 @@ public class CastTileTest extends SysuiTestCase {
        assertTrue(mCastTile.getState().forceExpandIcon);
    }

    @Test
    public void testDetailsViewUnavailableState_returnsNull() {
        createAndStartTileNewImpl();
        mTestableLooper.processAllMessages();

        assertEquals(Tile.STATE_UNAVAILABLE, mCastTile.getState().state);
        mCastTile.getDetailsViewModel(Assert::assertNull);
    }

    @Test
    public void testDetailsViewAvailableState_returnsNotNull() {
        createAndStartTileNewImpl();
        CastDevice device = createConnectedCastDevice();
        List<CastDevice> devices = new ArrayList<>();
        devices.add(device);
        when(mController.getCastDevices()).thenReturn(devices);
        mConnectivityRepository.setWifiConnected(true);
        mTestableLooper.processAllMessages();

        assertEquals(Tile.STATE_ACTIVE, mCastTile.getState().state);
        mCastTile.getDetailsViewModel(Assert::assertNotNull);
    }

    /**
     * For simplicity, let this method still set the field even though that's kind of gross
     */
@@ -567,8 +540,7 @@ public class CastTileTest extends SysuiTestCase {
                mConnectivityRepository,
                mJavaAdapter,
                mFeatureFlags,
                mShadeDialogContextInteractor,
                mCastDetailsViewModelFactory
                mShadeDialogContextInteractor
        );
        mCastTile.initialize();

@@ -612,8 +584,7 @@ public class CastTileTest extends SysuiTestCase {
                mConnectivityRepository,
                mJavaAdapter,
                mFeatureFlags,
                mShadeDialogContextInteractor,
                mCastDetailsViewModelFactory
                mShadeDialogContextInteractor
        );
        mCastTile.initialize();

+0 −3
Original line number Diff line number Diff line
@@ -43,8 +43,6 @@ import com.android.systemui.bluetooth.qsdialog.BluetoothDetailsViewModel
import com.android.systemui.plugins.qs.TileDetailsViewModel
import com.android.systemui.qs.flags.QsDetailedView
import com.android.systemui.qs.panels.ui.viewmodel.DetailsViewModel
import com.android.systemui.qs.tiles.dialog.CastDetailsContent
import com.android.systemui.qs.tiles.dialog.CastDetailsViewModel
import com.android.systemui.qs.tiles.dialog.InternetDetailsContent
import com.android.systemui.qs.tiles.dialog.InternetDetailsViewModel
import com.android.systemui.qs.tiles.dialog.ModesDetailsContent
@@ -133,7 +131,6 @@ private fun MapTileDetailsContent(tileDetailsViewModel: TileDetailsViewModel) {
        is BluetoothDetailsViewModel ->
            BluetoothDetailsContent(tileDetailsViewModel.detailsContentViewModel)
        is ModesDetailsViewModel -> ModesDetailsContent(tileDetailsViewModel)
        is CastDetailsViewModel -> CastDetailsContent()
    }
}

+13 −40
Original line number Diff line number Diff line
@@ -48,13 +48,11 @@ 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;
import com.android.systemui.plugins.qs.TileDetailsViewModel;
import com.android.systemui.plugins.statusbar.StatusBarStateController;
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.CastDetailsViewModel;
import com.android.systemui.res.R;
import com.android.systemui.shade.domain.interactor.ShadeDialogContextInteractor;
import com.android.systemui.statusbar.connectivity.NetworkController;
@@ -95,7 +93,6 @@ public class CastTile extends QSTileImpl<BooleanState> {
    private final ShadeDialogContextInteractor mShadeDialogContextInteractor;
    private boolean mCastTransportAllowed;
    private boolean mHotspotConnected;
    private final CastDetailsViewModel.Factory mCastDetailsViewModelFactory;

    @Inject
    public CastTile(
@@ -116,8 +113,7 @@ public class CastTile extends QSTileImpl<BooleanState> {
            ConnectivityRepository connectivityRepository,
            TileJavaAdapter javaAdapter,
            FeatureFlags featureFlags,
            ShadeDialogContextInteractor shadeDialogContextInteractor,
            CastDetailsViewModel.Factory castDetailsViewModelFactory
            ShadeDialogContextInteractor shadeDialogContextInteractor
    ) {
        super(host, uiEventLogger, backgroundLooper, mainHandler, falsingManager, metricsLogger,
                statusBarStateController, activityStarter, qsLogger);
@@ -128,7 +124,6 @@ public class CastTile extends QSTileImpl<BooleanState> {
        mJavaAdapter = javaAdapter;
        mFeatureFlags = featureFlags;
        mShadeDialogContextInteractor = shadeDialogContextInteractor;
        mCastDetailsViewModelFactory = castDetailsViewModelFactory;
        mController.observe(this, mCallback);
        mKeyguard.observe(this, mCallback);
        if (!mFeatureFlags.isEnabled(SIGNAL_CALLBACK_DEPRECATION)) {
@@ -177,7 +172,12 @@ public class CastTile extends QSTileImpl<BooleanState> {

    @Override
    protected void handleClick(@Nullable Expandable expandable) {
        handleClick(() -> {
        if (getState().state == Tile.STATE_UNAVAILABLE) {
            return;
        }

        List<CastDevice> activeDevices = getActiveDevices();
        if (willPopDialog()) {
            if (!mKeyguard.isShowing()) {
                showDialog(expandable);
            } else {
@@ -187,43 +187,16 @@ public class CastTile extends QSTileImpl<BooleanState> {
                    showDialog(null /* view */);
                });
            }
        });
    }

    @Override
    public boolean getDetailsViewModel(Consumer<TileDetailsViewModel> callback) {
        CastDetailsViewModel viewModel = mCastDetailsViewModelFactory.create();
        handleClick(() -> {
            if (!mKeyguard.isShowing()) {
                callback.accept(viewModel);
            } else {
                mActivityStarter.dismissKeyguardThenExecute(() -> {
                    callback.accept(viewModel);
                    return false;
                },  null /* cancelAction */,  true/* afterKeyguardGone */);
            }
        });
        return true;
    }

    private void handleClick(Runnable showPromptCallback) {
        if (getState().state == Tile.STATE_UNAVAILABLE) {
            return;
        }

        List<CastDevice> activeDevices = getActiveDevices();
        if (willShowPrompt()) {
            showPromptCallback.run();
        } else {
            mController.stopCasting(activeDevices.get(0), StopReason.STOP_QS_TILE);
        }
    }

    // We want to pop up the media route selection dialog (or show the cast details view) if we
    // either have no active devices (neither routes nor projection), or if we have an active
    // route. In other cases, we assume that a projection is active. This is messy, but this tile
    // never correctly handled the case where multiple devices were active :-/.
    private boolean willShowPrompt() {
    // We want to pop up the media route selection dialog if we either have no active devices
    // (neither routes nor projection), or if we have an active route. In other cases, we assume
    // that a projection is active. This is messy, but this tile never correctly handled the
    // case where multiple devices were active :-/.
    private boolean willPopDialog() {
        List<CastDevice> activeDevices = getActiveDevices();
        return activeDevices.isEmpty() || (activeDevices.get(0).getTag() instanceof RouteInfo);
    }
@@ -330,7 +303,7 @@ public class CastTile extends QSTileImpl<BooleanState> {
                state.secondaryLabel = "";
            }
            state.expandedAccessibilityClassName = Button.class.getName();
            state.forceExpandIcon = willShowPrompt();
            state.forceExpandIcon = willPopDialog();
        } else {
            state.state = Tile.STATE_UNAVAILABLE;
            String noWifi = mContext.getString(R.string.quick_settings_cast_no_network);
+0 −37
Original line number Diff line number Diff line
/*
 * Copyright (C) 2025 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.dialog

import android.view.LayoutInflater
import androidx.compose.foundation.layout.fillMaxHeight
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.viewinterop.AndroidView
import com.android.internal.R

@Composable
fun CastDetailsContent() {
    // TODO(b/378514236): Finish implementing this function.
    AndroidView(
        modifier = Modifier.fillMaxWidth().fillMaxHeight(),
        factory = { context ->
            // Inflate with the existing dialog xml layout
            LayoutInflater.from(context).inflate(R.layout.media_route_controller_dialog, null)
        },
    )
}
+0 −50
Original line number Diff line number Diff line
/*
 * Copyright (C) 2025 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.dialog

import android.content.Intent
import android.provider.Settings
import com.android.systemui.plugins.qs.TileDetailsViewModel
import com.android.systemui.qs.tiles.base.actions.QSTileIntentUserInputHandler
import dagger.assisted.AssistedFactory
import dagger.assisted.AssistedInject

/** The view model used for the screen record details view in the Quick Settings */
class CastDetailsViewModel
@AssistedInject
constructor(private val qsTileIntentUserActionHandler: QSTileIntentUserInputHandler) :
    TileDetailsViewModel {
    @AssistedFactory
    fun interface Factory {
        fun create(): CastDetailsViewModel
    }

    override fun clickOnSettingsButton() {
        qsTileIntentUserActionHandler.handle(
            /* expandable= */ null,
            Intent(Settings.ACTION_CAST_SETTINGS),
        )
    }

    // TODO(b/388321032): Replace this string with a string in a translatable xml file,
    override val title: String
        get() = "Cast screen to device"

    // TODO(b/388321032): Replace this string with a string in a translatable xml file,
    override val subTitle: String
        get() = "Searching for devices..."
}