Loading packages/SystemUI/src/com/android/systemui/controls/CustomIconCache.kt 0 → 100644 +76 −0 Original line number Diff line number Diff line /* * Copyright (C) 2020 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.controls import android.content.ComponentName import android.graphics.drawable.Icon import androidx.annotation.GuardedBy import javax.inject.Inject import javax.inject.Singleton /** * Icon cache for custom icons sent with controls. * * It assumes that only one component can be current at the time, to minimize the number of icons * stored at a given time. */ @Singleton class CustomIconCache @Inject constructor() { private var currentComponent: ComponentName? = null @GuardedBy("cache") private val cache: MutableMap<String, Icon> = LinkedHashMap() /** * Store an icon in the cache. * * If the icons currently stored do not correspond to the component to be stored, the cache is * cleared first. */ fun store(component: ComponentName, controlId: String, icon: Icon?) { if (component != currentComponent) { clear() currentComponent = component } synchronized(cache) { if (icon != null) { cache.put(controlId, icon) } else { cache.remove(controlId) } } } /** * Retrieves a custom icon stored in the cache. * * It will return null if the component requested is not the one whose icons are stored, or if * there is no icon cached for that id. */ fun retrieve(component: ComponentName, controlId: String): Icon? { if (component != currentComponent) return null return synchronized(cache) { cache.get(controlId) } } private fun clear() { synchronized(cache) { cache.clear() } } } No newline at end of file packages/SystemUI/src/com/android/systemui/controls/management/ControlsEditingActivity.kt +4 −2 Original line number Diff line number Diff line Loading @@ -29,6 +29,7 @@ import androidx.recyclerview.widget.ItemTouchHelper import androidx.recyclerview.widget.RecyclerView import com.android.systemui.R import com.android.systemui.broadcast.BroadcastDispatcher import com.android.systemui.controls.CustomIconCache import com.android.systemui.controls.controller.ControlsControllerImpl import com.android.systemui.controls.controller.StructureInfo import com.android.systemui.globalactions.GlobalActionsComponent Loading @@ -42,7 +43,8 @@ import javax.inject.Inject class ControlsEditingActivity @Inject constructor( private val controller: ControlsControllerImpl, broadcastDispatcher: BroadcastDispatcher, private val globalActionsComponent: GlobalActionsComponent private val globalActionsComponent: GlobalActionsComponent, private val customIconCache: CustomIconCache ) : LifecycleActivity() { companion object { Loading Loading @@ -170,7 +172,7 @@ class ControlsEditingActivity @Inject constructor( private fun setUpList() { val controls = controller.getFavoritesForStructure(component, structure) model = FavoritesModel(component, controls, favoritesModelCallback) model = FavoritesModel(customIconCache, component, controls, favoritesModelCallback) val elevation = resources.getFloat(R.dimen.control_card_elevation) val recyclerView = requireViewById<RecyclerView>(R.id.list) recyclerView.alpha = 0.0f Loading packages/SystemUI/src/com/android/systemui/controls/management/ControlsModel.kt +17 −2 Original line number Diff line number Diff line Loading @@ -114,11 +114,27 @@ data class ControlStatusWrapper( val controlStatus: ControlStatus ) : ElementWrapper(), ControlInterface by controlStatus private fun nullIconGetter(_a: ComponentName, _b: String): Icon? = null data class ControlInfoWrapper( override val component: ComponentName, val controlInfo: ControlInfo, override var favorite: Boolean ) : ElementWrapper(), ControlInterface { var customIconGetter: (ComponentName, String) -> Icon? = ::nullIconGetter private set // Separate constructor so the getter is not used in auto-generated methods constructor( component: ComponentName, controlInfo: ControlInfo, favorite: Boolean, customIconGetter: (ComponentName, String) -> Icon? ): this(component, controlInfo, favorite) { this.customIconGetter = customIconGetter } override val controlId: String get() = controlInfo.controlId override val title: CharSequence Loading @@ -128,8 +144,7 @@ data class ControlInfoWrapper( override val deviceType: Int get() = controlInfo.deviceType override val customIcon: Icon? // Will need to address to support for edit activity get() = null get() = customIconGetter(component, controlId) } data class DividerWrapper( Loading packages/SystemUI/src/com/android/systemui/controls/management/FavoritesModel.kt +3 −1 Original line number Diff line number Diff line Loading @@ -21,6 +21,7 @@ import android.util.Log import androidx.recyclerview.widget.ItemTouchHelper import androidx.recyclerview.widget.RecyclerView import com.android.systemui.controls.ControlInterface import com.android.systemui.controls.CustomIconCache import com.android.systemui.controls.controller.ControlInfo import java.util.Collections Loading @@ -35,6 +36,7 @@ import java.util.Collections * @property favoritesModelCallback callback to notify on first change and empty favorites */ class FavoritesModel( private val customIconCache: CustomIconCache, private val componentName: ComponentName, favorites: List<ControlInfo>, private val favoritesModelCallback: FavoritesModelCallback Loading Loading @@ -83,7 +85,7 @@ class FavoritesModel( } override val elements: List<ElementWrapper> = favorites.map { ControlInfoWrapper(componentName, it, true) ControlInfoWrapper(componentName, it, true, customIconCache::retrieve) } + DividerWrapper() /** Loading packages/SystemUI/src/com/android/systemui/controls/ui/ControlsUiControllerImpl.kt +4 −1 Original line number Diff line number Diff line Loading @@ -44,6 +44,7 @@ import android.widget.Space import android.widget.TextView import com.android.systemui.R import com.android.systemui.controls.ControlsServiceInfo import com.android.systemui.controls.CustomIconCache import com.android.systemui.controls.controller.ControlInfo import com.android.systemui.controls.controller.ControlsController import com.android.systemui.controls.controller.StructureInfo Loading Loading @@ -75,7 +76,8 @@ class ControlsUiControllerImpl @Inject constructor ( @Main val sharedPreferences: SharedPreferences, val controlActionCoordinator: ControlActionCoordinator, private val activityStarter: ActivityStarter, private val shadeController: ShadeController private val shadeController: ShadeController, private val iconCache: CustomIconCache ) : ControlsUiController { companion object { Loading Loading @@ -502,6 +504,7 @@ class ControlsUiControllerImpl @Inject constructor ( controls.forEach { c -> controlsById.get(ControlKey(componentName, c.getControlId()))?.let { Log.d(ControlsUiController.TAG, "onRefreshState() for id: " + c.getControlId()) iconCache.store(componentName, c.controlId, c.customIcon) val cws = ControlWithState(componentName, it.ci, c) val key = ControlKey(componentName, c.getControlId()) controlsById.put(key, cws) Loading Loading
packages/SystemUI/src/com/android/systemui/controls/CustomIconCache.kt 0 → 100644 +76 −0 Original line number Diff line number Diff line /* * Copyright (C) 2020 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.controls import android.content.ComponentName import android.graphics.drawable.Icon import androidx.annotation.GuardedBy import javax.inject.Inject import javax.inject.Singleton /** * Icon cache for custom icons sent with controls. * * It assumes that only one component can be current at the time, to minimize the number of icons * stored at a given time. */ @Singleton class CustomIconCache @Inject constructor() { private var currentComponent: ComponentName? = null @GuardedBy("cache") private val cache: MutableMap<String, Icon> = LinkedHashMap() /** * Store an icon in the cache. * * If the icons currently stored do not correspond to the component to be stored, the cache is * cleared first. */ fun store(component: ComponentName, controlId: String, icon: Icon?) { if (component != currentComponent) { clear() currentComponent = component } synchronized(cache) { if (icon != null) { cache.put(controlId, icon) } else { cache.remove(controlId) } } } /** * Retrieves a custom icon stored in the cache. * * It will return null if the component requested is not the one whose icons are stored, or if * there is no icon cached for that id. */ fun retrieve(component: ComponentName, controlId: String): Icon? { if (component != currentComponent) return null return synchronized(cache) { cache.get(controlId) } } private fun clear() { synchronized(cache) { cache.clear() } } } No newline at end of file
packages/SystemUI/src/com/android/systemui/controls/management/ControlsEditingActivity.kt +4 −2 Original line number Diff line number Diff line Loading @@ -29,6 +29,7 @@ import androidx.recyclerview.widget.ItemTouchHelper import androidx.recyclerview.widget.RecyclerView import com.android.systemui.R import com.android.systemui.broadcast.BroadcastDispatcher import com.android.systemui.controls.CustomIconCache import com.android.systemui.controls.controller.ControlsControllerImpl import com.android.systemui.controls.controller.StructureInfo import com.android.systemui.globalactions.GlobalActionsComponent Loading @@ -42,7 +43,8 @@ import javax.inject.Inject class ControlsEditingActivity @Inject constructor( private val controller: ControlsControllerImpl, broadcastDispatcher: BroadcastDispatcher, private val globalActionsComponent: GlobalActionsComponent private val globalActionsComponent: GlobalActionsComponent, private val customIconCache: CustomIconCache ) : LifecycleActivity() { companion object { Loading Loading @@ -170,7 +172,7 @@ class ControlsEditingActivity @Inject constructor( private fun setUpList() { val controls = controller.getFavoritesForStructure(component, structure) model = FavoritesModel(component, controls, favoritesModelCallback) model = FavoritesModel(customIconCache, component, controls, favoritesModelCallback) val elevation = resources.getFloat(R.dimen.control_card_elevation) val recyclerView = requireViewById<RecyclerView>(R.id.list) recyclerView.alpha = 0.0f Loading
packages/SystemUI/src/com/android/systemui/controls/management/ControlsModel.kt +17 −2 Original line number Diff line number Diff line Loading @@ -114,11 +114,27 @@ data class ControlStatusWrapper( val controlStatus: ControlStatus ) : ElementWrapper(), ControlInterface by controlStatus private fun nullIconGetter(_a: ComponentName, _b: String): Icon? = null data class ControlInfoWrapper( override val component: ComponentName, val controlInfo: ControlInfo, override var favorite: Boolean ) : ElementWrapper(), ControlInterface { var customIconGetter: (ComponentName, String) -> Icon? = ::nullIconGetter private set // Separate constructor so the getter is not used in auto-generated methods constructor( component: ComponentName, controlInfo: ControlInfo, favorite: Boolean, customIconGetter: (ComponentName, String) -> Icon? ): this(component, controlInfo, favorite) { this.customIconGetter = customIconGetter } override val controlId: String get() = controlInfo.controlId override val title: CharSequence Loading @@ -128,8 +144,7 @@ data class ControlInfoWrapper( override val deviceType: Int get() = controlInfo.deviceType override val customIcon: Icon? // Will need to address to support for edit activity get() = null get() = customIconGetter(component, controlId) } data class DividerWrapper( Loading
packages/SystemUI/src/com/android/systemui/controls/management/FavoritesModel.kt +3 −1 Original line number Diff line number Diff line Loading @@ -21,6 +21,7 @@ import android.util.Log import androidx.recyclerview.widget.ItemTouchHelper import androidx.recyclerview.widget.RecyclerView import com.android.systemui.controls.ControlInterface import com.android.systemui.controls.CustomIconCache import com.android.systemui.controls.controller.ControlInfo import java.util.Collections Loading @@ -35,6 +36,7 @@ import java.util.Collections * @property favoritesModelCallback callback to notify on first change and empty favorites */ class FavoritesModel( private val customIconCache: CustomIconCache, private val componentName: ComponentName, favorites: List<ControlInfo>, private val favoritesModelCallback: FavoritesModelCallback Loading Loading @@ -83,7 +85,7 @@ class FavoritesModel( } override val elements: List<ElementWrapper> = favorites.map { ControlInfoWrapper(componentName, it, true) ControlInfoWrapper(componentName, it, true, customIconCache::retrieve) } + DividerWrapper() /** Loading
packages/SystemUI/src/com/android/systemui/controls/ui/ControlsUiControllerImpl.kt +4 −1 Original line number Diff line number Diff line Loading @@ -44,6 +44,7 @@ import android.widget.Space import android.widget.TextView import com.android.systemui.R import com.android.systemui.controls.ControlsServiceInfo import com.android.systemui.controls.CustomIconCache import com.android.systemui.controls.controller.ControlInfo import com.android.systemui.controls.controller.ControlsController import com.android.systemui.controls.controller.StructureInfo Loading Loading @@ -75,7 +76,8 @@ class ControlsUiControllerImpl @Inject constructor ( @Main val sharedPreferences: SharedPreferences, val controlActionCoordinator: ControlActionCoordinator, private val activityStarter: ActivityStarter, private val shadeController: ShadeController private val shadeController: ShadeController, private val iconCache: CustomIconCache ) : ControlsUiController { companion object { Loading Loading @@ -502,6 +504,7 @@ class ControlsUiControllerImpl @Inject constructor ( controls.forEach { c -> controlsById.get(ControlKey(componentName, c.getControlId()))?.let { Log.d(ControlsUiController.TAG, "onRefreshState() for id: " + c.getControlId()) iconCache.store(componentName, c.controlId, c.customIcon) val cws = ControlWithState(componentName, it.ci, c) val key = ControlKey(componentName, c.getControlId()) controlsById.put(key, cws) Loading