diff options
19 files changed, 324 insertions, 190 deletions
diff --git a/packages/SystemUI/AndroidManifest.xml b/packages/SystemUI/AndroidManifest.xml index 149eaf47b97d..139a8c3f7411 100644 --- a/packages/SystemUI/AndroidManifest.xml +++ b/packages/SystemUI/AndroidManifest.xml @@ -644,7 +644,7 @@ <activity android:name=".controls.management.ControlsProviderSelectorActivity" android:label="Controls Providers" - android:theme="@style/Theme.SystemUI" + android:theme="@style/Theme.ControlsManagement" android:exported="true" android:showForAllUsers="true" android:excludeFromRecents="true" @@ -654,7 +654,7 @@ <activity android:name=".controls.management.ControlsFavoritingActivity" android:parentActivityName=".controls.management.ControlsProviderSelectorActivity" - android:theme="@style/Theme.SystemUI" + android:theme="@style/Theme.ControlsManagement" android:excludeFromRecents="true" android:showForAllUsers="true" android:configChanges="screenSize|smallestScreenSize|screenLayout|orientation|keyboard|keyboardHidden" diff --git a/packages/SystemUI/res-keyguard/layout/controls_management.xml b/packages/SystemUI/res-keyguard/layout/controls_management.xml new file mode 100644 index 000000000000..8330258e2456 --- /dev/null +++ b/packages/SystemUI/res-keyguard/layout/controls_management.xml @@ -0,0 +1,34 @@ +<?xml version="1.0" encoding="utf-8"?> + +<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" + android:orientation="vertical" + android:layout_width="match_parent" + android:layout_height="match_parent" + android:gravity="center_horizontal" + android:paddingTop="@dimen/controls_management_top_padding" + android:paddingStart="@dimen/controls_management_side_padding" + android:paddingEnd="@dimen/controls_management_side_padding" > + + <TextView + android:id="@+id/title" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:textAppearance="?android:attr/textAppearanceLarge" + android:textSize="@dimen/controls_title_size" + android:textAlignment="center" /> + + <TextView + android:id="@+id/subtitle" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_marginTop="@dimen/controls_management_titles_margin" + android:textAppearance="?android:attr/textAppearanceSmall" + android:textAlignment="center" /> + + <androidx.recyclerview.widget.RecyclerView + android:id="@+id/list" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:layout_marginTop="@dimen/controls_management_list_margin" /> + +</LinearLayout>
\ No newline at end of file diff --git a/packages/SystemUI/res/layout/app_item.xml b/packages/SystemUI/res/layout/app_item.xml deleted file mode 100644 index 83e788731442..000000000000 --- a/packages/SystemUI/res/layout/app_item.xml +++ /dev/null @@ -1,70 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- - Copyright (C) 2019 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. ---> -<LinearLayout - xmlns:android="http://schemas.android.com/apk/res/android" - android:layout_width="match_parent" - android:layout_height="wrap_content" - android:background="?android:attr/selectableItemBackground" - android:gravity="center_vertical" - android:minHeight="?android:attr/listPreferredItemHeightSmall" - android:paddingStart="?android:attr/listPreferredItemPaddingStart" - android:paddingEnd="?android:attr/listPreferredItemPaddingEnd"> - - <LinearLayout - android:id="@+id/icon_frame" - android:layout_width="wrap_content" - android:layout_height="wrap_content" - android:gravity="start|center_vertical" - android:minWidth="56dp" - android:orientation="horizontal" - android:paddingEnd="8dp" - android:paddingTop="4dp" - android:paddingBottom="4dp"> - <ImageView - android:id="@android:id/icon" - android:layout_width="@dimen/app_icon_size" - android:layout_height="@dimen/app_icon_size"/> - </LinearLayout> - - <LinearLayout - android:layout_width="0dp" - android:layout_height="wrap_content" - android:layout_weight="1" - android:orientation="vertical" - android:paddingTop="16dp" - android:paddingBottom="16dp"> - - <TextView - android:id="@android:id/title" - android:layout_width="wrap_content" - android:layout_height="wrap_content" - android:ellipsize="marquee" - android:fadingEdge="horizontal" - android:singleLine="true" - android:textAppearance="?android:attr/textAppearanceListItem"/> - - </LinearLayout> - - <LinearLayout - android:id="@android:id/widget_frame" - android:layout_width="wrap_content" - android:layout_height="match_parent" - android:gravity="center_vertical|end" - android:minWidth="64dp" - android:orientation="vertical"/> - -</LinearLayout>
\ No newline at end of file diff --git a/packages/SystemUI/res/layout/control_item.xml b/packages/SystemUI/res/layout/control_item.xml deleted file mode 100644 index 85701aaca41d..000000000000 --- a/packages/SystemUI/res/layout/control_item.xml +++ /dev/null @@ -1,72 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- - 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. ---> -<androidx.constraintlayout.widget.ConstraintLayout - xmlns:android="http://schemas.android.com/apk/res/android" - xmlns:app="http://schemas.android.com/apk/res-auto" - android:layout_width="match_parent" - android:layout_height="100dp" - android:padding="15dp" - android:clickable="true" - android:focusable="true"> - - <ImageView - android:id="@+id/icon" - android:layout_width="wrap_content" - android:layout_height="wrap_content" - app:layout_constraintStart_toStartOf="parent" - app:layout_constraintTop_toTopOf="parent" /> - - <TextView - android:id="@+id/status" - android:layout_width="wrap_content" - android:layout_height="wrap_content" - android:textSize="12sp" - android:textColor="?android:attr/textColorPrimary" - android:fontFamily="@*android:string/config_bodyFontFamily" - android:paddingLeft="3dp" - app:layout_constraintBottom_toBottomOf="@+id/icon" - app:layout_constraintStart_toEndOf="@+id/icon" /> - - <TextView - android:id="@+id/title" - android:layout_width="wrap_content" - android:layout_height="wrap_content" - android:textSize="18sp" - android:textColor="?android:attr/textColorPrimary" - android:fontFamily="@*android:string/config_headlineFontFamily" - app:layout_constraintBottom_toTopOf="@+id/subtitle" - app:layout_constraintStart_toStartOf="parent" - app:layout_constraintTop_toBottomOf="@+id/icon" /> - - <TextView - android:id="@+id/subtitle" - android:layout_width="wrap_content" - android:layout_height="wrap_content" - android:textSize="16sp" - android:textColor="?android:attr/textColorSecondary" - android:fontFamily="@*android:string/config_headlineFontFamily" - app:layout_constraintBottom_toBottomOf="parent" - app:layout_constraintStart_toStartOf="parent" /> - - <CheckBox - android:id="@+id/favorite" - android:layout_width="wrap_content" - android:layout_height="wrap_content" - app:layout_constraintEnd_toEndOf="parent" - app:layout_constraintTop_toTopOf="parent" - app:layout_constraintBottom_toBottomOf="parent"/> -</androidx.constraintlayout.widget.ConstraintLayout> diff --git a/packages/SystemUI/res/layout/controls_app_item.xml b/packages/SystemUI/res/layout/controls_app_item.xml new file mode 100644 index 000000000000..d54cd6db867a --- /dev/null +++ b/packages/SystemUI/res/layout/controls_app_item.xml @@ -0,0 +1,87 @@ +<?xml version="1.0" encoding="utf-8"?><!-- + Copyright (C) 2019 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. +--> +<FrameLayout + xmlns:android="http://schemas.android.com/apk/res/android" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:background="?android:attr/selectableItemBackground"> + + <LinearLayout + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:layout_gravity="start|top" + android:gravity="center_vertical" + android:minHeight="?android:attr/listPreferredItemHeightSmall" + android:paddingStart="?android:attr/listPreferredItemPaddingStart" + android:paddingEnd="?android:attr/listPreferredItemPaddingEnd" + android:layout_marginBottom="@dimen/controls_app_bottom_margin"> + + <FrameLayout + android:id="@+id/icon_frame" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:gravity="start|center_vertical" + android:minWidth="56dp" + android:orientation="horizontal" + android:paddingTop="@dimen/controls_app_icon_frame_top_padding" + android:paddingBottom="@dimen/controls_app_icon_frame_top_padding" + android:paddingEnd="@dimen/controls_app_icon_frame_side_padding" + android:paddingStart="@dimen/controls_app_icon_frame_side_padding" > + + <ImageView + android:id="@android:id/icon" + android:layout_width="@dimen/controls_app_icon_size" + android:layout_height="@dimen/controls_app_icon_size" /> + </FrameLayout> + + <LinearLayout + android:layout_width="0dp" + android:layout_height="wrap_content" + android:layout_weight="1" + android:orientation="vertical" + android:paddingTop="@dimen/controls_app_text_padding" + android:paddingBottom="@dimen/controls_app_text_padding"> + + <TextView + android:id="@android:id/title" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:ellipsize="end" + android:fadingEdge="horizontal" + android:singleLine="true" + android:textAppearance="?android:attr/textAppearanceMedium" + android:textColor="?android:attr/textColorPrimary"/> + + <TextView + android:id="@+id/favorites" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:ellipsize="end" + android:fadingEdge="horizontal" + android:singleLine="true" + android:textAppearance="?android:attr/textAppearanceSmall" /> + + </LinearLayout> + + </LinearLayout> + <View + android:layout_width="match_parent" + android:layout_height="@dimen/controls_app_divider_height" + android:layout_gravity="center_horizontal|bottom" + android:layout_marginStart="@dimen/controls_app_divider_side_margin" + android:layout_marginEnd="@dimen/controls_app_divider_side_margin" + android:background="?android:attr/listDivider" /> +</FrameLayout>
\ No newline at end of file diff --git a/packages/SystemUI/res/layout/controls_base_item.xml b/packages/SystemUI/res/layout/controls_base_item.xml index cd7ec5eb5c81..68c824698b2d 100644 --- a/packages/SystemUI/res/layout/controls_base_item.xml +++ b/packages/SystemUI/res/layout/controls_base_item.xml @@ -23,8 +23,8 @@ android:padding="@dimen/control_padding" android:clickable="true" android:focusable="true" - android:layout_marginLeft="2dp" - android:layout_marginRight="2dp" + android:layout_marginLeft="@dimen/control_base_item_margin" + android:layout_marginRight="@dimen/control_base_item_margin" android:background="@drawable/control_background"> <ImageView @@ -38,10 +38,8 @@ android:id="@+id/status" android:layout_width="wrap_content" android:layout_height="wrap_content" - android:textSize="@dimen/control_status_normal" - android:textColor="?android:attr/textColorPrimary" - android:fontFamily="@*android:string/config_bodyFontFamily" - android:paddingLeft="3dp" + android:textAppearance="@style/TextAppearance.Control.Status" + android:paddingStart="@dimen/control_status_padding" app:layout_constraintBottom_toBottomOf="@+id/icon" app:layout_constraintStart_toEndOf="@+id/icon" /> @@ -49,10 +47,8 @@ android:id="@+id/status_extra" android:layout_width="wrap_content" android:layout_height="wrap_content" - android:textSize="@dimen/control_status_normal" - android:textColor="?android:attr/textColorPrimary" - android:fontFamily="@*android:string/config_bodyFontFamily" - android:paddingLeft="3dp" + android:textAppearance="@style/TextAppearance.Control.Status" + android:paddingStart="@dimen/control_status_padding" app:layout_constraintBottom_toBottomOf="@+id/icon" app:layout_constraintStart_toEndOf="@+id/status" /> @@ -60,9 +56,7 @@ android:id="@+id/title" android:layout_width="wrap_content" android:layout_height="wrap_content" - android:textSize="14sp" - android:textColor="?android:attr/textColorPrimary" - android:textAppearance="?android:attr/textAppearanceSmall" + android:textAppearance="@style/TextAppearance.Control.Title" app:layout_constraintBottom_toTopOf="@+id/subtitle" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toBottomOf="@+id/icon" /> @@ -71,9 +65,15 @@ android:id="@+id/subtitle" android:layout_width="wrap_content" android:layout_height="wrap_content" - android:textSize="12sp" - android:textColor="?android:attr/textColorSecondary" - android:textAppearance="?android:attr/textAppearanceSmall" + android:textAppearance="@style/TextAppearance.Control.Subtitle" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintStart_toStartOf="parent" /> + + <CheckBox + android:id="@+id/favorite" + android:visibility="gone" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + app:layout_constraintEnd_toEndOf="parent" + app:layout_constraintBottom_toBottomOf="parent"/> </androidx.constraintlayout.widget.ConstraintLayout> diff --git a/packages/SystemUI/res/layout/controls_row.xml b/packages/SystemUI/res/layout/controls_row.xml index 13a6b36accd3..4cc461a28187 100644 --- a/packages/SystemUI/res/layout/controls_row.xml +++ b/packages/SystemUI/res/layout/controls_row.xml @@ -16,7 +16,7 @@ --> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" - orientation="horizontal" + android:orientation="horizontal" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginBottom="@dimen/control_spacing" /> diff --git a/packages/SystemUI/res/layout/controls_with_favorites.xml b/packages/SystemUI/res/layout/controls_with_favorites.xml index 6a3e95d34358..40b2476941c2 100644 --- a/packages/SystemUI/res/layout/controls_with_favorites.xml +++ b/packages/SystemUI/res/layout/controls_with_favorites.xml @@ -13,7 +13,7 @@ android:layout_height="wrap_content" android:singleLine="true" android:gravity="center" - android:textSize="25dp" + android:textSize="25sp" android:textColor="@*android:color/foreground_material_dark" android:fontFamily="@*android:string/config_headlineFontFamily" app:layout_constraintBottom_toBottomOf="parent" diff --git a/packages/SystemUI/res/values/dimens.xml b/packages/SystemUI/res/values/dimens.xml index 33cabc1fea52..9c997e88c0c2 100644 --- a/packages/SystemUI/res/values/dimens.xml +++ b/packages/SystemUI/res/values/dimens.xml @@ -1187,7 +1187,27 @@ <dimen name="control_corner_radius">15dp</dimen> <dimen name="control_height">100dp</dimen> <dimen name="control_padding">15dp</dimen> - <dimen name="control_status_normal">12dp</dimen> - <dimen name="control_status_expanded">18dp</dimen> - <dimen name="app_icon_size">32dp</dimen> + <dimen name="control_status_normal">12sp</dimen> + <dimen name="control_status_expanded">18sp</dimen> + <dimen name="control_base_item_margin">2dp</dimen> + <dimen name="control_status_padding">3dp</dimen> + + <!-- Home Controls management screens --> + <dimen name="controls_management_top_padding">48dp</dimen> + <dimen name="controls_management_side_padding">8dp</dimen> + <dimen name="controls_management_titles_margin">8dp</dimen> + <dimen name="controls_management_list_margin">16dp</dimen> + <dimen name="controls_title_size">26sp</dimen> + + <dimen name="controls_app_icon_size">32dp</dimen> + <dimen name="controls_app_icon_frame_side_padding">8dp</dimen> + <dimen name="controls_app_icon_frame_top_padding">4dp</dimen> + <dimen name="controls_app_bottom_margin">8dp</dimen> + <dimen name="controls_app_text_padding">8dp</dimen> + <dimen name="controls_app_divider_height">2dp</dimen> + <dimen name="controls_app_divider_side_margin">32dp</dimen> + + <dimen name="controls_card_margin">2dp</dimen> + + </resources> diff --git a/packages/SystemUI/res/values/strings.xml b/packages/SystemUI/res/values/strings.xml index fb8df5bfc7ce..82cd5f71e8a0 100644 --- a/packages/SystemUI/res/values/strings.xml +++ b/packages/SystemUI/res/values/strings.xml @@ -2547,6 +2547,24 @@ <!-- Title for Magnification Controls Window [CHAR LIMIT=NONE] --> <string name="magnification_controls_title">Magnification Window Controls</string> - <!-- Quick Controls strings [CHAR LIMIT=30] --> + <!-- Quick Controls strings --> + <!-- Quick Controls view header [CHAR LIMIT=30] --> <string name="quick_controls_title">Quick Controls</string> + + <!-- Controls management providers screen title [CHAR LIMIT=30]--> + <string name="controls_providers_title">Add Controls</string> + <!-- Controls management providers screen subtitle [CHAR LIMIT=NONE] --> + <string name="controls_providers_subtitle">Choose an app from which to add controls</string> + <!-- Number of favorites for controls management screen [CHAR LIMIT=NONE]--> + <plurals name="controls_number_of_favorites"> + <item quantity="one"><xliff:g id="number" example="1">%s</xliff:g> current favorite.</item> + <item quantity="other"><xliff:g id="number" example="3">%s</xliff:g> current favorites.</item> + </plurals> + + <!-- Controls management controls screen default title [CHAR LIMIT=30] --> + <string name="controls_favorite_default_title">Controls</string> + <!-- Controls management controls screen subtitle [CHAR LIMIT=NONE] --> + <string name="controls_favorite_subtitle">Choose controls for quick access</string> + + </resources> diff --git a/packages/SystemUI/res/values/styles.xml b/packages/SystemUI/res/values/styles.xml index 6cde90c6c996..bcffa8d0feea 100644 --- a/packages/SystemUI/res/values/styles.xml +++ b/packages/SystemUI/res/values/styles.xml @@ -624,4 +624,28 @@ <item name="android:background">?android:attr/selectableItemBackground</item> <item name="android:textColor">?android:attr/textColorPrimary</item> </style> + + <!-- Controls styles --> + <style name="Theme.ControlsManagement" parent="@android:style/Theme.DeviceDefault.NoActionBar"> + <item name="android:windowIsTranslucent">false</item> + </style> + + <style name="TextAppearance.Control"> + <item name="android:fontFamily">@*android:string/config_bodyFontFamily</item> + </style> + + <style name="TextAppearance.Control.Status"> + <item name="android:textSize">12sp</item> + <item name="android:textColor">?android:attr/textColorPrimary</item> + </style> + + <style name="TextAppearance.Control.Title"> + <item name="android:textSize">14sp</item> + <item name="android:textColor">?android:attr/textColorPrimary</item> + </style> + <style name="TextAppearance.Control.Subtitle"> + <item name="android:textSize">12sp</item> + <item name="android:textColor">?android:attr/textColorSecondary</item> + </style> + </resources> diff --git a/packages/SystemUI/src/com/android/systemui/controls/controller/ControlsController.kt b/packages/SystemUI/src/com/android/systemui/controls/controller/ControlsController.kt index b02de4500043..b3ba2b22f6df 100644 --- a/packages/SystemUI/src/com/android/systemui/controls/controller/ControlsController.kt +++ b/packages/SystemUI/src/com/android/systemui/controls/controller/ControlsController.kt @@ -29,6 +29,7 @@ interface ControlsController : UserAwareController { fun loadForComponent(componentName: ComponentName, callback: (List<ControlStatus>) -> Unit) fun subscribeToFavorites() fun changeFavoriteStatus(controlInfo: ControlInfo, state: Boolean) + fun countFavoritesForComponent(componentName: ComponentName): Int = 0 fun unsubscribe() fun action(controlInfo: ControlInfo, action: ControlAction) fun refreshStatus(componentName: ComponentName, control: Control) diff --git a/packages/SystemUI/src/com/android/systemui/controls/controller/ControlsControllerImpl.kt b/packages/SystemUI/src/com/android/systemui/controls/controller/ControlsControllerImpl.kt index 6ff1cf8474d3..a6f1d84877c5 100644 --- a/packages/SystemUI/src/com/android/systemui/controls/controller/ControlsControllerImpl.kt +++ b/packages/SystemUI/src/com/android/systemui/controls/controller/ControlsControllerImpl.kt @@ -328,6 +328,12 @@ class ControlsControllerImpl @Inject constructor ( } } + override fun countFavoritesForComponent(componentName: ComponentName): Int { + return synchronized(currentFavorites) { + currentFavorites.get(componentName)?.size ?: 0 + } + } + override fun dump(fd: FileDescriptor, pw: PrintWriter, args: Array<out String>) { pw.println("ControlsController state:") pw.println(" Available: $available") diff --git a/packages/SystemUI/src/com/android/systemui/controls/management/AppAdapter.kt b/packages/SystemUI/src/com/android/systemui/controls/management/AppAdapter.kt index 22c69086cf8c..b12243964fc1 100644 --- a/packages/SystemUI/src/com/android/systemui/controls/management/AppAdapter.kt +++ b/packages/SystemUI/src/com/android/systemui/controls/management/AppAdapter.kt @@ -17,6 +17,7 @@ package com.android.systemui.controls.management import android.content.ComponentName +import android.content.res.Resources import android.view.LayoutInflater import android.view.View import android.view.ViewGroup @@ -25,6 +26,7 @@ import android.widget.TextView import androidx.lifecycle.Lifecycle import androidx.lifecycle.LifecycleOwner import androidx.recyclerview.widget.RecyclerView +import com.android.settingslib.applications.DefaultAppInfo import com.android.settingslib.widget.CandidateInfo import com.android.systemui.R import java.util.concurrent.Executor @@ -46,7 +48,8 @@ class AppAdapter( lifecycle: Lifecycle, controlsListingController: ControlsListingController, private val layoutInflater: LayoutInflater, - private val onAppSelected: (ComponentName?) -> Unit = {} + private val onAppSelected: (ComponentName?) -> Unit = {}, + private val favoritesRenderer: FavoritesRenderer ) : RecyclerView.Adapter<AppAdapter.Holder>() { private var listOfServices = emptyList<CandidateInfo>() @@ -54,7 +57,9 @@ class AppAdapter( private val callback = object : ControlsListingController.ControlsListingCallback { override fun onServicesUpdated(list: List<CandidateInfo>) { uiExecutor.execute { - listOfServices = list + listOfServices = list.sortedBy { + it.loadLabel().toString() + } notifyDataSetChanged() } } @@ -65,7 +70,8 @@ class AppAdapter( } override fun onCreateViewHolder(parent: ViewGroup, i: Int): Holder { - return Holder(layoutInflater.inflate(R.layout.app_item, parent, false)) + return Holder(layoutInflater.inflate(R.layout.controls_app_item, parent, false), + favoritesRenderer) } override fun getItemCount() = listOfServices.size @@ -80,9 +86,10 @@ class AppAdapter( /** * Holder for binding views in the [RecyclerView]- */ - class Holder(view: View) : RecyclerView.ViewHolder(view) { + class Holder(view: View, val favRenderer: FavoritesRenderer) : RecyclerView.ViewHolder(view) { private val icon: ImageView = itemView.requireViewById(com.android.internal.R.id.icon) private val title: TextView = itemView.requireViewById(com.android.internal.R.id.title) + private val favorites: TextView = itemView.requireViewById(R.id.favorites) /** * Bind data to the view @@ -91,6 +98,19 @@ class AppAdapter( fun bindData(data: CandidateInfo) { icon.setImageDrawable(data.loadIcon()) title.text = data.loadLabel() + favorites.text = favRenderer.renderFavoritesForComponent( + (data as DefaultAppInfo).componentName) } } +} + +class FavoritesRenderer( + private val resources: Resources, + private val favoriteFunction: (ComponentName) -> Int +) { + + fun renderFavoritesForComponent(component: ComponentName): String { + val qty = favoriteFunction(component) + return resources.getQuantityString(R.plurals.controls_number_of_favorites, qty, qty) + } }
\ No newline at end of file diff --git a/packages/SystemUI/src/com/android/systemui/controls/management/ControlAdapter.kt b/packages/SystemUI/src/com/android/systemui/controls/management/ControlAdapter.kt index e6d3c26ea7b8..65dcc2b193d5 100644 --- a/packages/SystemUI/src/com/android/systemui/controls/management/ControlAdapter.kt +++ b/packages/SystemUI/src/com/android/systemui/controls/management/ControlAdapter.kt @@ -16,15 +16,20 @@ package com.android.systemui.controls.management +import android.graphics.Rect +import android.graphics.drawable.Icon +import android.service.controls.DeviceTypes import android.view.LayoutInflater import android.view.View import android.view.ViewGroup import android.widget.CheckBox +import android.widget.ImageView import android.widget.TextView import androidx.recyclerview.widget.RecyclerView import com.android.systemui.R import com.android.systemui.controls.ControlStatus import com.android.systemui.controls.controller.ControlInfo +import com.android.systemui.controls.ui.RenderInfo /** * Adapter for binding [Control] information to views. @@ -43,7 +48,12 @@ class ControlAdapter( var listOfControls = emptyList<ControlStatus>() override fun onCreateViewHolder(parent: ViewGroup, i: Int): Holder { - return Holder(layoutInflater.inflate(R.layout.control_item, parent, false)) + return Holder(layoutInflater.inflate(R.layout.controls_base_item, parent, false).apply { + layoutParams.apply { + width = ViewGroup.LayoutParams.MATCH_PARENT + } + elevation = 15f + }) } override fun getItemCount() = listOfControls.size @@ -56,9 +66,13 @@ class ControlAdapter( * Holder for binding views in the [RecyclerView]- */ class Holder(view: View) : RecyclerView.ViewHolder(view) { + private val icon: ImageView = itemView.requireViewById(R.id.icon) private val title: TextView = itemView.requireViewById(R.id.title) private val subtitle: TextView = itemView.requireViewById(R.id.subtitle) - private val favorite: CheckBox = itemView.requireViewById(R.id.favorite) + private val removed: TextView = itemView.requireViewById(R.id.status) + private val favorite: CheckBox = itemView.requireViewById<CheckBox>(R.id.favorite).apply { + visibility = View.VISIBLE + } /** * Bind data to the view @@ -68,9 +82,11 @@ class ControlAdapter( * pre-populated with the [Control] information and the new favorite status. */ fun bindData(data: ControlStatus, callback: (ControlInfo.Builder, Boolean) -> Unit) { + val renderInfo = getRenderInfo(data.control.deviceType, data.favorite) title.text = data.control.title subtitle.text = data.control.subtitle favorite.isChecked = data.favorite + removed.text = if (data.removed) "Removed" else "" favorite.setOnClickListener { val infoBuilder = ControlInfo.Builder().apply { controlId = data.control.controlId @@ -79,6 +95,25 @@ class ControlAdapter( } callback(infoBuilder, favorite.isChecked) } + itemView.setOnClickListener { + favorite.performClick() + } + applyRenderInfo(renderInfo) + } + + private fun getRenderInfo( + @DeviceTypes.DeviceType deviceType: Int, + favorite: Boolean + ): RenderInfo { + return RenderInfo.lookup(deviceType, favorite) + } + + private fun applyRenderInfo(ri: RenderInfo) { + val context = itemView.context + val fg = context.getResources().getColorStateList(ri.foreground, context.getTheme()) + + icon.setImageIcon(Icon.createWithResource(context, ri.iconResourceId)) + icon.setImageTintList(fg) } } @@ -86,4 +121,23 @@ class ControlAdapter( listOfControls = list notifyDataSetChanged() } +} + +class MarginItemDecorator( + private val topMargin: Int, + private val sideMargins: Int +) : RecyclerView.ItemDecoration() { + + override fun getItemOffsets( + outRect: Rect, + view: View, + parent: RecyclerView, + state: RecyclerView.State + ) { + outRect.apply { + top = topMargin + left = sideMargins + right = sideMargins + } + } }
\ No newline at end of file diff --git a/packages/SystemUI/src/com/android/systemui/controls/management/ControlsFavoritingActivity.kt b/packages/SystemUI/src/com/android/systemui/controls/management/ControlsFavoritingActivity.kt index 7ee4fd5b059e..be5258344492 100644 --- a/packages/SystemUI/src/com/android/systemui/controls/management/ControlsFavoritingActivity.kt +++ b/packages/SystemUI/src/com/android/systemui/controls/management/ControlsFavoritingActivity.kt @@ -20,8 +20,10 @@ import android.app.Activity import android.content.ComponentName import android.os.Bundle import android.view.LayoutInflater -import androidx.recyclerview.widget.LinearLayoutManager +import android.widget.TextView +import androidx.recyclerview.widget.GridLayoutManager import androidx.recyclerview.widget.RecyclerView +import com.android.systemui.R import com.android.systemui.broadcast.BroadcastDispatcher import com.android.systemui.controls.controller.ControlInfo import com.android.systemui.controls.controller.ControlsControllerImpl @@ -44,6 +46,7 @@ class ControlsFavoritingActivity @Inject constructor( private lateinit var recyclerView: RecyclerView private lateinit var adapter: ControlAdapter + private var component: ComponentName? = null private val currentUserTracker = object : CurrentUserTracker(broadcastDispatcher) { private val startingUser = controller.currentUserId @@ -56,10 +59,9 @@ class ControlsFavoritingActivity @Inject constructor( } } - private var component: ComponentName? = null - override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) + setContentView(R.layout.controls_management) val app = intent.getCharSequenceExtra(EXTRA_APP) component = intent.getParcelableExtra<ComponentName>(EXTRA_COMPONENT) @@ -72,17 +74,17 @@ class ControlsFavoritingActivity @Inject constructor( } } ?: { _, _ -> Unit } - recyclerView = RecyclerView(applicationContext) + recyclerView = requireViewById(R.id.list) adapter = ControlAdapter(LayoutInflater.from(applicationContext), callback) recyclerView.adapter = adapter - recyclerView.layoutManager = LinearLayoutManager(applicationContext) + recyclerView.layoutManager = GridLayoutManager(applicationContext, 2) + val margin = resources.getDimensionPixelSize(R.dimen.controls_card_margin) + recyclerView.addItemDecoration(MarginItemDecorator(margin, margin)) - if (app != null) { - setTitle("Controls for $app") - } else { - setTitle("Controls") - } - setContentView(recyclerView) + requireViewById<TextView>(R.id.title).text = app?.let { it } + ?: resources.getText(R.string.controls_favorite_default_title) + requireViewById<TextView>(R.id.subtitle).text = + resources.getText(R.string.controls_favorite_subtitle) currentUserTracker.startTracking() } diff --git a/packages/SystemUI/src/com/android/systemui/controls/management/ControlsProviderSelectorActivity.kt b/packages/SystemUI/src/com/android/systemui/controls/management/ControlsProviderSelectorActivity.kt index 5ff949c98806..645e929d6a10 100644 --- a/packages/SystemUI/src/com/android/systemui/controls/management/ControlsProviderSelectorActivity.kt +++ b/packages/SystemUI/src/com/android/systemui/controls/management/ControlsProviderSelectorActivity.kt @@ -20,9 +20,12 @@ import android.content.ComponentName import android.content.Intent import android.os.Bundle import android.view.LayoutInflater +import android.widget.TextView import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.RecyclerView +import com.android.systemui.R import com.android.systemui.broadcast.BroadcastDispatcher +import com.android.systemui.controls.controller.ControlsController import com.android.systemui.dagger.qualifiers.Background import com.android.systemui.dagger.qualifiers.Main import com.android.systemui.settings.CurrentUserTracker @@ -37,6 +40,7 @@ class ControlsProviderSelectorActivity @Inject constructor( @Main private val executor: Executor, @Background private val backExecutor: Executor, private val listingController: ControlsListingController, + private val controlsController: ControlsController, broadcastDispatcher: BroadcastDispatcher ) : LifecycleActivity() { @@ -58,13 +62,19 @@ class ControlsProviderSelectorActivity @Inject constructor( override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) + setContentView(R.layout.controls_management) - recyclerView = RecyclerView(applicationContext) + recyclerView = requireViewById(R.id.list) recyclerView.adapter = AppAdapter(executor, lifecycle, listingController, - LayoutInflater.from(this), ::launchFavoritingActivity) + LayoutInflater.from(this), ::launchFavoritingActivity, + FavoritesRenderer(resources, controlsController::countFavoritesForComponent)) recyclerView.layoutManager = LinearLayoutManager(applicationContext) - setContentView(recyclerView) + requireViewById<TextView>(R.id.title).text = + resources.getText(R.string.controls_providers_title) + requireViewById<TextView>(R.id.subtitle).text = + resources.getText(R.string.controls_providers_subtitle) + currentUserTracker.startTracking() } diff --git a/packages/SystemUI/src/com/android/systemui/controls/ui/ControlViewHolder.kt b/packages/SystemUI/src/com/android/systemui/controls/ui/ControlViewHolder.kt index 5519e32d6c10..fad2d94d6cf3 100644 --- a/packages/SystemUI/src/com/android/systemui/controls/ui/ControlViewHolder.kt +++ b/packages/SystemUI/src/com/android/systemui/controls/ui/ControlViewHolder.kt @@ -36,8 +36,8 @@ import android.widget.TextView import com.android.systemui.controls.controller.ControlsController import com.android.systemui.R -public const val MIN_LEVEL = 0 -public const val MAX_LEVEL = 10000 +const val MIN_LEVEL = 0 +const val MAX_LEVEL = 10000 class ControlViewHolder( val layout: ViewGroup, diff --git a/packages/SystemUI/src/com/android/systemui/controls/ui/RenderInfo.kt b/packages/SystemUI/src/com/android/systemui/controls/ui/RenderInfo.kt index 24c8020529ff..093c99f57a9a 100644 --- a/packages/SystemUI/src/com/android/systemui/controls/ui/RenderInfo.kt +++ b/packages/SystemUI/src/com/android/systemui/controls/ui/RenderInfo.kt @@ -50,7 +50,7 @@ data class RenderInfo(val iconResourceId: Int, val foreground: Int, val backgrou private const val BUCKET_SIZE = 1000 private const val THERMOSTAT_RANGE = DeviceTypes.TYPE_THERMOSTAT * BUCKET_SIZE -public val deviceColorMap = mapOf<Int, Pair<Int, Int>>( +private val deviceColorMap = mapOf<Int, Pair<Int, Int>>( (THERMOSTAT_RANGE + TemperatureControlTemplate.MODE_HEAT) to Pair(R.color.thermo_heat_foreground, R.color.thermo_heat_background), (THERMOSTAT_RANGE + TemperatureControlTemplate.MODE_COOL) to @@ -60,7 +60,7 @@ public val deviceColorMap = mapOf<Int, Pair<Int, Int>>( Pair(R.color.control_foreground, R.color.control_background) } -public val deviceIconMap = mapOf<Int, IconState>( +private val deviceIconMap = mapOf<Int, IconState>( THERMOSTAT_RANGE to IconState( R.drawable.ic_device_thermostat_gm2_24px, R.drawable.ic_device_thermostat_gm2_24px |