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

Commit c1562289 authored by Darrell Shi's avatar Darrell Shi Committed by Android (Google) Code Review
Browse files

Merge "Remove stopwatch widget" into main

parents e5aaca81 318d6ebd
Loading
Loading
Loading
Loading
+0 −50
Original line number Diff line number Diff line
@@ -18,13 +18,11 @@ package com.android.systemui.communal.data.repository

import android.appwidget.AppWidgetHost
import android.appwidget.AppWidgetManager
import android.appwidget.AppWidgetProviderInfo
import android.content.BroadcastReceiver
import android.content.ComponentName
import android.content.Context
import android.content.Intent
import android.content.IntentFilter
import android.content.pm.PackageManager
import android.os.UserManager
import com.android.systemui.broadcast.BroadcastDispatcher
import com.android.systemui.common.coroutine.ChannelExt.trySendWithFailureLogging
@@ -32,13 +30,10 @@ import com.android.systemui.communal.data.db.CommunalItemRank
import com.android.systemui.communal.data.db.CommunalWidgetDao
import com.android.systemui.communal.data.db.CommunalWidgetItem
import com.android.systemui.communal.shared.CommunalWidgetHost
import com.android.systemui.communal.shared.model.CommunalAppWidgetInfo
import com.android.systemui.communal.shared.model.CommunalWidgetContentModel
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.dagger.qualifiers.Application
import com.android.systemui.dagger.qualifiers.Background
import com.android.systemui.flags.FeatureFlagsClassic
import com.android.systemui.flags.Flags
import com.android.systemui.log.LogBuffer
import com.android.systemui.log.core.Logger
import com.android.systemui.log.dagger.CommunalLog
@@ -58,9 +53,6 @@ import kotlinx.coroutines.launch

/** Encapsulates the state of widgets for communal mode. */
interface CommunalWidgetRepository {
    /** A flow of provider info for the stopwatch widget, or null if widget is unavailable. */
    val stopwatchAppWidgetInfo: Flow<CommunalAppWidgetInfo?>

    /** A flow of information about active communal widgets stored in database. */
    val communalWidgets: Flow<List<CommunalWidgetContentModel>>

@@ -84,15 +76,12 @@ constructor(
    communalRepository: CommunalRepository,
    private val communalWidgetHost: CommunalWidgetHost,
    private val communalWidgetDao: CommunalWidgetDao,
    private val packageManager: PackageManager,
    private val userManager: UserManager,
    private val userTracker: UserTracker,
    @CommunalLog logBuffer: LogBuffer,
    featureFlags: FeatureFlagsClassic,
) : CommunalWidgetRepository {
    companion object {
        const val TAG = "CommunalWidgetRepository"
        const val WIDGET_LABEL = "Stopwatch"
    }

    private val logger = Logger(logBuffer, TAG)
@@ -100,9 +89,6 @@ constructor(
    // Whether the [AppWidgetHost] is listening for updates.
    private var isHostListening = false

    // Widgets that should be rendered in communal mode.
    private val widgets: HashMap<Int, CommunalAppWidgetInfo> = hashMapOf()

    private val isUserUnlocked: Flow<Boolean> =
        callbackFlow {
                if (!communalRepository.isCommunalEnabled) {
@@ -149,25 +135,6 @@ constructor(
            }
        }

    override val stopwatchAppWidgetInfo: Flow<CommunalAppWidgetInfo?> =
        isHostActive.map { isHostActive ->
            if (!isHostActive || !featureFlags.isEnabled(Flags.WIDGET_ON_KEYGUARD)) {
                return@map null
            }

            val providerInfo =
                appWidgetManager.installedProviders.find {
                    it.loadLabel(packageManager).equals(WIDGET_LABEL)
                }

            if (providerInfo == null) {
                logger.w("Cannot find app widget: $WIDGET_LABEL")
                return@map null
            }

            return@map addStopWatchWidget(providerInfo)
        }

    override val communalWidgets: Flow<List<CommunalWidgetContentModel>> =
        isHostActive.flatMapLatest { isHostActive ->
            if (!isHostActive) {
@@ -226,21 +193,4 @@ constructor(
        appWidgetHost.stopListening()
        isHostListening = false
    }

    // TODO(b/306471933): remove this prototype that shows a stopwatch in the communal blueprint
    private fun addStopWatchWidget(providerInfo: AppWidgetProviderInfo): CommunalAppWidgetInfo {
        val existing = widgets.values.firstOrNull { it.providerInfo == providerInfo }
        if (existing != null) {
            return existing
        }

        val appWidgetId = appWidgetHost.allocateAppWidgetId()
        val widget =
            CommunalAppWidgetInfo(
                providerInfo,
                appWidgetId,
            )
        widgets[appWidgetId] = widget
        return widget
    }
}
+0 −4
Original line number Diff line number Diff line
@@ -23,7 +23,6 @@ import com.android.systemui.communal.data.repository.CommunalMediaRepository
import com.android.systemui.communal.data.repository.CommunalRepository
import com.android.systemui.communal.data.repository.CommunalWidgetRepository
import com.android.systemui.communal.domain.model.CommunalContentModel
import com.android.systemui.communal.shared.model.CommunalAppWidgetInfo
import com.android.systemui.communal.shared.model.CommunalContentSize
import com.android.systemui.communal.shared.model.CommunalSceneKey
import com.android.systemui.dagger.SysUISingleton
@@ -55,9 +54,6 @@ constructor(
    val isCommunalEnabled: Boolean
        get() = communalRepository.isCommunalEnabled

    /** A flow of info about the widget to be displayed, or null if widget is unavailable. */
    val appWidgetInfo: Flow<CommunalAppWidgetInfo?> = widgetRepository.stopwatchAppWidgetInfo

    /**
     * Target scene as requested by the underlying [SceneTransitionLayout] or through
     * [onSceneChanged].
+0 −70
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.communal.ui.binder

import androidx.lifecycle.Lifecycle
import androidx.lifecycle.repeatOnLifecycle
import com.android.systemui.res.R
import com.android.systemui.communal.ui.adapter.CommunalWidgetViewAdapter
import com.android.systemui.communal.ui.view.CommunalWidgetWrapper
import com.android.systemui.communal.ui.viewmodel.CommunalWidgetViewModel
import com.android.systemui.keyguard.domain.interactor.KeyguardBlueprintInteractor
import com.android.systemui.keyguard.ui.view.KeyguardRootView
import com.android.systemui.lifecycle.repeatWhenAttached
import kotlinx.coroutines.launch

/** Binds [CommunalWidgetViewModel] to the keyguard root view. */
object CommunalWidgetViewBinder {

    @JvmStatic
    fun bind(
        rootView: KeyguardRootView,
        viewModel: CommunalWidgetViewModel,
        adapter: CommunalWidgetViewAdapter,
        keyguardBlueprintInteractor: KeyguardBlueprintInteractor,
    ) {
        rootView.repeatWhenAttached {
            repeatOnLifecycle(Lifecycle.State.STARTED) {
                launch {
                    adapter.adapt(viewModel.appWidgetInfo).collect {
                        val oldView =
                            rootView.findViewById<CommunalWidgetWrapper>(
                                R.id.communal_widget_wrapper
                            )
                        var dirty = false

                        if (oldView != null) {
                            rootView.removeView(oldView)
                            dirty = true
                        }

                        if (it != null) {
                            rootView.addView(it)
                            dirty = true
                        }

                        if (dirty) {
                            keyguardBlueprintInteractor.refreshBlueprint()
                        }
                    }
                }

                launch { viewModel.alpha.collect { rootView.alpha = it } }
            }
        }
    }
}
+0 −3
Original line number Diff line number Diff line
@@ -17,7 +17,6 @@
package com.android.systemui.communal.ui.view.layout.blueprints

import com.android.systemui.communal.ui.view.layout.sections.DefaultCommunalHubSection
import com.android.systemui.communal.ui.view.layout.sections.DefaultCommunalWidgetSection
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.keyguard.shared.model.KeyguardBlueprint
import com.android.systemui.keyguard.shared.model.KeyguardSection
@@ -30,13 +29,11 @@ class DefaultCommunalBlueprint
@Inject
constructor(
    defaultCommunalHubSection: DefaultCommunalHubSection,
    defaultCommunalWidgetSection: DefaultCommunalWidgetSection,
) : KeyguardBlueprint {
    override val id: String = COMMUNAL
    override val sections: List<KeyguardSection> =
        listOf(
            defaultCommunalHubSection,
            defaultCommunalWidgetSection,
        )

    companion object {
+0 −73
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.communal.ui.view.layout.sections

import android.view.ViewGroup.LayoutParams.WRAP_CONTENT
import androidx.constraintlayout.widget.ConstraintLayout
import androidx.constraintlayout.widget.ConstraintSet
import androidx.constraintlayout.widget.ConstraintSet.BOTTOM
import androidx.constraintlayout.widget.ConstraintSet.END
import androidx.constraintlayout.widget.ConstraintSet.PARENT_ID
import com.android.systemui.res.R
import com.android.systemui.communal.ui.adapter.CommunalWidgetViewAdapter
import com.android.systemui.communal.ui.binder.CommunalWidgetViewBinder
import com.android.systemui.communal.ui.viewmodel.CommunalWidgetViewModel
import com.android.systemui.flags.FeatureFlags
import com.android.systemui.flags.Flags
import com.android.systemui.keyguard.domain.interactor.KeyguardBlueprintInteractor
import com.android.systemui.keyguard.shared.model.KeyguardSection
import com.android.systemui.keyguard.ui.view.KeyguardRootView
import dagger.Lazy
import javax.inject.Inject

class DefaultCommunalWidgetSection
@Inject
constructor(
    private val featureFlags: FeatureFlags,
    private val keyguardRootView: KeyguardRootView,
    private val communalWidgetViewModel: CommunalWidgetViewModel,
    private val communalWidgetViewAdapter: CommunalWidgetViewAdapter,
    private val keyguardBlueprintInteractor: Lazy<KeyguardBlueprintInteractor>,
) : KeyguardSection() {
    private val widgetAreaViewId = R.id.communal_widget_wrapper

    override fun addViews(constraintLayout: ConstraintLayout) {}

    override fun bindData(constraintLayout: ConstraintLayout) {
        if (!featureFlags.isEnabled(Flags.WIDGET_ON_KEYGUARD)) {
            return
        }

        CommunalWidgetViewBinder.bind(
            keyguardRootView,
            communalWidgetViewModel,
            communalWidgetViewAdapter,
            keyguardBlueprintInteractor.get(),
        )
    }

    override fun applyConstraints(constraintSet: ConstraintSet) {
        constraintSet.apply {
            constrainWidth(widgetAreaViewId, WRAP_CONTENT)
            constrainHeight(widgetAreaViewId, WRAP_CONTENT)
            connect(widgetAreaViewId, BOTTOM, PARENT_ID, BOTTOM)
            connect(widgetAreaViewId, END, PARENT_ID, END)
        }
    }

    override fun removeViews(constraintLayout: ConstraintLayout) {}
}
Loading