Merge "Remove unused and unnecessary loggings (1/3)" into main
diff --git a/res/layout-land/activity_custom_theme.xml b/res/layout-land/activity_custom_theme.xml
deleted file mode 100644
index 59296df..0000000
--- a/res/layout-land/activity_custom_theme.xml
+++ /dev/null
@@ -1,63 +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.
--->
-<FrameLayout
- xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:app="http://schemas.android.com/apk/res-auto"
- xmlns:tools="http://schemas.android.com/tools"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- tools:context="com.android.customization.picker.theme.CustomThemeActivity">
-
- <FrameLayout
- android:id="@+id/fragment_container"
- android:layout_width="match_parent"
- android:layout_height="match_parent"/>
- <LinearLayout
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:layout_gravity="bottom"
- android:orientation="horizontal">
- <Space
- android:layout_width="0dp"
- android:layout_height="0dp"
- android:layout_weight="1"
- android:layout_gravity="bottom"/>
-
- <FrameLayout
- android:id="@+id/custom_theme_nav"
- android:layout_width="0dp"
- android:layout_height="@dimen/custom_theme_nav_height"
- android:layout_weight="1"
- android:paddingHorizontal="12dp">
- <Button
- android:id="@+id/previous_button"
- style="@style/ActionSecondaryButton"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_gravity="start|center_vertical"
- android:text="@string/custom_theme_previous"/>
- <Button
- android:id="@+id/next_button"
- style="@style/ActionPrimaryButton"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_gravity="end|center_vertical"
- android:text="@string/custom_theme_next"/>
- </FrameLayout>
- </LinearLayout>
-
-</FrameLayout>
diff --git a/res/layout-land/fragment_custom_theme_component.xml b/res/layout-land/fragment_custom_theme_component.xml
deleted file mode 100644
index 2679bdf..0000000
--- a/res/layout-land/fragment_custom_theme_component.xml
+++ /dev/null
@@ -1,75 +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="match_parent"
- android:orientation="vertical"
- android:background="?android:colorPrimary">
- <include layout="@layout/section_header"/>
-
- <LinearLayout
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:orientation="horizontal">
-
- <FrameLayout
- android:id="@+id/component_preview_container"
- android:layout_width="0dp"
- android:layout_height="match_parent"
- android:layout_weight="1"
- android:background="?android:colorPrimary">
- <include
- android:id="@+id/component_preview_content"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:layout_marginHorizontal="@dimen/preview_page_horizontal_margin"
- android:layout_marginTop="@dimen/preview_page_top_margin"
- android:layout_marginBottom="@dimen/component_preview_page_bottom_margin"
- layout="@layout/theme_component_preview"/>
- </FrameLayout>
- <View
- android:layout_width="1dp"
- android:layout_height="match_parent"
- android:background="?android:colorForeground"/>
- <LinearLayout
- android:id="@+id/options_section"
- android:layout_width="0dp"
- android:layout_height="match_parent"
- android:layout_weight="1"
- android:paddingTop="10dp"
- android:paddingBottom="@dimen/custom_theme_nav_height"
- android:orientation="vertical">
-
- <TextView
- android:id="@+id/component_options_title"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:layout_gravity="center"
- android:layout_margin="10dp"
- android:textAlignment="center"
- android:textAppearance="@style/TitleTextAppearance"/>
-
- <androidx.recyclerview.widget.RecyclerView
- android:id="@+id/options_container"
- android:layout_width="match_parent"
- android:layout_height="0dp"
- android:layout_weight="1"/>
-
- </LinearLayout>
- </LinearLayout>
-</LinearLayout>
diff --git a/res/layout-land/fragment_custom_theme_name.xml b/res/layout-land/fragment_custom_theme_name.xml
deleted file mode 100644
index a60b9c2..0000000
--- a/res/layout-land/fragment_custom_theme_name.xml
+++ /dev/null
@@ -1,76 +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="match_parent"
- android:orientation="vertical"
- android:background="?android:colorPrimary">
- <include layout="@layout/section_header"/>
-
- <LinearLayout
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:orientation="horizontal">
- <FrameLayout
- android:id="@+id/component_preview_container"
- android:layout_width="0dp"
- android:layout_height="match_parent"
- android:layout_weight="1"
- android:paddingTop="@dimen/preview_content_padding_top"
- android:paddingBottom="@dimen/preview_content_padding_bottom"
- android:clipToPadding="false"
- android:background="?android:colorSecondary">
- <include layout="@layout/theme_preview_card"/>
- </FrameLayout>
- <LinearLayout
- android:id="@+id/options_section"
- android:layout_width="0dp"
- android:layout_height="match_parent"
- android:layout_weight="1"
- android:paddingTop="10dp"
- android:paddingBottom="@dimen/custom_theme_nav_height"
- android:paddingVertical="10dp"
- android:clipToPadding="false"
- android:orientation="vertical">
-
- <TextView
- android:id="@+id/component_options_title"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:layout_gravity="center"
- android:layout_margin="10dp"
- android:textAlignment="center"
- android:textAppearance="@style/TitleTextAppearance"/>
-
- <FrameLayout
- android:layout_width="match_parent"
- android:layout_height="@dimen/options_container_height"
- android:layout_gravity="center">
-
- <EditText
- style="@style/CustomThemeNameEditText"
- android:id="@+id/custom_theme_name"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_gravity="center"
- android:minWidth="300dp"/>
- </FrameLayout>
-
- </LinearLayout>
- </LinearLayout>
-</LinearLayout>
diff --git a/res/layout-land/fragment_theme_picker.xml b/res/layout-land/fragment_theme_picker.xml
deleted file mode 100644
index d358037..0000000
--- a/res/layout-land/fragment_theme_picker.xml
+++ /dev/null
@@ -1,82 +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="match_parent"
- android:orientation="vertical"
- android:background="?android:colorPrimary">
- <include layout="@layout/section_header"/>
-
- <FrameLayout
- android:layout_width="match_parent"
- android:layout_height="match_parent">
- <LinearLayout
- android:id="@+id/content_section"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:orientation="horizontal">
-
- <FrameLayout
- android:layout_width="0dp"
- android:layout_height="match_parent"
- android:layout_weight="1">
- <FrameLayout
- android:id="@+id/preview_card_container"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:paddingTop="@dimen/preview_content_padding_top"
- android:paddingBottom="@dimen/preview_content_padding_bottom"
- android:clipToPadding="false"
- android:background="?android:colorSecondary">
- <include layout="@layout/theme_preview_card"/>
- </FrameLayout>
- </FrameLayout>
-
- <androidx.recyclerview.widget.RecyclerView
- android:id="@+id/options_container"
- android:layout_width="0dp"
- android:layout_height="match_parent"
- android:layout_weight="1"
- android:paddingVertical="10dp" />
- </LinearLayout>
-
- <androidx.core.widget.ContentLoadingProgressBar
- android:id="@+id/loading_indicator"
- style="@android:style/Widget.DeviceDefault.ProgressBar"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_marginTop="200dp"
- android:layout_gravity="center_horizontal|top"
- android:indeterminate="true"/>
-
- <FrameLayout
- android:id="@+id/error_section"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:visibility="gone">
- <TextView
- android:id="@+id/error_message"
- style="@style/TitleTextAppearance"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:layout_gravity="center"
- android:gravity="center"
- android:text="@string/something_went_wrong"/>
- </FrameLayout>
- </FrameLayout>
-</LinearLayout>
diff --git a/res/layout/activity_custom_theme.xml b/res/layout/activity_custom_theme.xml
deleted file mode 100644
index 24d58b7..0000000
--- a/res/layout/activity_custom_theme.xml
+++ /dev/null
@@ -1,53 +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"
- xmlns:app="http://schemas.android.com/apk/res-auto"
- xmlns:tools="http://schemas.android.com/tools"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:orientation="vertical"
- tools:context="com.android.customization.picker.theme.CustomThemeActivity">
-
- <FrameLayout
- android:id="@+id/fragment_container"
- android:layout_width="match_parent"
- android:layout_height="0dp"
- android:layout_weight="1"/>
-
- <FrameLayout
- android:id="@+id/custom_theme_nav"
- android:layout_width="match_parent"
- android:layout_height="@dimen/custom_theme_nav_height"
- android:paddingHorizontal="12dp"
- android:background="?android:colorPrimary">
- <Button
- android:id="@+id/previous_button"
- style="@style/ActionSecondaryButton"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_gravity="start|center_vertical"
- android:text="@string/custom_theme_previous"/>
- <Button
- android:id="@+id/next_button"
- style="@style/ActionPrimaryButton"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_gravity="end|center_vertical"
- android:text="@string/custom_theme_next"/>
- </FrameLayout>
-</LinearLayout>
diff --git a/res/layout/custom_theme_option.xml b/res/layout/custom_theme_option.xml
deleted file mode 100644
index aff43a9..0000000
--- a/res/layout/custom_theme_option.xml
+++ /dev/null
@@ -1,51 +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:paddingHorizontal="@dimen/option_padding_horizontal"
- android:paddingBottom="@dimen/option_bottom_margin"
- android:clipChildren="false"
- android:clipToPadding="false"
- android:orientation="vertical">
-
- <TextView
- android:id="@+id/option_label"
- android:layout_width="@dimen/option_tile_width"
- android:layout_height="wrap_content"
- android:layout_gravity="center_horizontal"
- android:layout_marginBottom="@dimen/theme_option_label_margin"
- android:ellipsize="end"
- android:gravity="center_horizontal"
- android:maxLines="1"
- android:textAppearance="@style/OptionTitleTextAppearance"/>
- <FrameLayout
- android:id="@+id/option_tile"
- android:layout_width="@dimen/option_tile_width"
- android:layout_height="@dimen/option_tile_width"
- android:layout_gravity="center_horizontal"
- android:paddingHorizontal="@dimen/option_tile_padding_horizontal"
- android:paddingVertical="@dimen/option_tile_padding_vertical"
- android:background="@drawable/option_border_custom">
- <ImageView
- android:layout_width="@dimen/option_icon_size"
- android:layout_height="@dimen/option_icon_size"
- android:layout_gravity="center"
- android:src="@drawable/ic_add_24px"
- android:tint="?android:attr/colorAccent" />
- </FrameLayout>
-</LinearLayout>
diff --git a/res/layout/fragment_custom_theme_component.xml b/res/layout/fragment_custom_theme_component.xml
deleted file mode 100644
index 7bae84b..0000000
--- a/res/layout/fragment_custom_theme_component.xml
+++ /dev/null
@@ -1,93 +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"
- xmlns:app="http://schemas.android.com/apk/res-auto"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:orientation="vertical"
- android:background="?android:colorPrimary">
- <include layout="@layout/section_header"/>
-
- <androidx.constraintlayout.widget.ConstraintLayout
- android:layout_width="match_parent"
- android:layout_height="match_parent">
-
- <FrameLayout
- android:id="@+id/component_preview_container"
- android:layout_width="match_parent"
- android:layout_height="0dp"
- android:background="?android:colorPrimary"
- app:layout_constrainedHeight="true"
- app:layout_constraintBottom_toTopOf="@+id/divider"
- app:layout_constraintEnd_toEndOf="parent"
- app:layout_constraintHeight_max="@dimen/preview_pager_max_height"
- app:layout_constraintStart_toStartOf="parent"
- app:layout_constraintTop_toTopOf="parent"
- app:layout_constraintVertical_bias="0.0"
- app:layout_constraintHeight_percent="@dimen/preview_pager_maximum_height_ratio">
-
- <include
- android:id="@+id/component_preview_content"
- layout="@layout/theme_component_preview"
- android:layout_width="match_parent"
- android:layout_height="match_parent"/>
- </FrameLayout>
-
- <View
- android:id="@+id/divider"
- android:layout_width="match_parent"
- android:layout_height="1dp"
- android:background="?android:colorForeground"
- app:layout_constraintEnd_toEndOf="parent"
- app:layout_constraintStart_toStartOf="parent"
- app:layout_constraintTop_toBottomOf="@+id/component_preview_container"
- app:layout_constraintBottom_toTopOf="@+id/component_scroll_view"/>
-
- <ScrollView
- android:id="@+id/component_scroll_view"
- android:layout_width="match_parent"
- android:layout_height="0dp"
- app:layout_constraintEnd_toEndOf="parent"
- app:layout_constraintStart_toStartOf="parent"
- app:layout_constraintTop_toBottomOf="@+id/divider"
- app:layout_constraintBottom_toBottomOf="parent">
-
- <LinearLayout
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:orientation="vertical">
-
- <TextView
- android:id="@+id/component_options_title"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:layout_marginVertical="18dp"
- android:layout_marginHorizontal="16dp"
- android:textAlignment="center"
- android:textAppearance="@style/TitleTextAppearance"
- android:textSize="@dimen/component_options_title_size" />
-
- <androidx.recyclerview.widget.RecyclerView
- android:id="@+id/options_container"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:layout_gravity="center_horizontal"/>
- </LinearLayout>
- </ScrollView>
- </androidx.constraintlayout.widget.ConstraintLayout>
-</LinearLayout>
diff --git a/res/layout/fragment_custom_theme_name.xml b/res/layout/fragment_custom_theme_name.xml
deleted file mode 100644
index 98edd29..0000000
--- a/res/layout/fragment_custom_theme_name.xml
+++ /dev/null
@@ -1,86 +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"
- xmlns:app="http://schemas.android.com/apk/res-auto"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:orientation="vertical">
- <include layout="@layout/section_header"/>
-
- <androidx.constraintlayout.widget.ConstraintLayout
- android:layout_width="match_parent"
- android:layout_height="match_parent">
-
- <FrameLayout
- android:id="@+id/component_preview_container"
- android:layout_width="match_parent"
- android:layout_height="0dp"
- android:paddingTop="@dimen/preview_content_padding_top"
- android:paddingBottom="@dimen/preview_content_padding_bottom"
- android:clipToPadding="false"
- app:layout_constrainedHeight="true"
- app:layout_constraintBottom_toTopOf="@+id/component_scroll_view"
- app:layout_constraintEnd_toEndOf="parent"
- app:layout_constraintHeight_max="@dimen/preview_pager_max_height"
- app:layout_constraintStart_toStartOf="parent"
- app:layout_constraintTop_toTopOf="parent"
- app:layout_constraintVertical_bias="0.0"
- app:layout_constraintHeight_percent="@dimen/preview_pager_maximum_height_ratio">
-
- <include layout="@layout/theme_preview_card"/>
- </FrameLayout>
-
- <ScrollView
- android:id="@+id/component_scroll_view"
- android:layout_width="match_parent"
- android:layout_height="0dp"
- android:background="?android:colorPrimary"
- app:layout_constraintEnd_toEndOf="parent"
- app:layout_constraintStart_toStartOf="parent"
- app:layout_constraintTop_toBottomOf="@+id/component_preview_container"
- app:layout_constraintBottom_toBottomOf="parent">
-
- <LinearLayout
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:orientation="vertical">
-
- <TextView
- android:id="@+id/component_options_title"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:layout_marginVertical="18dp"
- android:layout_marginHorizontal="16dp"
- android:textAlignment="center"
- android:textAppearance="@style/TitleTextAppearance"
- android:textSize="@dimen/component_options_title_size"/>
-
- <EditText
- android:id="@+id/custom_theme_name"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_marginVertical="16dp"
- android:layout_marginHorizontal="16dp"
- android:layout_gravity="center|top"
- android:importantForAutofill="no"
- android:minWidth="300dp"
- style="@style/CustomThemeNameEditText"/>
- </LinearLayout>
- </ScrollView>
- </androidx.constraintlayout.widget.ConstraintLayout>
-</LinearLayout>
diff --git a/res/layout/fragment_theme_full_preview.xml b/res/layout/fragment_theme_full_preview.xml
deleted file mode 100644
index 762af07..0000000
--- a/res/layout/fragment_theme_full_preview.xml
+++ /dev/null
@@ -1,35 +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.
--->
-<LinearLayout
- xmlns:android="http://schemas.android.com/apk/res/android"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:orientation="vertical">
-
- <include layout="@layout/section_header"/>
-
- <FrameLayout
- android:layout_width="match_parent"
- android:layout_height="0dp"
- android:layout_weight="1"
- android:paddingTop="@dimen/full_preview_page_default_padding_top"
- android:paddingBottom="@dimen/full_preview_page_default_padding_bottom"
- android:clipToPadding="false">
-
- <include layout="@layout/theme_preview_card"/>
- </FrameLayout>
-</LinearLayout>
\ No newline at end of file
diff --git a/res/layout/fragment_theme_picker.xml b/res/layout/fragment_theme_picker.xml
deleted file mode 100644
index 0ecfdd0..0000000
--- a/res/layout/fragment_theme_picker.xml
+++ /dev/null
@@ -1,87 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- Copyright (C) 2018 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"
- xmlns:app="http://schemas.android.com/apk/res-auto"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:orientation="vertical">
- <include layout="@layout/section_header"/>
-
- <FrameLayout
- android:layout_width="match_parent"
- android:layout_height="match_parent">
-
- <androidx.constraintlayout.widget.ConstraintLayout
- android:id="@+id/content_section"
- android:layout_width="match_parent"
- android:layout_height="match_parent">
- <FrameLayout
- android:id="@+id/preview_card_container"
- android:layout_width="match_parent"
- android:layout_height="0dp"
- android:paddingTop="@dimen/preview_content_padding_top"
- android:paddingBottom="@dimen/preview_content_padding_bottom"
- android:clipToPadding="false"
- app:layout_constrainedHeight="true"
- app:layout_constraintStart_toStartOf="parent"
- app:layout_constraintEnd_toEndOf="parent"
- app:layout_constraintTop_toTopOf="parent"
- app:layout_constraintBottom_toTopOf="@id/options_container"
- app:layout_constraintHeight_max="@dimen/preview_pager_max_height"
- app:layout_constraintVertical_bias="0.0"
- app:layout_constraintHeight_percent="@dimen/preview_pager_maximum_height_ratio">
- <include layout="@layout/theme_preview_card"/>
- </FrameLayout>
-
- <androidx.recyclerview.widget.RecyclerView
- android:id="@+id/options_container"
- android:layout_width="match_parent"
- android:layout_height="0dp"
- android:layout_gravity="bottom|center_horizontal"
- android:layout_marginTop="10dp"
- app:layout_constraintStart_toStartOf="parent"
- app:layout_constraintEnd_toEndOf="parent"
- app:layout_constraintTop_toBottomOf="@+id/preview_card_container"
- app:layout_constraintBottom_toBottomOf="parent"
- app:layout_constraintVertical_bias="1.0"/>
- </androidx.constraintlayout.widget.ConstraintLayout>
-
- <androidx.core.widget.ContentLoadingProgressBar
- android:id="@+id/loading_indicator"
- style="@android:style/Widget.DeviceDefault.ProgressBar"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_marginTop="200dp"
- android:layout_gravity="center_horizontal|top"
- android:indeterminate="true"/>
-
- <FrameLayout
- android:id="@+id/error_section"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:visibility="gone">
- <TextView
- android:id="@+id/error_message"
- style="@style/TitleTextAppearance"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:layout_gravity="center"
- android:gravity="center"
- android:text="@string/something_went_wrong"/>
- </FrameLayout>
- </FrameLayout>
-</LinearLayout>
diff --git a/res/layout/preview_card_color_content.xml b/res/layout/preview_card_color_content.xml
deleted file mode 100644
index 9ab90c1..0000000
--- a/res/layout/preview_card_color_content.xml
+++ /dev/null
@@ -1,160 +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="match_parent"
- android:layout_gravity="center"
- android:gravity="center_horizontal"
- android:orientation="vertical">
- <LinearLayout
- android:layout_width="@dimen/preview_theme_color_component_size"
- android:layout_height="wrap_content"
- android:gravity="center|bottom"
- android:orientation="horizontal">
- <FrameLayout
- android:layout_width="@dimen/preview_theme_icon_size"
- android:layout_height="@dimen/preview_theme_icon_size"
- android:layout_weight="1">
- <ImageView
- android:layout_width="@dimen/preview_theme_icon_size"
- android:layout_height="@dimen/preview_theme_icon_size"
- android:layout_gravity="center"
- android:id="@+id/preview_color_qs_0_bg"/>
- <ImageView
- android:layout_width="@dimen/preview_theme_tile_size"
- android:layout_height="@dimen/preview_theme_tile_size"
- android:layout_gravity="center"
- android:id="@+id/preview_color_qs_0_icon"
- android:tint="@color/tile_enabled_icon_color"/>
- </FrameLayout>
- <Space
- android:layout_width="0dp"
- android:layout_height="match_parent"
- android:layout_weight="0" />
- <FrameLayout
- android:layout_width="@dimen/preview_theme_icon_size"
- android:layout_height="@dimen/preview_theme_icon_size"
- android:layout_weight="1">
- <ImageView
- android:layout_width="@dimen/preview_theme_icon_size"
- android:layout_height="@dimen/preview_theme_icon_size"
- android:layout_gravity="center"
- android:id="@+id/preview_color_qs_1_bg"/>
- <ImageView
- android:layout_width="@dimen/preview_theme_tile_size"
- android:layout_height="@dimen/preview_theme_tile_size"
- android:layout_gravity="center"
- android:id="@+id/preview_color_qs_1_icon"
- android:tint="@color/tile_enabled_icon_color"/>
- </FrameLayout>
- <Space
- android:layout_width="0dp"
- android:layout_height="match_parent"
- android:layout_weight="0" />
- <FrameLayout
- android:layout_width="@dimen/preview_theme_icon_size"
- android:layout_height="@dimen/preview_theme_icon_size"
- android:layout_weight="1">
- <ImageView
- android:layout_width="@dimen/preview_theme_icon_size"
- android:layout_height="@dimen/preview_theme_icon_size"
- android:layout_gravity="center"
- android:id="@+id/preview_color_qs_2_bg"/>
- <ImageView
- android:layout_width="@dimen/preview_theme_tile_size"
- android:layout_height="@dimen/preview_theme_tile_size"
- android:layout_gravity="center"
- android:id="@+id/preview_color_qs_2_icon"
- android:color="@color/tile_enabled_icon_color"/>
- </FrameLayout>
- </LinearLayout>
- <Space
- android:layout_width="match_parent"
- android:layout_height="0dp"
- android:layout_weight="1" />
- <LinearLayout
- android:layout_width="@dimen/preview_theme_color_component_size"
- android:layout_height="wrap_content"
- android:layout_weight="0"
- android:orientation="horizontal"
- android:gravity="center">
- <SeekBar
- android:id="@+id/preview_seekbar"
- android:layout_height="wrap_content"
- android:layout_width="match_parent"
- android:tint="@color/theme_preview_icon_color"
- android:maxHeight="2dp"
- android:progress="1"
- android:clickable="true"
- android:max="3"/>
- </LinearLayout>
- <Space
- android:layout_width="match_parent"
- android:layout_height="0dp"
- android:layout_weight="1" />
- <LinearLayout
- android:layout_width="@dimen/preview_theme_color_component_size"
- android:layout_height="wrap_content"
- android:gravity="center"
- android:orientation="horizontal">
- <FrameLayout
- android:layout_width="@dimen/preview_theme_icon_size"
- android:layout_height="@dimen/preview_theme_icon_size"
- android:layout_weight="1">
- <CheckBox
- android:id="@+id/preview_check_selected"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_gravity="center"
- android:checked="true"
- android:enabled="false"/>
- </FrameLayout>
- <Space
- android:layout_width="0dp"
- android:layout_height="match_parent"
- android:layout_weight="0" />
- <FrameLayout
- android:layout_width="@dimen/preview_theme_icon_size"
- android:layout_height="@dimen/preview_theme_icon_size"
- android:layout_weight="1">
- <RadioButton
- android:id="@+id/preview_radio_selected"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_gravity="center"
- android:checked="true"
- android:enabled="false"/>
- </FrameLayout>
- <Space
- android:layout_width="0dp"
- android:layout_height="match_parent"
- android:layout_weight="0" />
- <FrameLayout
- android:layout_width="@dimen/preview_theme_icon_size"
- android:layout_height="@dimen/preview_theme_icon_size"
- android:layout_weight="1">
- <Switch
- android:id="@+id/preview_toggle_selected"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_gravity="center"
- android:checked="true"
- android:enabled="false"/>
- </FrameLayout>
- </LinearLayout>
-</LinearLayout>
diff --git a/res/layout/preview_card_font_content.xml b/res/layout/preview_card_font_content.xml
deleted file mode 100644
index 408778e..0000000
--- a/res/layout/preview_card_font_content.xml
+++ /dev/null
@@ -1,55 +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"
- xmlns:tools="http://schemas.android.com/tools"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:layout_gravity="center"
- android:orientation="vertical"
- tools:showIn="@layout/theme_preview_card">
- <TextView
- style="@style/FontCardTitleStyle"
- android:id="@+id/font_card_title"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_gravity="center"
- android:gravity="center_horizontal"
- android:maxLines="1"
- android:text="@string/font_card_title"/>
- <Space
- android:layout_width="match_parent"
- android:layout_height="0dp"
- android:layout_weight="1"/>
- <View
- android:id="@+id/font_card_divider"
- android:layout_width="16dp"
- android:layout_height="2dp"
- android:layout_gravity="center"
- android:background="?android:colorAccent"/>
- <Space
- android:layout_width="match_parent"
- android:layout_height="0dp"
- android:layout_weight="1"/>
- <TextView
- style="@style/FontCardBodyTextStyle"
- android:id="@+id/font_card_body"
- android:layout_height="wrap_content"
- android:layout_gravity="bottom|center_horizontal"
- android:gravity="center_horizontal"
- android:text="@string/font_card_body"/>
-</LinearLayout>
\ No newline at end of file
diff --git a/res/layout/preview_card_icon_content.xml b/res/layout/preview_card_icon_content.xml
deleted file mode 100644
index 29620c8..0000000
--- a/res/layout/preview_card_icon_content.xml
+++ /dev/null
@@ -1,91 +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="match_parent"
- android:layout_gravity="center"
- android:gravity="center_horizontal"
- android:orientation="vertical">
- <LinearLayout
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:gravity="center_horizontal"
- android:orientation="horizontal">
- <ImageView
- android:id="@+id/preview_icon_0"
- android:layout_width="@dimen/preview_theme_icon_size"
- android:layout_height="@dimen/preview_theme_icon_size"
- android:layout_weight="1"
- android:tint="@color/theme_preview_icon_color"/>
- <Space
- android:layout_width="@dimen/preview_theme_icon_size"
- android:layout_height="match_parent"
- android:layout_weight="0" />
- <ImageView
- android:id="@+id/preview_icon_1"
- android:layout_width="@dimen/preview_theme_icon_size"
- android:layout_height="@dimen/preview_theme_icon_size"
- android:layout_weight="1"
- android:tint="@color/theme_preview_icon_color"/>
- <Space
- android:layout_width="@dimen/preview_theme_icon_size"
- android:layout_height="match_parent"
- android:layout_weight="0" />
- <ImageView
- android:id="@+id/preview_icon_2"
- android:layout_width="@dimen/preview_theme_icon_size"
- android:layout_height="@dimen/preview_theme_icon_size"
- android:layout_weight="1"
- android:tint="@color/theme_preview_icon_color"/>
- </LinearLayout>
- <Space
- android:layout_width="match_parent"
- android:layout_height="68dp" />
- <LinearLayout
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:gravity="bottom|center_horizontal"
- android:orientation="horizontal">
- <ImageView
- android:id="@+id/preview_icon_3"
- android:layout_width="@dimen/preview_theme_icon_size"
- android:layout_height="@dimen/preview_theme_icon_size"
- android:layout_weight="1"
- android:tint="@color/theme_preview_icon_color"/>
- <Space
- android:layout_width="@dimen/preview_theme_icon_size"
- android:layout_height="match_parent"
- android:layout_weight="0" />
- <ImageView
- android:id="@+id/preview_icon_4"
- android:layout_width="@dimen/preview_theme_icon_size"
- android:layout_height="@dimen/preview_theme_icon_size"
- android:layout_weight="1"
- android:tint="@color/theme_preview_icon_color"/>
- <Space
- android:layout_width="@dimen/preview_theme_icon_size"
- android:layout_height="match_parent"
- android:layout_weight="0" />
- <ImageView
- android:id="@+id/preview_icon_5"
- android:layout_width="@dimen/preview_theme_icon_size"
- android:layout_height="@dimen/preview_theme_icon_size"
- android:layout_weight="1"
- android:tint="@color/theme_preview_icon_color"/>
- </LinearLayout>
-</LinearLayout>
\ No newline at end of file
diff --git a/res/layout/preview_card_shape_content.xml b/res/layout/preview_card_shape_content.xml
deleted file mode 100644
index 0afa6bc..0000000
--- a/res/layout/preview_card_shape_content.xml
+++ /dev/null
@@ -1,127 +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="match_parent"
- android:layout_gravity="center"
- android:gravity="center_horizontal"
- android:orientation="vertical">
- <LinearLayout
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:gravity="center_horizontal"
- android:orientation="horizontal">
- <FrameLayout
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_weight="1">
- <ImageView
- android:id="@+id/shape_preview_icon_0"
- android:layout_width="@dimen/preview_theme_shape_size"
- android:layout_height="@dimen/preview_theme_shape_size"
- android:layout_gravity="center_horizontal"
- android:layout_margin="4dp"
- android:elevation="4dp"/>
- </FrameLayout>
- <Space
- android:layout_width="@dimen/preview_theme_shape_size"
- android:layout_height="match_parent"
- android:layout_weight="0" />
- <FrameLayout
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_weight="1">
- <ImageView
- android:id="@+id/shape_preview_icon_1"
- android:layout_width="@dimen/preview_theme_shape_size"
- android:layout_height="@dimen/preview_theme_shape_size"
- android:layout_gravity="center_horizontal"
- android:layout_margin="4dp"
- android:elevation="4dp"/>
- </FrameLayout>
- <Space
- android:layout_width="@dimen/preview_theme_shape_size"
- android:layout_height="match_parent"
- android:layout_weight="0" />
- <FrameLayout
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_weight="1">
- <ImageView
- android:id="@+id/shape_preview_icon_2"
- android:layout_width="@dimen/preview_theme_shape_size"
- android:layout_height="@dimen/preview_theme_shape_size"
- android:layout_gravity="center_horizontal"
- android:layout_margin="4dp"
- android:elevation="4dp"/>
- </FrameLayout>
- </LinearLayout>
- <Space
- android:layout_width="match_parent"
- android:layout_height="60dp" />
- <LinearLayout
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:gravity="bottom|center_horizontal"
- android:orientation="horizontal">
- <FrameLayout
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_weight="1">
- <ImageView
- android:id="@+id/shape_preview_icon_3"
- android:layout_width="@dimen/preview_theme_shape_size"
- android:layout_height="@dimen/preview_theme_shape_size"
- android:layout_gravity="center_horizontal"
- android:layout_margin="4dp"
- android:elevation="4dp"/>
- </FrameLayout>
- <Space
- android:layout_width="@dimen/preview_theme_shape_size"
- android:layout_height="match_parent"
- android:layout_weight="0" />
- <FrameLayout
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_weight="1">
- <ImageView
- android:id="@+id/shape_preview_icon_4"
- android:layout_width="@dimen/preview_theme_shape_size"
- android:layout_height="@dimen/preview_theme_shape_size"
- android:layout_gravity="center_horizontal"
- android:layout_margin="4dp"
- android:elevation="4dp"/>
- </FrameLayout>
- <Space
- android:layout_width="@dimen/preview_theme_shape_size"
- android:layout_height="match_parent"
- android:layout_weight="0" />
- <FrameLayout
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_weight="1">
- <ImageView
- android:id="@+id/shape_preview_icon_5"
- android:layout_width="@dimen/preview_theme_shape_size"
- android:layout_height="@dimen/preview_theme_shape_size"
- android:layout_margin="4dp"
- android:layout_gravity="center_horizontal"
- android:elevation="4dp"/>
- </FrameLayout>
- </LinearLayout>
-</LinearLayout>
\ No newline at end of file
diff --git a/res/layout/theme_color_option.xml b/res/layout/theme_color_option.xml
deleted file mode 100644
index 8d55626..0000000
--- a/res/layout/theme_color_option.xml
+++ /dev/null
@@ -1,30 +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.
--->
-<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_gravity="center"
- android:layout_marginTop="28dp"
- android:layout_marginHorizontal="@dimen/component_options_margin_horizontal">
-
- <ImageView
- android:id="@+id/option_tile"
- android:layout_width="@dimen/component_color_chip_container_size"
- android:layout_height="@dimen/component_color_chip_container_size"
- android:layout_gravity="center"
- android:scaleType="center"/>
-</FrameLayout>
diff --git a/res/layout/theme_component_preview.xml b/res/layout/theme_component_preview.xml
deleted file mode 100644
index 67abe6b..0000000
--- a/res/layout/theme_component_preview.xml
+++ /dev/null
@@ -1,58 +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.
--->
-<androidx.constraintlayout.widget.ConstraintLayout
- xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:app="http://schemas.android.com/apk/res-auto"
- xmlns:tools="http://schemas.android.com/tools"
- android:id="@+id/theme_preview_card_background"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:clipToPadding="false"
- android:maxHeight="@dimen/preview_theme_max_height"
- android:minHeight="@dimen/preview_theme_min_height"
- android:paddingTop="64dp">
-
- <TextView
- android:id="@+id/theme_preview_card_header"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_gravity="center_horizontal"
- android:drawablePadding="@dimen/theme_preview_header_drawable_padding"
- android:textAppearance="@style/CardTitleTextAppearance"
- android:importantForAccessibility="no"
- app:layout_constraintBottom_toTopOf="@id/theme_preview_card_body_container"
- app:layout_constraintEnd_toEndOf="parent"
- app:layout_constraintHorizontal_bias="0.5"
- app:layout_constraintStart_toStartOf="parent"
- app:layout_constraintTop_toTopOf="parent"
- app:layout_constraintVertical_chainStyle="spread_inside"
- tools:text="Default"/>
-
- <FrameLayout
- android:id="@+id/theme_preview_card_body_container"
- android:layout_width="match_parent"
- android:layout_height="0dp"
- android:layout_marginTop="@dimen/preview_theme_content_margin"
- android:clipChildren="false"
- android:importantForAccessibility="noHideDescendants"
- app:layout_constraintEnd_toEndOf="parent"
- app:layout_constraintHeight_max="@dimen/preview_theme_content_max_height"
- app:layout_constraintHeight_min="@dimen/preview_theme_content_min_height"
- app:layout_constraintHorizontal_bias="0.5"
- app:layout_constraintStart_toStartOf="parent"
- app:layout_constraintTop_toBottomOf="@+id/theme_preview_card_header"/>
-</androidx.constraintlayout.widget.ConstraintLayout>
diff --git a/res/layout/theme_font_option.xml b/res/layout/theme_font_option.xml
deleted file mode 100644
index dea4f78..0000000
--- a/res/layout/theme_font_option.xml
+++ /dev/null
@@ -1,41 +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="wrap_content"
- android:layout_height="wrap_content"
- android:orientation="vertical">
-
- <FrameLayout
- android:id="@+id/option_tile"
- android:layout_width="@dimen/option_tile_width"
- android:layout_height="@dimen/option_tile_width"
- android:layout_gravity="center_horizontal"
- android:paddingHorizontal="@dimen/option_tile_padding_horizontal"
- android:paddingVertical="@dimen/option_tile_padding_vertical"
- android:layout_marginHorizontal="@dimen/component_options_margin_horizontal"
- android:background="@drawable/option_border">
- <TextView
- android:id="@+id/thumbnail_text"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_gravity="center"
- android:textSize="@dimen/font_comonent_option_thumbnail_size"
- android:textAlignment="center"
- android:textColor="?android:attr/colorForeground"
- android:text="@string/font_component_option_thumbnail"/>
- </FrameLayout>
-</LinearLayout>
diff --git a/res/layout/theme_icon_option.xml b/res/layout/theme_icon_option.xml
deleted file mode 100644
index 292b8cd..0000000
--- a/res/layout/theme_icon_option.xml
+++ /dev/null
@@ -1,38 +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="wrap_content"
- android:layout_height="wrap_content"
- android:orientation="vertical">
-
- <FrameLayout
- android:id="@+id/option_tile"
- android:layout_width="@dimen/option_tile_width"
- android:layout_height="@dimen/option_tile_width"
- android:layout_gravity="center_horizontal"
- android:paddingHorizontal="@dimen/option_tile_padding_horizontal"
- android:paddingVertical="@dimen/option_tile_padding_vertical"
- android:layout_marginHorizontal="@dimen/component_options_margin_horizontal"
- android:background="@drawable/option_border">
- <ImageView
- android:id="@+id/option_icon"
- android:layout_width="@dimen/component_icon_thumb_size"
- android:layout_height="@dimen/component_icon_thumb_size"
- android:layout_gravity="center"
- android:tint="?android:colorForeground"/>
- </FrameLayout>
-</LinearLayout>
diff --git a/res/layout/theme_info_view.xml b/res/layout/theme_info_view.xml
deleted file mode 100644
index 085a35e..0000000
--- a/res/layout/theme_info_view.xml
+++ /dev/null
@@ -1,76 +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.
--->
-<com.android.customization.picker.theme.ThemeInfoView
- xmlns:android="http://schemas.android.com/apk/res/android"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:gravity="center_horizontal"
- android:orientation="vertical"
- android:padding="@dimen/wallpaper_info_pane_padding"
- android:theme="@style/WallpaperPicker.BottomPaneStyle">
-
- <TextView
- android:id="@+id/style_info_title"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:layout_marginBottom="@dimen/theme_info_margin"
- android:gravity="center"
- android:lineHeight="24dp"
- android:textAppearance="@style/SubtitleTextAppearance"
- android:textColor="?android:textColorPrimary"
- android:textSize="16sp"
- android:text="@string/style_info_description"/>
-
- <LinearLayout
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:orientation="horizontal"
- android:gravity="center">
-
- <TextView
- android:id="@+id/font_preview"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_gravity="center"
- android:layout_marginHorizontal="@dimen/theme_info_margin"
- android:importantForAccessibility="no"
- android:textSize="@dimen/theme_info_text_size"
- android:textColor="?android:attr/colorForeground"
- android:text="@string/font_component_option_thumbnail"/>
-
- <ImageView
- android:id="@+id/qs_preview_icon"
- android:layout_width="@dimen/theme_info_icon_size"
- android:layout_height="@dimen/theme_info_icon_size"
- android:layout_marginHorizontal="@dimen/theme_info_margin"
- android:tint="?android:textColorPrimary"/>
-
- <ImageView
- android:id="@+id/app_preview_icon"
- android:layout_width="@dimen/theme_info_icon_size"
- android:layout_height="@dimen/theme_info_icon_size"
- android:layout_marginHorizontal="@dimen/theme_info_margin"
- android:layout_marginVertical="@dimen/theme_info_app_preview_icon_margin"
- android:elevation="@dimen/theme_info_app_preview_icon_elevation"/>
-
- <ImageView
- android:id="@+id/shape_preview_icon"
- android:layout_width="@dimen/theme_info_icon_size"
- android:layout_height="@dimen/theme_info_icon_size"
- android:layout_marginHorizontal="@dimen/theme_info_margin"/>
- </LinearLayout>
-</com.android.customization.picker.theme.ThemeInfoView>
\ No newline at end of file
diff --git a/res/layout/theme_option.xml b/res/layout/theme_option.xml
deleted file mode 100644
index bdf82d0..0000000
--- a/res/layout/theme_option.xml
+++ /dev/null
@@ -1,74 +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:paddingHorizontal="@dimen/option_padding_horizontal"
- android:paddingBottom="@dimen/option_bottom_margin"
- android:clipChildren="false"
- android:clipToPadding="false"
- android:orientation="vertical">
-
- <TextView
- android:id="@+id/option_label"
- android:layout_width="@dimen/option_tile_width"
- android:layout_height="wrap_content"
- android:layout_gravity="center_horizontal"
- android:layout_marginBottom="@dimen/theme_option_label_margin"
- android:ellipsize="end"
- android:gravity="center_horizontal"
- android:maxLines="1"
- android:textAppearance="@style/OptionTitleTextAppearance"/>
- <RelativeLayout
- android:id="@+id/option_tile"
- android:layout_width="@dimen/option_tile_width"
- android:layout_height="@dimen/option_tile_width"
- android:layout_gravity="center_horizontal"
- android:paddingHorizontal="@dimen/option_tile_padding_horizontal"
- android:paddingVertical="@dimen/option_tile_padding_vertical"
- android:background="@drawable/option_border">
- <ImageView
- android:id="@+id/theme_option_icon"
- android:layout_width="@dimen/theme_option_icon_sample_width"
- android:layout_height="@dimen/theme_option_icon_sample_height"
- android:layout_alignParentTop="true"
- android:layout_alignParentStart="true"
- android:tint="?android:colorForeground"/>
- <ImageView
- android:id="@+id/theme_option_shape"
- android:layout_width="@dimen/theme_option_shape_sample_width"
- android:layout_height="@dimen/theme_option_shape_sample_height"
- android:layout_alignBottom="@+id/theme_option_icon"
- android:layout_toEndOf="@id/theme_option_icon"
- android:layout_marginStart="@dimen/theme_option_sample_margin"/>
- <TextView
- android:id="@+id/theme_option_font"
- android:layout_width="@dimen/theme_option_font_sample_width"
- android:layout_height="@dimen/theme_option_font_sample_height"
- android:layout_gravity="center"
- android:layout_below="@id/theme_option_icon"
- android:layout_marginTop="@dimen/option_bottom_margin"
- android:autoSizeMaxTextSize="@dimen/theme_option_font_text_size"
- android:autoSizeMinTextSize="@dimen/theme_option_font_min_text_size"
- android:autoSizeTextType="uniform"
- android:gravity="center"
- android:letterSpacing=".2"
- android:text="@string/theme_font_example"
- android:textAlignment="center"
- android:textSize="@dimen/theme_option_font_text_size" />
- </RelativeLayout>
-</LinearLayout>
diff --git a/res/layout/theme_preview_app_icon_shape.xml b/res/layout/theme_preview_app_icon_shape.xml
deleted file mode 100644
index fe95f90..0000000
--- a/res/layout/theme_preview_app_icon_shape.xml
+++ /dev/null
@@ -1,149 +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="match_parent"
- android:orientation="vertical">
-
- <androidx.constraintlayout.widget.ConstraintLayout
- android:id="@+id/app_row_0"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:orientation="horizontal"
- app:layout_constraintStart_toStartOf="parent"
- app:layout_constraintEnd_toEndOf="parent"
- app:layout_constraintTop_toTopOf="parent"
- app:layout_constraintBottom_toTopOf="@id/app_row_1">
-
- <LinearLayout
- android:id="@+id/app_item_0"
- android:layout_width="@dimen/preview_theme_app_icon_size"
- android:layout_height="wrap_content"
- android:gravity="center_horizontal"
- android:orientation="vertical"
- android:clipChildren="false"
- app:layout_constraintStart_toStartOf="parent"
- app:layout_constraintEnd_toStartOf="@id/app_item_1"
- app:layout_constraintTop_toTopOf="parent"
- app:layout_constraintBottom_toBottomOf="parent">
- <ImageView
- android:id="@+id/shape_preview_icon_0"
- android:layout_width="@dimen/preview_theme_app_icon_size"
- android:layout_height="@dimen/preview_theme_app_icon_size"
- android:elevation="4dp"/>
- <TextView
- android:id="@+id/shape_preview_icon_app_name_0"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_marginTop="@dimen/preview_theme_app_icon_shape_text_margin_top"
- android:textSize="@dimen/preview_theme_app_icon_shape_text_size"
- android:lineHeight="20dp"
- android:singleLine="true"/>
- </LinearLayout>
-
- <LinearLayout
- android:id="@+id/app_item_1"
- android:layout_width="@dimen/preview_theme_app_icon_size"
- android:layout_height="wrap_content"
- android:gravity="center_horizontal"
- android:orientation="vertical"
- android:clipChildren="false"
- app:layout_constraintStart_toEndOf="@id/app_item_0"
- app:layout_constraintEnd_toEndOf="parent"
- app:layout_constraintTop_toTopOf="parent"
- app:layout_constraintBottom_toBottomOf="parent">
- <ImageView
- android:id="@+id/shape_preview_icon_1"
- android:layout_width="@dimen/preview_theme_app_icon_size"
- android:layout_height="@dimen/preview_theme_app_icon_size"
- android:elevation="4dp"/>
- <TextView
- android:id="@+id/shape_preview_icon_app_name_1"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_marginTop="@dimen/preview_theme_app_icon_shape_text_margin_top"
- android:textSize="@dimen/preview_theme_app_icon_shape_text_size"
- android:lineHeight="20dp"
- android:singleLine="true"/>
- </LinearLayout>
-
- </androidx.constraintlayout.widget.ConstraintLayout>
-
- <androidx.constraintlayout.widget.ConstraintLayout
- android:id="@+id/app_row_1"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:orientation="horizontal"
- app:layout_constraintStart_toStartOf="parent"
- app:layout_constraintEnd_toEndOf="parent"
- app:layout_constraintTop_toBottomOf="@id/app_row_0"
- app:layout_constraintBottom_toBottomOf="parent">
- <LinearLayout
- android:id="@+id/app_item_2"
- android:layout_width="@dimen/preview_theme_app_icon_size"
- android:layout_height="wrap_content"
- android:gravity="center_horizontal"
- android:orientation="vertical"
- android:clipChildren="false"
- app:layout_constraintStart_toStartOf="parent"
- app:layout_constraintEnd_toStartOf="@id/app_item_3"
- app:layout_constraintTop_toTopOf="parent"
- app:layout_constraintBottom_toBottomOf="parent">
- <ImageView
- android:id="@+id/shape_preview_icon_2"
- android:layout_width="@dimen/preview_theme_app_icon_size"
- android:layout_height="@dimen/preview_theme_app_icon_size"
- android:elevation="4dp"/>
- <TextView
- android:id="@+id/shape_preview_icon_app_name_2"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_marginTop="@dimen/preview_theme_app_icon_shape_text_margin_top"
- android:textSize="@dimen/preview_theme_app_icon_shape_text_size"
- android:lineHeight="20dp"
- android:singleLine="true"/>
- </LinearLayout>
-
- <LinearLayout
- android:id="@+id/app_item_3"
- android:layout_width="@dimen/preview_theme_app_icon_size"
- android:layout_height="wrap_content"
- android:gravity="center_horizontal"
- android:orientation="vertical"
- android:clipChildren="false"
- app:layout_constraintStart_toEndOf="@id/app_item_2"
- app:layout_constraintEnd_toEndOf="parent"
- app:layout_constraintTop_toTopOf="parent"
- app:layout_constraintBottom_toBottomOf="parent">
- <ImageView
- android:id="@+id/shape_preview_icon_3"
- android:layout_width="@dimen/preview_theme_app_icon_size"
- android:layout_height="@dimen/preview_theme_app_icon_size"
- android:elevation="4dp"/>
- <TextView
- android:id="@+id/shape_preview_icon_app_name_3"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_marginTop="@dimen/preview_theme_app_icon_shape_text_margin_top"
- android:textSize="@dimen/preview_theme_app_icon_shape_text_size"
- android:lineHeight="20dp"
- android:singleLine="true"/>
- </LinearLayout>
- </androidx.constraintlayout.widget.ConstraintLayout>
-</androidx.constraintlayout.widget.ConstraintLayout>
diff --git a/res/layout/theme_preview_card.xml b/res/layout/theme_preview_card.xml
deleted file mode 100644
index 4fc8995..0000000
--- a/res/layout/theme_preview_card.xml
+++ /dev/null
@@ -1,42 +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.cardview.widget.CardView
- xmlns:android="http://schemas.android.com/apk/res/android"
- style="@style/FullContentPreviewCard"
- android:id="@+id/theme_preview_card"
- android:contentDescription="@string/theme_preview_card_content_description"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:layout_gravity="center">
-
- <ImageView
- android:id="@+id/wallpaper_preview_image"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:background="?android:colorPrimary" />
-
- <SurfaceView
- android:id="@+id/wallpaper_preview_surface"
- android:layout_width="match_parent"
- android:layout_height="match_parent" />
-
- <FrameLayout
- android:id="@+id/theme_preview_container"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:importantForAccessibility="noHideDescendants" />
-</androidx.cardview.widget.CardView>
\ No newline at end of file
diff --git a/res/layout/theme_preview_color_icons.xml b/res/layout/theme_preview_color_icons.xml
deleted file mode 100644
index e87a7a1..0000000
--- a/res/layout/theme_preview_color_icons.xml
+++ /dev/null
@@ -1,181 +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.cardview.widget.CardView
- xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:app="http://schemas.android.com/apk/res-auto"
- android:id="@+id/color_icons_section"
- android:layout_width="match_parent"
- android:layout_height="match_parent">
-
- <androidx.constraintlayout.widget.ConstraintLayout
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:paddingHorizontal="@dimen/preview_theme_color_icons_padding_horizontal"
- android:paddingTop="@dimen/preview_theme_color_icons_padding_top"
- android:paddingBottom="@dimen/preview_theme_color_icons_padding_bottom"
- android:orientation="vertical"
- android:background="?android:colorBackground">
-
- <!-- Title -->
- <TextView
- android:id="@+id/color_icons_section_title"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:text="@string/theme_preview_icons_section_title"
- android:textSize="@dimen/preview_theme_color_icons_title_text_size"
- android:textColor="?android:textColorSecondary"
- android:lineHeight="16dp"
- android:gravity="center"
- app:layout_constraintStart_toStartOf="parent"
- app:layout_constraintEnd_toEndOf="parent"
- app:layout_constraintTop_toTopOf="parent"
- app:layout_constraintBottom_toTopOf="@id/qs_icons"
- app:layout_constraintVertical_bias="0.0"
- app:layout_constraintVertical_chainStyle="spread_inside" />
-
- <!-- QS icons -->
- <LinearLayout
- android:id="@+id/qs_icons"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:orientation="horizontal"
- app:layout_constraintStart_toStartOf="parent"
- app:layout_constraintEnd_toEndOf="parent"
- app:layout_constraintTop_toBottomOf="@id/color_icons_section_title"
- app:layout_constraintBottom_toTopOf="@id/button_icons">
- <FrameLayout
- android:layout_width="@dimen/preview_theme_color_icons_icon_size"
- android:layout_height="@dimen/preview_theme_color_icons_icon_size">
- <ImageView
- android:id="@+id/preview_color_qs_0_bg"
- android:layout_width="@dimen/preview_theme_color_icons_icon_size"
- android:layout_height="@dimen/preview_theme_color_icons_icon_size"/>
- <ImageView
- android:id="@+id/preview_color_qs_0_icon"
- android:layout_width="@dimen/preview_theme_color_icons_tile_size"
- android:layout_height="@dimen/preview_theme_color_icons_tile_size"
- android:tint="?android:textColorPrimary"
- android:layout_gravity="center"/>
- </FrameLayout>
- <Space
- android:layout_width="0dp"
- android:layout_height="wrap_content"
- android:layout_weight="1"/>
- <FrameLayout
- android:layout_width="@dimen/preview_theme_color_icons_icon_size"
- android:layout_height="@dimen/preview_theme_color_icons_icon_size"
- android:layout_gravity="center_horizontal">
- <ImageView
- android:id="@+id/preview_color_qs_1_bg"
- android:layout_width="@dimen/preview_theme_color_icons_icon_size"
- android:layout_height="@dimen/preview_theme_color_icons_icon_size"/>
- <ImageView
- android:id="@+id/preview_color_qs_1_icon"
- android:layout_width="@dimen/preview_theme_color_icons_tile_size"
- android:layout_height="@dimen/preview_theme_color_icons_tile_size"
- android:tint="?android:textColorPrimary"
- android:layout_gravity="center"/>
- </FrameLayout>
- <Space
- android:layout_width="0dp"
- android:layout_height="wrap_content"
- android:layout_weight="1"/>
- <FrameLayout
- android:layout_width="@dimen/preview_theme_color_icons_icon_size"
- android:layout_height="@dimen/preview_theme_color_icons_icon_size">
- <ImageView
- android:id="@+id/preview_color_qs_2_bg"
- android:layout_width="@dimen/preview_theme_color_icons_icon_size"
- android:layout_height="@dimen/preview_theme_color_icons_icon_size"/>
- <ImageView
- android:id="@+id/preview_color_qs_2_icon"
- android:layout_width="@dimen/preview_theme_color_icons_tile_size"
- android:layout_height="@dimen/preview_theme_color_icons_tile_size"
- android:tint="?android:textColorPrimary"
- android:layout_gravity="center"/>
- </FrameLayout>
- <Space
- android:layout_width="0dp"
- android:layout_height="wrap_content"
- android:layout_weight="1"/>
- <FrameLayout
- android:layout_width="@dimen/preview_theme_color_icons_icon_size"
- android:layout_height="@dimen/preview_theme_color_icons_icon_size">
- <ImageView
- android:id="@+id/preview_color_qs_3_bg"
- android:layout_width="@dimen/preview_theme_color_icons_icon_size"
- android:layout_height="@dimen/preview_theme_color_icons_icon_size"/>
- <ImageView
- android:id="@+id/preview_color_qs_3_icon"
- android:layout_width="@dimen/preview_theme_color_icons_tile_size"
- android:layout_height="@dimen/preview_theme_color_icons_tile_size"
- android:tint="?android:textColorPrimary"
- android:layout_gravity="center"/>
- </FrameLayout>
- </LinearLayout>
-
- <!-- Icons of CheckBox/RadioButton/Switch. -->
- <RelativeLayout
- android:id="@+id/button_icons"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- app:layout_constraintStart_toStartOf="parent"
- app:layout_constraintEnd_toEndOf="parent"
- app:layout_constraintTop_toBottomOf="@id/qs_icons"
- app:layout_constraintBottom_toBottomOf="parent">
- <FrameLayout
- android:layout_width="@dimen/preview_theme_icon_size"
- android:layout_height="@dimen/preview_theme_icon_size"
- android:layout_alignParentStart="true">
- <CheckBox
- android:id="@+id/preview_check_selected"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_gravity="center"
- android:checked="true"
- android:enabled="false"/>
- </FrameLayout>
-
- <FrameLayout
- android:layout_width="@dimen/preview_theme_icon_size"
- android:layout_height="@dimen/preview_theme_icon_size"
- android:layout_centerHorizontal="true">
- <RadioButton
- android:id="@+id/preview_radio_selected"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_gravity="center"
- android:checked="true"
- android:enabled="false"/>
- </FrameLayout>
-
- <FrameLayout
- android:layout_width="wrap_content"
- android:layout_height="@dimen/preview_theme_icon_size"
- android:layout_alignParentEnd="true">
- <Switch
- android:id="@+id/preview_toggle_selected"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_gravity="center"
- android:checked="true"
- android:enabled="false"/>
- </FrameLayout>
- </RelativeLayout>
-
- </androidx.constraintlayout.widget.ConstraintLayout>
-</androidx.cardview.widget.CardView>
diff --git a/res/layout/theme_preview_content.xml b/res/layout/theme_preview_content.xml
deleted file mode 100644
index 4b29617..0000000
--- a/res/layout/theme_preview_content.xml
+++ /dev/null
@@ -1,92 +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="match_parent"
- android:paddingTop="@dimen/preview_theme_content_padding_top"
- android:paddingBottom="@dimen/preview_theme_content_padding_bottom"
- android:clipToPadding="false"
- android:clipChildren="false">
-
- <FrameLayout
- android:id="@+id/topbar_container"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:layout_marginHorizontal="@dimen/preview_theme_topbar_container_margin_horizontal"
- app:layout_constraintStart_toStartOf="parent"
- app:layout_constraintEnd_toEndOf="parent"
- app:layout_constraintTop_toTopOf="parent"
- app:layout_constraintBottom_toTopOf="@id/smart_space_date"
- app:layout_constraintVertical_bias="0.0"
- app:layout_constraintVertical_chainStyle="spread_inside">
- <include layout="@layout/theme_preview_topbar" />
- </FrameLayout>
-
- <TextView
- android:id="@+id/smart_space_date"
- android:layout_width="match_parent"
- android:layout_height="0dp"
- android:textSize="@dimen/preview_theme_smart_space_date_size"
- android:singleLine="true"
- android:gravity="center|bottom"
- app:layout_constraintStart_toStartOf="parent"
- app:layout_constraintEnd_toEndOf="parent"
- app:layout_constraintTop_toBottomOf="@id/topbar_container"
- app:layout_constraintBottom_toTopOf="@id/app_icon_shape_container"
- app:layout_constraintHeight_percent="0.1" />
-
- <FrameLayout
- android:id="@+id/app_icon_shape_container"
- android:layout_width="match_parent"
- android:layout_height="0dp"
- app:layout_constraintStart_toStartOf="parent"
- app:layout_constraintEnd_toEndOf="parent"
- app:layout_constraintTop_toBottomOf="@id/smart_space_date"
- app:layout_constraintBottom_toTopOf="@id/color_icons_container"
- app:layout_constraintHeight_percent="0.49">
- <include layout="@layout/theme_preview_app_icon_shape" />
- </FrameLayout>
-
- <FrameLayout
- android:id="@+id/color_icons_container"
- android:layout_width="match_parent"
- android:layout_height="0dp"
- android:layout_marginHorizontal="@dimen/preview_theme_color_icons_container_margin_horizontal"
- app:layout_constraintStart_toStartOf="parent"
- app:layout_constraintEnd_toEndOf="parent"
- app:layout_constraintTop_toBottomOf="@id/app_icon_shape_container"
- app:layout_constraintBottom_toTopOf="@id/theme_qsb_container"
- app:layout_constraintHeight_percent="0.275">
- <include layout="@layout/theme_preview_color_icons" />
- </FrameLayout>
-
- <FrameLayout
- android:id="@+id/theme_qsb_container"
- android:layout_width="match_parent"
- android:layout_height="0dp"
- android:layout_marginHorizontal="@dimen/preview_theme_qsb_container_margin_horizontal"
- app:layout_constraintStart_toStartOf="parent"
- app:layout_constraintEnd_toEndOf="parent"
- app:layout_constraintTop_toBottomOf="@id/color_icons_container"
- app:layout_constraintBottom_toBottomOf="parent"
- app:layout_constraintHeight_percent="0.1">
- <include layout="@layout/theme_cover_qsb" />
- </FrameLayout>
-
-</androidx.constraintlayout.widget.ConstraintLayout>
diff --git a/res/layout/theme_preview_topbar.xml b/res/layout/theme_preview_topbar.xml
deleted file mode 100644
index af69de9..0000000
--- a/res/layout/theme_preview_topbar.xml
+++ /dev/null
@@ -1,56 +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.
--->
-<FrameLayout
- xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:tools="http://schemas.android.com/tools"
- android:id="@+id/theme_preview_top_bar"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- tools:visibility="visible"
- tools:showIn="@layout/theme_preview_card">
- <TextView
- android:id="@+id/theme_preview_clock"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_gravity="start|center_vertical"
- android:textColor="?android:textColorSecondary"
- android:textSize="@dimen/preview_theme_cover_topbar_clock_size"
- tools:text="8:10"/>
- <LinearLayout
- android:id="@+id/theme_preview_top_bar_icons"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_gravity="end|center_vertical"
- android:orientation="horizontal">
- <ImageView
- android:id="@+id/preview_icon_0"
- android:layout_width="@dimen/preview_theme_cover_topbar_icon_size"
- android:layout_height="@dimen/preview_theme_cover_topbar_icon_size"
- android:tint="?android:textColorSecondary"/>
- <ImageView
- android:id="@+id/preview_icon_1"
- android:layout_width="@dimen/preview_theme_cover_topbar_icon_size"
- android:layout_height="@dimen/preview_theme_cover_topbar_icon_size"
- android:layout_marginHorizontal="8dp"
- android:tint="?android:textColorSecondary"/>
- <ImageView
- android:id="@+id/preview_icon_2"
- android:layout_width="@dimen/preview_theme_cover_topbar_icon_size"
- android:layout_height="@dimen/preview_theme_cover_topbar_icon_size"
- android:tint="?android:textColorSecondary"/>
- </LinearLayout>
-</FrameLayout>
\ No newline at end of file
diff --git a/res/layout/theme_shape_option.xml b/res/layout/theme_shape_option.xml
deleted file mode 100644
index c5682c0..0000000
--- a/res/layout/theme_shape_option.xml
+++ /dev/null
@@ -1,33 +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="wrap_content"
- android:layout_height="wrap_content"
- android:orientation="vertical">
- <FrameLayout
- android:id="@+id/option_tile"
- android:layout_width="@dimen/option_tile_width"
- android:layout_height="@dimen/option_tile_width"
- android:layout_gravity="center"
- android:layout_marginHorizontal="@dimen/component_options_margin_horizontal">
- <ImageView
- android:id="@+id/shape_thumbnail"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:layout_gravity="center"/>
- </FrameLayout>
-</LinearLayout>
diff --git a/res/menu/custom_theme_editor_menu.xml b/res/menu/custom_theme_editor_menu.xml
deleted file mode 100644
index 7019181..0000000
--- a/res/menu/custom_theme_editor_menu.xml
+++ /dev/null
@@ -1,23 +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.
--->
-<menu xmlns:android="http://schemas.android.com/apk/res/android">
- <item
- android:id="@+id/custom_theme_delete"
- android:title="@string/custom_theme_delete"
- android:icon="@drawable/ic_delete_24px"
- android:showAsAction="always"/>
-</menu>
\ No newline at end of file
diff --git a/src/com/android/customization/model/theme/DefaultThemeProvider.java b/src/com/android/customization/model/theme/DefaultThemeProvider.java
deleted file mode 100644
index 89067c6..0000000
--- a/src/com/android/customization/model/theme/DefaultThemeProvider.java
+++ /dev/null
@@ -1,424 +0,0 @@
-/*
- * 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.
- */
-package com.android.customization.model.theme;
-
-import static com.android.customization.model.ResourceConstants.ANDROID_PACKAGE;
-import static com.android.customization.model.ResourceConstants.ICONS_FOR_PREVIEW;
-import static com.android.customization.model.ResourceConstants.OVERLAY_CATEGORY_COLOR;
-import static com.android.customization.model.ResourceConstants.OVERLAY_CATEGORY_FONT;
-import static com.android.customization.model.ResourceConstants.OVERLAY_CATEGORY_ICON_ANDROID;
-import static com.android.customization.model.ResourceConstants.OVERLAY_CATEGORY_ICON_LAUNCHER;
-import static com.android.customization.model.ResourceConstants.OVERLAY_CATEGORY_ICON_SETTINGS;
-import static com.android.customization.model.ResourceConstants.OVERLAY_CATEGORY_ICON_SYSUI;
-import static com.android.customization.model.ResourceConstants.OVERLAY_CATEGORY_ICON_THEMEPICKER;
-import static com.android.customization.model.ResourceConstants.OVERLAY_CATEGORY_SHAPE;
-import static com.android.customization.model.ResourceConstants.SYSUI_PACKAGE;
-
-import android.content.Context;
-import android.content.pm.ApplicationInfo;
-import android.content.pm.PackageManager.NameNotFoundException;
-import android.content.res.Resources.NotFoundException;
-import android.graphics.drawable.Drawable;
-import android.text.TextUtils;
-import android.util.Log;
-
-import androidx.annotation.Nullable;
-
-import com.android.customization.model.CustomizationManager.OptionsFetchedListener;
-import com.android.customization.model.ResourcesApkProvider;
-import com.android.customization.model.theme.ThemeBundle.Builder;
-import com.android.customization.model.theme.ThemeBundle.PreviewInfo.ShapeAppIcon;
-import com.android.customization.model.theme.custom.CustomTheme;
-import com.android.customization.module.CustomizationPreferences;
-import com.android.wallpaper.R;
-
-import org.json.JSONArray;
-import org.json.JSONException;
-import org.json.JSONObject;
-
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-
-/**
- * Default implementation of {@link ThemeBundleProvider} that reads Themes' overlays from a stub APK.
- */
-public class DefaultThemeProvider extends ResourcesApkProvider implements ThemeBundleProvider {
-
- private static final String TAG = "DefaultThemeProvider";
-
- private static final String THEMES_ARRAY = "themes";
- private static final String TITLE_PREFIX = "theme_title_";
- private static final String FONT_PREFIX = "theme_overlay_font_";
- private static final String COLOR_PREFIX = "theme_overlay_color_";
- private static final String SHAPE_PREFIX = "theme_overlay_shape_";
- private static final String ICON_ANDROID_PREFIX = "theme_overlay_icon_android_";
- private static final String ICON_LAUNCHER_PREFIX = "theme_overlay_icon_launcher_";
- private static final String ICON_THEMEPICKER_PREFIX = "theme_overlay_icon_themepicker_";
- private static final String ICON_SETTINGS_PREFIX = "theme_overlay_icon_settings_";
- private static final String ICON_SYSUI_PREFIX = "theme_overlay_icon_sysui_";
-
- private static final String DEFAULT_THEME_NAME= "default";
- private static final String THEME_TITLE_FIELD = "_theme_title";
- private static final String THEME_ID_FIELD = "_theme_id";
-
- private final OverlayThemeExtractor mOverlayProvider;
- private List<ThemeBundle> mThemes;
- private final CustomizationPreferences mCustomizationPreferences;
-
- public DefaultThemeProvider(Context context, CustomizationPreferences customizationPrefs) {
- super(context, context.getString(R.string.themes_stub_package));
- mOverlayProvider = new OverlayThemeExtractor(context);
- mCustomizationPreferences = customizationPrefs;
- }
-
- @Override
- public void fetch(OptionsFetchedListener<ThemeBundle> callback, boolean reload) {
- if (mThemes == null || reload) {
- mThemes = new ArrayList<>();
- loadAll();
- }
-
- if(callback != null) {
- callback.onOptionsLoaded(mThemes);
- }
- }
-
- @Override
- public boolean isAvailable() {
- return mOverlayProvider.isAvailable() && super.isAvailable();
- }
-
- private void loadAll() {
- // Add "Custom" option at the beginning.
- mThemes.add(new CustomTheme.Builder()
- .setId(CustomTheme.newId())
- .setTitle(mContext.getString(R.string.custom_theme))
- .build(mContext));
-
- addDefaultTheme();
-
- String[] themeNames = getItemsFromStub(THEMES_ARRAY);
-
- for (String themeName : themeNames) {
- // Default theme needs special treatment (see #addDefaultTheme())
- if (DEFAULT_THEME_NAME.equals(themeName)) {
- continue;
- }
- ThemeBundle.Builder builder = new Builder();
- try {
- builder.setTitle(mStubApkResources.getString(
- mStubApkResources.getIdentifier(TITLE_PREFIX + themeName,
- "string", mStubPackageName)));
-
- String shapeOverlayPackage = getOverlayPackage(SHAPE_PREFIX, themeName);
- mOverlayProvider.addShapeOverlay(builder, shapeOverlayPackage);
-
- String fontOverlayPackage = getOverlayPackage(FONT_PREFIX, themeName);
- mOverlayProvider.addFontOverlay(builder, fontOverlayPackage);
-
- String colorOverlayPackage = getOverlayPackage(COLOR_PREFIX, themeName);
- mOverlayProvider.addColorOverlay(builder, colorOverlayPackage);
-
- String iconAndroidOverlayPackage = getOverlayPackage(ICON_ANDROID_PREFIX,
- themeName);
-
- mOverlayProvider.addAndroidIconOverlay(builder, iconAndroidOverlayPackage);
-
- String iconSysUiOverlayPackage = getOverlayPackage(ICON_SYSUI_PREFIX, themeName);
-
- mOverlayProvider.addSysUiIconOverlay(builder, iconSysUiOverlayPackage);
-
- String iconLauncherOverlayPackage = getOverlayPackage(ICON_LAUNCHER_PREFIX,
- themeName);
- mOverlayProvider.addNoPreviewIconOverlay(builder, iconLauncherOverlayPackage);
-
- String iconThemePickerOverlayPackage = getOverlayPackage(ICON_THEMEPICKER_PREFIX,
- themeName);
- mOverlayProvider.addNoPreviewIconOverlay(builder,
- iconThemePickerOverlayPackage);
-
- String iconSettingsOverlayPackage = getOverlayPackage(ICON_SETTINGS_PREFIX,
- themeName);
-
- mOverlayProvider.addNoPreviewIconOverlay(builder, iconSettingsOverlayPackage);
-
- mThemes.add(builder.build(mContext));
- } catch (NameNotFoundException | NotFoundException e) {
- Log.w(TAG, String.format("Couldn't load part of theme %s, will skip it", themeName),
- e);
- }
- }
-
- addCustomThemes();
- }
-
- /**
- * Default theme requires different treatment: if there are overlay packages specified in the
- * stub apk, we'll use those, otherwise we'll get the System default values. But we cannot skip
- * the default theme.
- */
- private void addDefaultTheme() {
- ThemeBundle.Builder builder = new Builder().asDefault();
-
- int titleId = mStubApkResources.getIdentifier(TITLE_PREFIX + DEFAULT_THEME_NAME,
- "string", mStubPackageName);
- if (titleId > 0) {
- builder.setTitle(mStubApkResources.getString(titleId));
- } else {
- builder.setTitle(mContext.getString(R.string.default_theme_title));
- }
-
- try {
- String colorOverlayPackage = getOverlayPackage(COLOR_PREFIX, DEFAULT_THEME_NAME);
- mOverlayProvider.addColorOverlay(builder, colorOverlayPackage);
- } catch (NameNotFoundException | NotFoundException e) {
- Log.d(TAG, "Didn't find color overlay for default theme, will use system default");
- mOverlayProvider.addSystemDefaultColor(builder);
- }
-
- try {
- String fontOverlayPackage = getOverlayPackage(FONT_PREFIX, DEFAULT_THEME_NAME);
- mOverlayProvider.addFontOverlay(builder, fontOverlayPackage);
- } catch (NameNotFoundException | NotFoundException e) {
- Log.d(TAG, "Didn't find font overlay for default theme, will use system default");
- mOverlayProvider.addSystemDefaultFont(builder);
- }
-
- try {
- String shapeOverlayPackage = getOverlayPackage(SHAPE_PREFIX, DEFAULT_THEME_NAME);
- mOverlayProvider.addShapeOverlay(builder ,shapeOverlayPackage, false);
- } catch (NameNotFoundException | NotFoundException e) {
- Log.d(TAG, "Didn't find shape overlay for default theme, will use system default");
- mOverlayProvider.addSystemDefaultShape(builder);
- }
-
- List<ShapeAppIcon> icons = new ArrayList<>();
- for (String packageName : mOverlayProvider.getShapePreviewIconPackages()) {
- Drawable icon = null;
- CharSequence name = null;
- try {
- icon = mContext.getPackageManager().getApplicationIcon(packageName);
- ApplicationInfo appInfo = mContext.getPackageManager()
- .getApplicationInfo(packageName, /* flag= */ 0);
- name = mContext.getPackageManager().getApplicationLabel(appInfo);
- } catch (NameNotFoundException e) {
- Log.d(TAG, "Couldn't find app " + packageName + ", won't use it for icon shape"
- + "preview");
- } finally {
- if (icon != null && !TextUtils.isEmpty(name)) {
- icons.add(new ShapeAppIcon(icon, name));
- }
- }
- }
- builder.setShapePreviewIcons(icons);
-
- try {
- String iconAndroidOverlayPackage = getOverlayPackage(ICON_ANDROID_PREFIX,
- DEFAULT_THEME_NAME);
- mOverlayProvider.addAndroidIconOverlay(builder, iconAndroidOverlayPackage);
- } catch (NameNotFoundException | NotFoundException e) {
- Log.d(TAG, "Didn't find Android icons overlay for default theme, using system default");
- mOverlayProvider.addSystemDefaultIcons(builder, ANDROID_PACKAGE, ICONS_FOR_PREVIEW);
- }
-
- try {
- String iconSysUiOverlayPackage = getOverlayPackage(ICON_SYSUI_PREFIX,
- DEFAULT_THEME_NAME);
- mOverlayProvider.addSysUiIconOverlay(builder, iconSysUiOverlayPackage);
- } catch (NameNotFoundException | NotFoundException e) {
- Log.d(TAG,
- "Didn't find SystemUi icons overlay for default theme, using system default");
- mOverlayProvider.addSystemDefaultIcons(builder, SYSUI_PACKAGE, ICONS_FOR_PREVIEW);
- }
-
- mThemes.add(builder.build(mContext));
- }
-
- @Override
- public void storeCustomTheme(CustomTheme theme) {
- if (mThemes == null) {
- fetch(options -> {
- addCustomThemeAndStore(theme);
- }, false);
- } else {
- addCustomThemeAndStore(theme);
- }
- }
-
- private void addCustomThemeAndStore(CustomTheme theme) {
- if (!mThemes.contains(theme)) {
- mThemes.add(theme);
- } else {
- mThemes.replaceAll(t -> theme.equals(t) ? theme : t);
- }
- JSONArray themesArray = new JSONArray();
- mThemes.stream()
- .filter(themeBundle -> themeBundle instanceof CustomTheme
- && !themeBundle.getPackagesByCategory().isEmpty())
- .forEachOrdered(themeBundle -> addThemeBundleToArray(themesArray, themeBundle));
- mCustomizationPreferences.storeCustomThemes(themesArray.toString());
- }
-
- private void addThemeBundleToArray(JSONArray themesArray, ThemeBundle themeBundle) {
- JSONObject jsonPackages = themeBundle.getJsonPackages(false);
- try {
- jsonPackages.put(THEME_TITLE_FIELD, themeBundle.getTitle());
- if (themeBundle instanceof CustomTheme) {
- jsonPackages.put(THEME_ID_FIELD, ((CustomTheme)themeBundle).getId());
- }
- } catch (JSONException e) {
- Log.w("Exception saving theme's title", e);
- }
- themesArray.put(jsonPackages);
- }
-
- @Override
- public void removeCustomTheme(CustomTheme theme) {
- JSONArray themesArray = new JSONArray();
- mThemes.stream()
- .filter(themeBundle -> themeBundle instanceof CustomTheme
- && ((CustomTheme) themeBundle).isDefined())
- .forEachOrdered(customTheme -> {
- if (!customTheme.equals(theme)) {
- addThemeBundleToArray(themesArray, customTheme);
- }
- });
- mCustomizationPreferences.storeCustomThemes(themesArray.toString());
- }
-
- private void addCustomThemes() {
- String serializedThemes = mCustomizationPreferences.getSerializedCustomThemes();
- int customThemesCount = 0;
- if (!TextUtils.isEmpty(serializedThemes)) {
- try {
- JSONArray customThemes = new JSONArray(serializedThemes);
- for (int i = 0; i < customThemes.length(); i++) {
- JSONObject jsonTheme = customThemes.getJSONObject(i);
- CustomTheme.Builder builder = new CustomTheme.Builder();
- try {
- convertJsonToBuilder(jsonTheme, builder);
- } catch (NameNotFoundException | NotFoundException e) {
- Log.i(TAG, "Couldn't parse serialized custom theme", e);
- builder = null;
- }
- if (builder != null) {
- if (TextUtils.isEmpty(builder.getTitle())) {
- builder.setTitle(mContext.getString(R.string.custom_theme_title,
- customThemesCount + 1));
- }
- mThemes.add(builder.build(mContext));
- } else {
- Log.w(TAG, "Couldn't read stored custom theme, resetting");
- mThemes.add(new CustomTheme.Builder()
- .setId(CustomTheme.newId())
- .setTitle(mContext.getString(
- R.string.custom_theme_title, customThemesCount + 1))
- .build(mContext));
- }
- customThemesCount++;
- }
- } catch (JSONException e) {
- Log.w(TAG, "Couldn't read stored custom theme, resetting", e);
- mThemes.add(new CustomTheme.Builder()
- .setId(CustomTheme.newId())
- .setTitle(mContext.getString(
- R.string.custom_theme_title, customThemesCount + 1))
- .build(mContext));
- }
- }
- }
-
- @Nullable
- @Override
- public ThemeBundle.Builder parseThemeBundle(String serializedTheme) throws JSONException {
- JSONObject theme = new JSONObject(serializedTheme);
- try {
- ThemeBundle.Builder builder = new ThemeBundle.Builder();
- convertJsonToBuilder(theme, builder);
- return builder;
- } catch (NameNotFoundException | NotFoundException e) {
- Log.i(TAG, "Couldn't parse serialized custom theme", e);
- return null;
- }
- }
-
- @Nullable
- @Override
- public CustomTheme.Builder parseCustomTheme(String serializedTheme) throws JSONException {
- JSONObject theme = new JSONObject(serializedTheme);
- try {
- CustomTheme.Builder builder = new CustomTheme.Builder();
- convertJsonToBuilder(theme, builder);
- return builder;
- } catch (NameNotFoundException | NotFoundException e) {
- Log.i(TAG, "Couldn't parse serialized custom theme", e);
- return null;
- }
- }
-
- private void convertJsonToBuilder(JSONObject theme, ThemeBundle.Builder builder)
- throws JSONException, NameNotFoundException, NotFoundException {
- Map<String, String> customPackages = new HashMap<>();
- Iterator<String> keysIterator = theme.keys();
-
- while (keysIterator.hasNext()) {
- String category = keysIterator.next();
- customPackages.put(category, theme.getString(category));
- }
- mOverlayProvider.addShapeOverlay(builder,
- customPackages.get(OVERLAY_CATEGORY_SHAPE));
- mOverlayProvider.addFontOverlay(builder,
- customPackages.get(OVERLAY_CATEGORY_FONT));
- mOverlayProvider.addColorOverlay(builder,
- customPackages.get(OVERLAY_CATEGORY_COLOR));
- mOverlayProvider.addAndroidIconOverlay(builder,
- customPackages.get(OVERLAY_CATEGORY_ICON_ANDROID));
- mOverlayProvider.addSysUiIconOverlay(builder,
- customPackages.get(OVERLAY_CATEGORY_ICON_SYSUI));
- mOverlayProvider.addNoPreviewIconOverlay(builder,
- customPackages.get(OVERLAY_CATEGORY_ICON_SETTINGS));
- mOverlayProvider.addNoPreviewIconOverlay(builder,
- customPackages.get(OVERLAY_CATEGORY_ICON_LAUNCHER));
- mOverlayProvider.addNoPreviewIconOverlay(builder,
- customPackages.get(OVERLAY_CATEGORY_ICON_THEMEPICKER));
- if (theme.has(THEME_TITLE_FIELD)) {
- builder.setTitle(theme.getString(THEME_TITLE_FIELD));
- }
- if (builder instanceof CustomTheme.Builder && theme.has(THEME_ID_FIELD)) {
- ((CustomTheme.Builder) builder).setId(theme.getString(THEME_ID_FIELD));
- }
- }
-
- @Override
- public ThemeBundle findEquivalent(ThemeBundle other) {
- if (mThemes == null) {
- return null;
- }
- for (ThemeBundle theme : mThemes) {
- if (theme.isEquivalent(other)) {
- return theme;
- }
- }
- return null;
- }
-
- private String getOverlayPackage(String prefix, String themeName) {
- return getItemStringFromStub(prefix, themeName);
- }
-}
diff --git a/src/com/android/customization/model/theme/OverlayThemeExtractor.java b/src/com/android/customization/model/theme/OverlayThemeExtractor.java
deleted file mode 100644
index 816176e..0000000
--- a/src/com/android/customization/model/theme/OverlayThemeExtractor.java
+++ /dev/null
@@ -1,293 +0,0 @@
-package com.android.customization.model.theme;
-
-import static com.android.customization.model.ResourceConstants.ANDROID_PACKAGE;
-import static com.android.customization.model.ResourceConstants.ICONS_FOR_PREVIEW;
-import static com.android.customization.model.ResourceConstants.SETTINGS_PACKAGE;
-import static com.android.customization.model.ResourceConstants.SYSUI_PACKAGE;
-
-import android.content.Context;
-import android.content.om.OverlayInfo;
-import android.content.om.OverlayManager;
-import android.content.pm.ApplicationInfo;
-import android.content.pm.PackageManager.NameNotFoundException;
-import android.content.res.Resources;
-import android.content.res.Resources.NotFoundException;
-import android.graphics.Typeface;
-import android.graphics.drawable.Drawable;
-import android.os.UserHandle;
-import android.text.TextUtils;
-import android.util.Log;
-
-import androidx.annotation.Dimension;
-import androidx.annotation.Nullable;
-
-import com.android.customization.model.ResourceConstants;
-import com.android.customization.model.theme.ThemeBundle.Builder;
-import com.android.customization.model.theme.ThemeBundle.PreviewInfo.ShapeAppIcon;
-import com.android.wallpaper.R;
-
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.function.Consumer;
-
-class OverlayThemeExtractor {
-
- private static final String TAG = "OverlayThemeExtractor";
-
- private final Context mContext;
- private final Map<String, OverlayInfo> mOverlayInfos = new HashMap<>();
- // List of packages
- private final String[] mShapePreviewIconPackages;
-
- OverlayThemeExtractor(Context context) {
- mContext = context;
- OverlayManager om = context.getSystemService(OverlayManager.class);
- if (om != null) {
- Consumer<OverlayInfo> addToMap = overlayInfo -> mOverlayInfos.put(
- overlayInfo.getPackageName(), overlayInfo);
-
- UserHandle user = UserHandle.of(UserHandle.myUserId());
- om.getOverlayInfosForTarget(ANDROID_PACKAGE, user).forEach(addToMap);
- om.getOverlayInfosForTarget(SYSUI_PACKAGE, user).forEach(addToMap);
- om.getOverlayInfosForTarget(SETTINGS_PACKAGE, user).forEach(addToMap);
- om.getOverlayInfosForTarget(ResourceConstants.getLauncherPackage(context), user)
- .forEach(addToMap);
- om.getOverlayInfosForTarget(context.getPackageName(), user).forEach(addToMap);
- }
- mShapePreviewIconPackages = context.getResources().getStringArray(
- R.array.icon_shape_preview_packages);
- }
-
- boolean isAvailable() {
- return !mOverlayInfos.isEmpty();
- }
-
- void addColorOverlay(Builder builder, String colorOverlayPackage)
- throws NameNotFoundException {
- if (!TextUtils.isEmpty(colorOverlayPackage)) {
- builder.addOverlayPackage(getOverlayCategory(colorOverlayPackage),
- colorOverlayPackage)
- .setColorAccentLight(loadColor(ResourceConstants.ACCENT_COLOR_LIGHT_NAME,
- colorOverlayPackage))
- .setColorAccentDark(loadColor(ResourceConstants.ACCENT_COLOR_DARK_NAME,
- colorOverlayPackage));
- } else {
- addSystemDefaultColor(builder);
- }
- }
-
- void addShapeOverlay(Builder builder, String shapeOverlayPackage)
- throws NameNotFoundException {
- addShapeOverlay(builder, shapeOverlayPackage, true);
- }
-
- void addShapeOverlay(Builder builder, String shapeOverlayPackage, boolean addPreview)
- throws NameNotFoundException {
- if (!TextUtils.isEmpty(shapeOverlayPackage)) {
- builder.addOverlayPackage(getOverlayCategory(shapeOverlayPackage),
- shapeOverlayPackage)
- .setShapePath(
- loadString(ResourceConstants.CONFIG_ICON_MASK, shapeOverlayPackage))
- .setBottomSheetCornerRadius(
- loadDimen(ResourceConstants.CONFIG_CORNERRADIUS, shapeOverlayPackage));
- } else {
- addSystemDefaultShape(builder);
- }
- if (addPreview) {
- addShapePreviewIcons(builder);
- }
- }
-
- private void addShapePreviewIcons(Builder builder) {
- List<ShapeAppIcon> icons = new ArrayList<>();
- for (String packageName : mShapePreviewIconPackages) {
- Drawable icon = null;
- CharSequence name = null;
- try {
- icon = mContext.getPackageManager().getApplicationIcon(packageName);
- // Add the shape icon app name.
- ApplicationInfo appInfo = mContext.getPackageManager()
- .getApplicationInfo(packageName, /* flag= */ 0);
- name = mContext.getPackageManager().getApplicationLabel(appInfo);
- } catch (NameNotFoundException e) {
- Log.d(TAG, "Couldn't find app " + packageName
- + ", won't use it for icon shape preview");
- } finally {
- if (icon != null && !TextUtils.isEmpty(name)) {
- icons.add(new ShapeAppIcon(icon, name));
- }
- }
- }
- builder.setShapePreviewIcons(icons);
- }
-
- void addNoPreviewIconOverlay(Builder builder, String overlayPackage) {
- if (!TextUtils.isEmpty(overlayPackage)) {
- builder.addOverlayPackage(getOverlayCategory(overlayPackage),
- overlayPackage);
- }
- }
-
- void addSysUiIconOverlay(Builder builder, String iconSysUiOverlayPackage)
- throws NameNotFoundException {
- if (!TextUtils.isEmpty(iconSysUiOverlayPackage)) {
- addIconOverlay(builder, iconSysUiOverlayPackage);
- }
- }
-
- void addAndroidIconOverlay(Builder builder, String iconAndroidOverlayPackage)
- throws NameNotFoundException {
- if (!TextUtils.isEmpty(iconAndroidOverlayPackage)) {
- addIconOverlay(builder, iconAndroidOverlayPackage, ICONS_FOR_PREVIEW);
- } else {
- addSystemDefaultIcons(builder, ANDROID_PACKAGE, ICONS_FOR_PREVIEW);
- }
- }
-
- void addIconOverlay(Builder builder, String packageName, String... previewIcons)
- throws NameNotFoundException {
- builder.addOverlayPackage(getOverlayCategory(packageName), packageName);
- for (String iconName : previewIcons) {
- builder.addIcon(loadIconPreviewDrawable(iconName, packageName, false));
- }
- }
-
- void addFontOverlay(Builder builder, String fontOverlayPackage)
- throws NameNotFoundException {
- if (!TextUtils.isEmpty(fontOverlayPackage)) {
- builder.addOverlayPackage(getOverlayCategory(fontOverlayPackage),
- fontOverlayPackage)
- .setBodyFontFamily(loadTypeface(
- ResourceConstants.CONFIG_BODY_FONT_FAMILY,
- fontOverlayPackage))
- .setHeadlineFontFamily(loadTypeface(
- ResourceConstants.CONFIG_HEADLINE_FONT_FAMILY,
- fontOverlayPackage));
- } else {
- addSystemDefaultFont(builder);
- }
- }
-
- void addSystemDefaultIcons(Builder builder, String packageName,
- String... previewIcons) {
- try {
- for (String iconName : previewIcons) {
- builder.addIcon(loadIconPreviewDrawable(iconName, packageName, true));
- }
- } catch (NameNotFoundException | NotFoundException e) {
- Log.w(TAG, "Didn't find android package icons, will skip preview", e);
- }
- }
-
- void addSystemDefaultShape(Builder builder) {
- Resources system = Resources.getSystem();
- String iconMaskPath = system.getString(
- system.getIdentifier(ResourceConstants.CONFIG_ICON_MASK,
- "string", ResourceConstants.ANDROID_PACKAGE));
- builder.setShapePath(iconMaskPath)
- .setBottomSheetCornerRadius(
- system.getDimensionPixelOffset(
- system.getIdentifier(ResourceConstants.CONFIG_CORNERRADIUS,
- "dimen", ResourceConstants.ANDROID_PACKAGE)));
- }
-
- void addSystemDefaultColor(Builder builder) {
- Resources system = Resources.getSystem();
- int colorAccentLight = system.getColor(
- system.getIdentifier(ResourceConstants.ACCENT_COLOR_LIGHT_NAME, "color",
- ResourceConstants.ANDROID_PACKAGE), null);
- builder.setColorAccentLight(colorAccentLight);
-
- int colorAccentDark = system.getColor(
- system.getIdentifier(ResourceConstants.ACCENT_COLOR_DARK_NAME, "color",
- ResourceConstants.ANDROID_PACKAGE), null);
- builder.setColorAccentDark(colorAccentDark);
- }
-
- void addSystemDefaultFont(Builder builder) {
- Resources system = Resources.getSystem();
- String headlineFontFamily = system.getString(system.getIdentifier(
- ResourceConstants.CONFIG_HEADLINE_FONT_FAMILY, "string",
- ResourceConstants.ANDROID_PACKAGE));
- String bodyFontFamily = system.getString(system.getIdentifier(
- ResourceConstants.CONFIG_BODY_FONT_FAMILY,
- "string", ResourceConstants.ANDROID_PACKAGE));
- builder.setHeadlineFontFamily(Typeface.create(headlineFontFamily, Typeface.NORMAL))
- .setBodyFontFamily(Typeface.create(bodyFontFamily, Typeface.NORMAL));
- }
-
- Typeface loadTypeface(String configName, String fontOverlayPackage)
- throws NameNotFoundException, NotFoundException {
-
- // TODO(santie): check for font being present in system
-
- Resources overlayRes = mContext.getPackageManager()
- .getResourcesForApplication(fontOverlayPackage);
-
- String fontFamily = overlayRes.getString(overlayRes.getIdentifier(configName,
- "string", fontOverlayPackage));
- return Typeface.create(fontFamily, Typeface.NORMAL);
- }
-
- int loadColor(String colorName, String colorPackage)
- throws NameNotFoundException, NotFoundException {
-
- Resources overlayRes = mContext.getPackageManager()
- .getResourcesForApplication(colorPackage);
- return overlayRes.getColor(overlayRes.getIdentifier(colorName, "color", colorPackage),
- null);
- }
-
- String loadString(String stringName, String packageName)
- throws NameNotFoundException, NotFoundException {
-
- Resources overlayRes =
- mContext.getPackageManager().getResourcesForApplication(
- packageName);
- return overlayRes.getString(overlayRes.getIdentifier(stringName, "string", packageName));
- }
-
- @Dimension
- int loadDimen(String dimenName, String packageName)
- throws NameNotFoundException, NotFoundException {
-
- Resources overlayRes =
- mContext.getPackageManager().getResourcesForApplication(
- packageName);
- return overlayRes.getDimensionPixelOffset(overlayRes.getIdentifier(
- dimenName, "dimen", packageName));
- }
-
- boolean loadBoolean(String booleanName, String packageName)
- throws NameNotFoundException, NotFoundException {
-
- Resources overlayRes =
- mContext.getPackageManager().getResourcesForApplication(
- packageName);
- return overlayRes.getBoolean(overlayRes.getIdentifier(
- booleanName, "boolean", packageName));
- }
-
- Drawable loadIconPreviewDrawable(String drawableName, String packageName,
- boolean fromSystem) throws NameNotFoundException, NotFoundException {
-
- Resources packageRes =
- mContext.getPackageManager().getResourcesForApplication(
- packageName);
- Resources res = fromSystem ? Resources.getSystem() : packageRes;
- return res.getDrawable(
- packageRes.getIdentifier(drawableName, "drawable", packageName), null);
- }
-
- @Nullable
- String getOverlayCategory(String packageName) {
- OverlayInfo info = mOverlayInfos.get(packageName);
- return info != null ? info.getCategory() : null;
- }
-
- String[] getShapePreviewIconPackages() {
- return mShapePreviewIconPackages;
- }
-}
\ No newline at end of file
diff --git a/src/com/android/customization/model/theme/ThemeBundle.java b/src/com/android/customization/model/theme/ThemeBundle.java
deleted file mode 100644
index 3a32f25..0000000
--- a/src/com/android/customization/model/theme/ThemeBundle.java
+++ /dev/null
@@ -1,432 +0,0 @@
-/*
- * 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.
- */
-package com.android.customization.model.theme;
-
-import static com.android.customization.model.ResourceConstants.OVERLAY_CATEGORY_COLOR;
-import static com.android.customization.model.ResourceConstants.OVERLAY_CATEGORY_FONT;
-import static com.android.customization.model.ResourceConstants.OVERLAY_CATEGORY_ICON_ANDROID;
-import static com.android.customization.model.ResourceConstants.OVERLAY_CATEGORY_SHAPE;
-import static com.android.customization.model.ResourceConstants.PATH_SIZE;
-
-import android.content.Context;
-import android.content.pm.PackageManager;
-import android.content.res.Configuration;
-import android.content.res.Resources;
-import android.graphics.Path;
-import android.graphics.Typeface;
-import android.graphics.drawable.AdaptiveIconDrawable;
-import android.graphics.drawable.Drawable;
-import android.graphics.drawable.ShapeDrawable;
-import android.graphics.drawable.shapes.PathShape;
-import android.text.TextUtils;
-import android.util.Log;
-import android.view.View;
-import android.widget.ImageView;
-import android.widget.TextView;
-
-import androidx.annotation.ColorInt;
-import androidx.annotation.Dimension;
-import androidx.annotation.Nullable;
-import androidx.core.graphics.PathParser;
-
-import com.android.customization.model.CustomizationManager;
-import com.android.customization.model.CustomizationOption;
-import com.android.customization.model.theme.ThemeBundle.PreviewInfo.ShapeAppIcon;
-import com.android.customization.widget.DynamicAdaptiveIconDrawable;
-import com.android.wallpaper.R;
-import com.android.wallpaper.asset.Asset;
-import com.android.wallpaper.asset.BitmapCachingAsset;
-import com.android.wallpaper.model.WallpaperInfo;
-import com.android.wallpaper.util.ResourceUtils;
-
-import org.json.JSONException;
-import org.json.JSONObject;
-
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.stream.Collectors;
-
-/**
- * Represents a Theme component available in the system as a "persona" bundle.
- * Note that in this context a Theme is not related to Android's Styles, but it's rather an
- * abstraction representing a series of overlays to be applied to the system.
- */
-public class ThemeBundle implements CustomizationOption<ThemeBundle> {
-
- private static final String TAG = "ThemeBundle";
- private final static String EMPTY_JSON = "{}";
- private final static String TIMESTAMP_FIELD = "_applied_timestamp";
-
- private final String mTitle;
- private final PreviewInfo mPreviewInfo;
- private final boolean mIsDefault;
- protected final Map<String, String> mPackagesByCategory;
- private WallpaperInfo mOverrideWallpaper;
- private Asset mOverrideWallpaperAsset;
- private CharSequence mContentDescription;
-
- protected ThemeBundle(String title, Map<String, String> overlayPackages,
- boolean isDefault, PreviewInfo previewInfo) {
- mTitle = title;
- mIsDefault = isDefault;
- mPreviewInfo = previewInfo;
- mPackagesByCategory = Collections.unmodifiableMap(removeNullValues(overlayPackages));
- }
-
- @Override
- public String getTitle() {
- return mTitle;
- }
-
- @Override
- public void bindThumbnailTile(View view) {
- Resources res = view.getContext().getResources();
-
- ((TextView) view.findViewById(R.id.theme_option_font)).setTypeface(
- mPreviewInfo.headlineFontFamily);
- if (mPreviewInfo.shapeDrawable != null) {
- ((ShapeDrawable) mPreviewInfo.shapeDrawable).getPaint().setColor(
- mPreviewInfo.resolveAccentColor(res));
- ((ImageView) view.findViewById(R.id.theme_option_shape)).setImageDrawable(
- mPreviewInfo.shapeDrawable);
- }
- if (!mPreviewInfo.icons.isEmpty()) {
- Drawable icon = mPreviewInfo.icons.get(0).getConstantState().newDrawable().mutate();
- icon.setTint(ResourceUtils.getColorAttr(
- view.getContext(), android.R.attr.textColorSecondary));
- ((ImageView) view.findViewById(R.id.theme_option_icon)).setImageDrawable(
- icon);
- }
- view.setContentDescription(getContentDescription(view.getContext()));
- }
-
- @Override
- public boolean isActive(CustomizationManager<ThemeBundle> manager) {
- ThemeManager themeManager = (ThemeManager) manager;
-
- if (mIsDefault) {
- String serializedOverlays = themeManager.getStoredOverlays();
- return TextUtils.isEmpty(serializedOverlays) || EMPTY_JSON.equals(serializedOverlays);
- } else {
- Map<String, String> currentOverlays = themeManager.getCurrentOverlays();
- return mPackagesByCategory.equals(currentOverlays);
- }
- }
-
- @Override
- public int getLayoutResId() {
- return R.layout.theme_option;
- }
-
- /**
- * This is similar to #equals() but it only compares this theme's packages with the other, that
- * is, it will return true if applying this theme has the same effect of applying the given one.
- */
- public boolean isEquivalent(ThemeBundle other) {
- if (other == null) {
- return false;
- }
- if (mIsDefault) {
- return other.isDefault() || TextUtils.isEmpty(other.getSerializedPackages())
- || EMPTY_JSON.equals(other.getSerializedPackages());
- }
- // Map#equals ensures keys and values are compared.
- return mPackagesByCategory.equals(other.mPackagesByCategory);
- }
-
- public PreviewInfo getPreviewInfo() {
- return mPreviewInfo;
- }
-
- public void setOverrideThemeWallpaper(WallpaperInfo homeWallpaper) {
- mOverrideWallpaper = homeWallpaper;
- mOverrideWallpaperAsset = null;
- }
-
- private Asset getOverrideWallpaperAsset(Context context) {
- if (mOverrideWallpaperAsset == null) {
- mOverrideWallpaperAsset = new BitmapCachingAsset(context,
- mOverrideWallpaper.getThumbAsset(context));
- }
- return mOverrideWallpaperAsset;
- }
-
- boolean isDefault() {
- return mIsDefault;
- }
-
- public Map<String, String> getPackagesByCategory() {
- return mPackagesByCategory;
- }
-
- public String getSerializedPackages() {
- return getJsonPackages(false).toString();
- }
-
- public String getSerializedPackagesWithTimestamp() {
- return getJsonPackages(true).toString();
- }
-
- JSONObject getJsonPackages(boolean insertTimestamp) {
- if (isDefault()) {
- return new JSONObject();
- }
- JSONObject json = new JSONObject(mPackagesByCategory);
- // Remove items with null values to avoid deserialization issues.
- removeNullValues(json);
- if (insertTimestamp) {
- try {
- json.put(TIMESTAMP_FIELD, System.currentTimeMillis());
- } catch (JSONException e) {
- Log.e(TAG, "Couldn't add timestamp to serialized themebundle");
- }
- }
- return json;
- }
-
- private void removeNullValues(JSONObject json) {
- Iterator<String> keys = json.keys();
- Set<String> keysToRemove = new HashSet<>();
- while(keys.hasNext()) {
- String key = keys.next();
- if (json.isNull(key)) {
- keysToRemove.add(key);
- }
- }
- for (String key : keysToRemove) {
- json.remove(key);
- }
- }
-
- private Map<String, String> removeNullValues(Map<String, String> map) {
- return map.entrySet()
- .stream()
- .filter(entry -> entry.getValue() != null)
- .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
- }
-
- protected CharSequence getContentDescription(Context context) {
- if (mContentDescription == null) {
- CharSequence defaultName = context.getString(R.string.default_theme_title);
- if (isDefault()) {
- mContentDescription = defaultName;
- } else {
- PackageManager pm = context.getPackageManager();
- CharSequence fontName = getOverlayName(pm, OVERLAY_CATEGORY_FONT);
- CharSequence iconName = getOverlayName(pm, OVERLAY_CATEGORY_ICON_ANDROID);
- CharSequence shapeName = getOverlayName(pm, OVERLAY_CATEGORY_SHAPE);
- CharSequence colorName = getOverlayName(pm, OVERLAY_CATEGORY_COLOR);
- mContentDescription = context.getString(R.string.theme_description,
- TextUtils.isEmpty(fontName) ? defaultName : fontName,
- TextUtils.isEmpty(iconName) ? defaultName : iconName,
- TextUtils.isEmpty(shapeName) ? defaultName : shapeName,
- TextUtils.isEmpty(colorName) ? defaultName : colorName);
- }
- }
- return mContentDescription;
- }
-
- private CharSequence getOverlayName(PackageManager pm, String overlayCategoryFont) {
- try {
- return pm.getApplicationInfo(
- mPackagesByCategory.get(overlayCategoryFont), 0).loadLabel(pm);
- } catch (PackageManager.NameNotFoundException e) {
- return "";
- }
- }
-
- public static class PreviewInfo {
- public final Typeface bodyFontFamily;
- public final Typeface headlineFontFamily;
- @ColorInt public final int colorAccentLight;
- @ColorInt public final int colorAccentDark;
- public final List<Drawable> icons;
- public final Drawable shapeDrawable;
- public final List<ShapeAppIcon> shapeAppIcons;
- @Dimension public final int bottomSheeetCornerRadius;
-
- /** A class to represent an App icon and its name. */
- public static class ShapeAppIcon {
- private Drawable mIconDrawable;
- private CharSequence mAppName;
-
- public ShapeAppIcon(Drawable icon, CharSequence appName) {
- mIconDrawable = icon;
- mAppName = appName;
- }
-
- /** Returns a copy of app icon drawable. */
- public Drawable getDrawableCopy() {
- return mIconDrawable.getConstantState().newDrawable().mutate();
- }
-
- /** Returns the app name. */
- public CharSequence getAppName() {
- return mAppName;
- }
- }
-
- private PreviewInfo(Context context, Typeface bodyFontFamily, Typeface headlineFontFamily,
- int colorAccentLight, int colorAccentDark, List<Drawable> icons,
- Drawable shapeDrawable, @Dimension int cornerRadius,
- List<ShapeAppIcon> shapeAppIcons) {
- this.bodyFontFamily = bodyFontFamily;
- this.headlineFontFamily = headlineFontFamily;
- this.colorAccentLight = colorAccentLight;
- this.colorAccentDark = colorAccentDark;
- this.icons = icons;
- this.shapeDrawable = shapeDrawable;
- this.bottomSheeetCornerRadius = cornerRadius;
- this.shapeAppIcons = shapeAppIcons;
- }
-
- /**
- * Returns the accent color to be applied corresponding with the current configuration's
- * UI mode.
- * @return one of {@link #colorAccentDark} or {@link #colorAccentLight}
- */
- @ColorInt
- public int resolveAccentColor(Resources res) {
- return (res.getConfiguration().uiMode & Configuration.UI_MODE_NIGHT_MASK)
- == Configuration.UI_MODE_NIGHT_YES ? colorAccentDark : colorAccentLight;
- }
- }
-
- public static class Builder {
- protected String mTitle;
- private Typeface mBodyFontFamily;
- private Typeface mHeadlineFontFamily;
- @ColorInt private int mColorAccentLight = -1;
- @ColorInt private int mColorAccentDark = -1;
- private List<Drawable> mIcons = new ArrayList<>();
- private String mPathString;
- private Path mShapePath;
- private boolean mIsDefault;
- @Dimension private int mCornerRadius;
- protected Map<String, String> mPackages = new HashMap<>();
- private List<ShapeAppIcon> mAppIcons = new ArrayList<>();
-
- public ThemeBundle build(Context context) {
- return new ThemeBundle(mTitle, mPackages, mIsDefault, createPreviewInfo(context));
- }
-
- public PreviewInfo createPreviewInfo(Context context) {
- ShapeDrawable shapeDrawable = null;
- List<ShapeAppIcon> shapeIcons = new ArrayList<>();
- Path path = mShapePath;
- if (!TextUtils.isEmpty(mPathString)) {
- path = PathParser.createPathFromPathData(mPathString);
- }
- if (path != null) {
- PathShape shape = new PathShape(path, PATH_SIZE, PATH_SIZE);
- shapeDrawable = new ShapeDrawable(shape);
- shapeDrawable.setIntrinsicHeight((int) PATH_SIZE);
- shapeDrawable.setIntrinsicWidth((int) PATH_SIZE);
- for (ShapeAppIcon icon : mAppIcons) {
- Drawable drawable = icon.mIconDrawable;
- if (drawable instanceof AdaptiveIconDrawable) {
- AdaptiveIconDrawable adaptiveIcon = (AdaptiveIconDrawable) drawable;
- shapeIcons.add(new ShapeAppIcon(
- new DynamicAdaptiveIconDrawable(adaptiveIcon.getBackground(),
- adaptiveIcon.getForeground(), path),
- icon.getAppName()));
- } else if (drawable instanceof DynamicAdaptiveIconDrawable) {
- shapeIcons.add(icon);
- }
- // TODO: add iconloader library's legacy treatment helper methods for
- // non-adaptive icons
- }
- }
- return new PreviewInfo(context, mBodyFontFamily, mHeadlineFontFamily, mColorAccentLight,
- mColorAccentDark, mIcons, shapeDrawable, mCornerRadius, shapeIcons);
- }
-
- public Map<String, String> getPackages() {
- return Collections.unmodifiableMap(mPackages);
- }
-
- public String getTitle() {
- return mTitle;
- }
-
- public Builder setTitle(String title) {
- mTitle = title;
- return this;
- }
-
- public Builder setBodyFontFamily(@Nullable Typeface bodyFontFamily) {
- mBodyFontFamily = bodyFontFamily;
- return this;
- }
-
- public Builder setHeadlineFontFamily(@Nullable Typeface headlineFontFamily) {
- mHeadlineFontFamily = headlineFontFamily;
- return this;
- }
-
- public Builder setColorAccentLight(@ColorInt int colorAccentLight) {
- mColorAccentLight = colorAccentLight;
- return this;
- }
-
- public Builder setColorAccentDark(@ColorInt int colorAccentDark) {
- mColorAccentDark = colorAccentDark;
- return this;
- }
-
- public Builder addIcon(Drawable icon) {
- mIcons.add(icon);
- return this;
- }
-
- public Builder addOverlayPackage(String category, String packageName) {
- mPackages.put(category, packageName);
- return this;
- }
-
- public Builder setShapePath(String path) {
- mPathString = path;
- return this;
- }
-
- public Builder setShapePath(Path path) {
- mShapePath = path;
- return this;
- }
-
- public Builder asDefault() {
- mIsDefault = true;
- return this;
- }
-
- public Builder setShapePreviewIcons(List<ShapeAppIcon> appIcons) {
- mAppIcons.clear();
- mAppIcons.addAll(appIcons);
- return this;
- }
-
- public Builder setBottomSheetCornerRadius(@Dimension int radius) {
- mCornerRadius = radius;
- return this;
- }
- }
-}
diff --git a/src/com/android/customization/model/theme/ThemeBundleProvider.java b/src/com/android/customization/model/theme/ThemeBundleProvider.java
deleted file mode 100644
index 34342b3..0000000
--- a/src/com/android/customization/model/theme/ThemeBundleProvider.java
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
- * 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.
- */
-package com.android.customization.model.theme;
-
-import androidx.annotation.Nullable;
-
-import com.android.customization.model.CustomizationManager.OptionsFetchedListener;
-import com.android.customization.model.theme.custom.CustomTheme;
-
-import org.json.JSONException;
-
-/**
- * Interface for a class that can retrieve Themes from the system.
- */
-public interface ThemeBundleProvider {
-
- /**
- * Returns whether themes are available in the current setup.
- */
- boolean isAvailable();
-
- /**
- * Retrieve the available themes.
- * @param callback called when the themes have been retrieved (or immediately if cached)
- * @param reload whether to reload themes if they're cached.
- */
- void fetch(OptionsFetchedListener<ThemeBundle> callback, boolean reload);
-
- void storeCustomTheme(CustomTheme theme);
-
- void removeCustomTheme(CustomTheme theme);
-
- @Nullable ThemeBundle.Builder parseThemeBundle(String serializedTheme) throws JSONException;
-
- @Nullable CustomTheme.Builder parseCustomTheme(String serializedTheme) throws JSONException;
-
- ThemeBundle findEquivalent(ThemeBundle other);
-}
diff --git a/src/com/android/customization/model/theme/ThemeBundledWallpaperInfo.java b/src/com/android/customization/model/theme/ThemeBundledWallpaperInfo.java
deleted file mode 100644
index 4f0cd6c..0000000
--- a/src/com/android/customization/model/theme/ThemeBundledWallpaperInfo.java
+++ /dev/null
@@ -1,190 +0,0 @@
-/*
- * 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.
- */
-package com.android.customization.model.theme;
-
-import android.app.Activity;
-import android.content.ActivityNotFoundException;
-import android.content.Context;
-import android.content.pm.PackageManager;
-import android.content.res.Resources;
-import android.os.Parcel;
-import android.util.Log;
-
-import androidx.annotation.DrawableRes;
-import androidx.annotation.StringRes;
-
-import com.android.wallpaper.asset.Asset;
-import com.android.wallpaper.asset.ResourceAsset;
-import com.android.wallpaper.model.InlinePreviewIntentFactory;
-import com.android.wallpaper.model.WallpaperInfo;
-
-import java.util.ArrayList;
-import java.util.List;
-
-/**
- * Represents a wallpaper coming from the resources of the theme bundle container APK.
- */
-public class ThemeBundledWallpaperInfo extends WallpaperInfo {
- public static final Creator<ThemeBundledWallpaperInfo> CREATOR =
- new Creator<ThemeBundledWallpaperInfo>() {
- @Override
- public ThemeBundledWallpaperInfo createFromParcel(Parcel in) {
- return new ThemeBundledWallpaperInfo(in);
- }
-
- @Override
- public ThemeBundledWallpaperInfo[] newArray(int size) {
- return new ThemeBundledWallpaperInfo[size];
- }
- };
-
- private static final String TAG = "ThemeBundledWallpaperInfo";
-
- private final String mPackageName;
- private final String mResName;
- private final String mCollectionId;
- @DrawableRes private final int mDrawableResId;
- @StringRes private final int mTitleResId;
- @StringRes private final int mAttributionResId;
- @StringRes private final int mActionUrlResId;
- private List<String> mAttributions;
- private String mActionUrl;
- private Resources mResources;
- private Asset mAsset;
-
- /**
- * Constructs a new theme-bundled static wallpaper model object.
- *
- * @param drawableResId Resource ID of the raw wallpaper image.
- * @param resName The unique name of the wallpaper resource, e.g. "z_wp001".
- * @param themeName Unique name of the collection this wallpaper belongs in; used for logging.
- * @param titleResId Resource ID of the string for the title attribution.
- * @param attributionResId Resource ID of the string for the first subtitle attribution.
- */
- public ThemeBundledWallpaperInfo(String packageName, String resName, String themeName,
- int drawableResId, int titleResId, int attributionResId, int actionUrlResId) {
- mPackageName = packageName;
- mResName = resName;
- mCollectionId = themeName;
- mDrawableResId = drawableResId;
- mTitleResId = titleResId;
- mAttributionResId = attributionResId;
- mActionUrlResId = actionUrlResId;
- }
-
- private ThemeBundledWallpaperInfo(Parcel in) {
- super(in);
- mPackageName = in.readString();
- mResName = in.readString();
- mCollectionId = in.readString();
- mDrawableResId = in.readInt();
- mTitleResId = in.readInt();
- mAttributionResId = in.readInt();
- mActionUrlResId = in.readInt();
- }
-
- @Override
- public List<String> getAttributions(Context context) {
- if (mAttributions == null) {
- Resources res = getPackageResources(context);
- mAttributions = new ArrayList<>();
- if (mTitleResId != 0) {
- mAttributions.add(res.getString(mTitleResId));
- }
- if (mAttributionResId != 0) {
- mAttributions.add(res.getString(mAttributionResId));
- }
- }
-
- return mAttributions;
- }
-
- @Override
- public String getActionUrl(Context context) {
- if (mActionUrl == null && mActionUrlResId != 0) {
- mActionUrl = getPackageResources(context).getString(mActionUrlResId);
- }
- return mActionUrl;
- }
-
- @Override
- public Asset getAsset(Context context) {
- if (mAsset == null) {
- Resources res = getPackageResources(context);
- mAsset = new ResourceAsset(res, mDrawableResId);
- }
-
- return mAsset;
- }
-
- @Override
- public Asset getThumbAsset(Context context) {
- return getAsset(context);
- }
-
- @Override
- public void showPreview(Activity srcActivity, InlinePreviewIntentFactory factory,
- int requestCode, boolean isAssetIdPresent) {
- try {
- srcActivity.startActivityForResult(factory.newIntent(srcActivity, this,
- isAssetIdPresent), requestCode);
- } catch (ActivityNotFoundException |SecurityException e) {
- Log.e(TAG, "App isn't installed or ThemePicker doesn't have permission to launch", e);
- }
- }
-
- @Override
- public String getCollectionId(Context unused) {
- return mCollectionId;
- }
-
- @Override
- public String getWallpaperId() {
- return mResName;
- }
-
- public String getResName() {
- return mResName;
- }
-
- /**
- * Returns the {@link Resources} instance for the theme bundles stub APK.
- */
- private Resources getPackageResources(Context context) {
- if (mResources != null) {
- return mResources;
- }
-
- try {
- mResources = context.getPackageManager().getResourcesForApplication(mPackageName);
- } catch (PackageManager.NameNotFoundException e) {
- Log.e(TAG, "Could not get app resources for " + mPackageName);
- }
- return mResources;
- }
-
- @Override
- public void writeToParcel(Parcel dest, int flags) {
- super.writeToParcel(dest, flags);
- dest.writeString(mPackageName);
- dest.writeString(mResName);
- dest.writeString(mCollectionId);
- dest.writeInt(mDrawableResId);
- dest.writeInt(mTitleResId);
- dest.writeInt(mAttributionResId);
- dest.writeInt(mActionUrlResId);
- }
-}
diff --git a/src/com/android/customization/model/theme/ThemeManager.java b/src/com/android/customization/model/theme/ThemeManager.java
deleted file mode 100644
index 85241c1..0000000
--- a/src/com/android/customization/model/theme/ThemeManager.java
+++ /dev/null
@@ -1,149 +0,0 @@
-/*
- * 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.
- */
-package com.android.customization.model.theme;
-
-import static com.android.customization.model.ResourceConstants.OVERLAY_CATEGORY_COLOR;
-import static com.android.customization.model.ResourceConstants.OVERLAY_CATEGORY_FONT;
-import static com.android.customization.model.ResourceConstants.OVERLAY_CATEGORY_ICON_ANDROID;
-import static com.android.customization.model.ResourceConstants.OVERLAY_CATEGORY_ICON_LAUNCHER;
-import static com.android.customization.model.ResourceConstants.OVERLAY_CATEGORY_ICON_SETTINGS;
-import static com.android.customization.model.ResourceConstants.OVERLAY_CATEGORY_ICON_SYSUI;
-import static com.android.customization.model.ResourceConstants.OVERLAY_CATEGORY_ICON_THEMEPICKER;
-import static com.android.customization.model.ResourceConstants.OVERLAY_CATEGORY_SHAPE;
-
-import android.provider.Settings;
-import android.text.TextUtils;
-
-import androidx.annotation.Nullable;
-import androidx.fragment.app.FragmentActivity;
-
-import com.android.customization.model.CustomizationManager;
-import com.android.customization.model.ResourceConstants;
-import com.android.customization.model.theme.custom.CustomTheme;
-import com.android.customization.module.ThemesUserEventLogger;
-
-import org.json.JSONObject;
-
-import java.util.HashSet;
-import java.util.Map;
-import java.util.Set;
-
-public class ThemeManager implements CustomizationManager<ThemeBundle> {
-
- public static final Set<String> THEME_CATEGORIES = new HashSet<>();
- static {
- THEME_CATEGORIES.add(OVERLAY_CATEGORY_COLOR);
- THEME_CATEGORIES.add(OVERLAY_CATEGORY_FONT);
- THEME_CATEGORIES.add(OVERLAY_CATEGORY_SHAPE);
- THEME_CATEGORIES.add(OVERLAY_CATEGORY_ICON_ANDROID);
- THEME_CATEGORIES.add(OVERLAY_CATEGORY_ICON_SETTINGS);
- THEME_CATEGORIES.add(OVERLAY_CATEGORY_ICON_SYSUI);
- THEME_CATEGORIES.add(OVERLAY_CATEGORY_ICON_LAUNCHER);
- THEME_CATEGORIES.add(OVERLAY_CATEGORY_ICON_THEMEPICKER);
- }
-
- private final ThemeBundleProvider mProvider;
- private final OverlayManagerCompat mOverlayManagerCompat;
-
- protected final FragmentActivity mActivity;
- private final ThemesUserEventLogger mEventLogger;
-
- private Map<String, String> mCurrentOverlays;
-
- public ThemeManager(ThemeBundleProvider provider, FragmentActivity activity,
- OverlayManagerCompat overlayManagerCompat,
- ThemesUserEventLogger logger) {
- mProvider = provider;
- mActivity = activity;
- mOverlayManagerCompat = overlayManagerCompat;
- mEventLogger = logger;
- }
-
- @Override
- public boolean isAvailable() {
- return mOverlayManagerCompat.isAvailable() && mProvider.isAvailable();
- }
-
- @Override
- public void apply(ThemeBundle theme, Callback callback) {
- applyOverlays(theme, callback);
- }
-
- private void applyOverlays(ThemeBundle theme, Callback callback) {
- boolean allApplied = Settings.Secure.putString(mActivity.getContentResolver(),
- ResourceConstants.THEME_SETTING, theme.getSerializedPackagesWithTimestamp());
- if (theme instanceof CustomTheme) {
- storeCustomTheme((CustomTheme) theme);
- }
- mCurrentOverlays = null;
- if (allApplied) {
- mEventLogger.logThemeApplied(theme, theme instanceof CustomTheme);
- callback.onSuccess();
- } else {
- callback.onError(null);
- }
- }
-
- private void storeCustomTheme(CustomTheme theme) {
- mProvider.storeCustomTheme(theme);
- }
-
- @Override
- public void fetchOptions(OptionsFetchedListener<ThemeBundle> callback, boolean reload) {
- mProvider.fetch(callback, reload);
- }
-
- public Map<String, String> getCurrentOverlays() {
- if (mCurrentOverlays == null) {
- mCurrentOverlays = mOverlayManagerCompat.getEnabledOverlaysForTargets(
- ResourceConstants.getPackagesToOverlay(mActivity));
- mCurrentOverlays.entrySet().removeIf(
- categoryAndPackage -> !THEME_CATEGORIES.contains(categoryAndPackage.getKey()));
- }
- return mCurrentOverlays;
- }
-
- public String getStoredOverlays() {
- return Settings.Secure.getString(mActivity.getContentResolver(),
- ResourceConstants.THEME_SETTING);
- }
-
- public void removeCustomTheme(CustomTheme theme) {
- mProvider.removeCustomTheme(theme);
- }
-
- /**
- * @return an existing ThemeBundle that matches the same packages as the given one, if one
- * exists, or {@code null} otherwise.
- */
- @Nullable
- public ThemeBundle findThemeByPackages(ThemeBundle other) {
- return mProvider.findEquivalent(other);
- }
-
- /**
- * Store empty theme if no theme has been set yet. This will prevent Settings from showing the
- * suggestion to select a theme
- */
- public void storeEmptyTheme() {
- String themeSetting = Settings.Secure.getString(mActivity.getContentResolver(),
- ResourceConstants.THEME_SETTING);
- if (TextUtils.isEmpty(themeSetting)) {
- Settings.Secure.putString(mActivity.getContentResolver(),
- ResourceConstants.THEME_SETTING, new JSONObject().toString());
- }
- }
-}
diff --git a/src/com/android/customization/model/theme/custom/ColorOptionsProvider.java b/src/com/android/customization/model/theme/custom/ColorOptionsProvider.java
deleted file mode 100644
index f3b950b..0000000
--- a/src/com/android/customization/model/theme/custom/ColorOptionsProvider.java
+++ /dev/null
@@ -1,171 +0,0 @@
-/*
- * 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.
- */
-package com.android.customization.model.theme.custom;
-
-import static com.android.customization.model.ResourceConstants.ACCENT_COLOR_DARK_NAME;
-import static com.android.customization.model.ResourceConstants.ACCENT_COLOR_LIGHT_NAME;
-import static com.android.customization.model.ResourceConstants.ANDROID_PACKAGE;
-import static com.android.customization.model.ResourceConstants.ICONS_FOR_PREVIEW;
-import static com.android.customization.model.ResourceConstants.OVERLAY_CATEGORY_ANDROID_THEME;
-import static com.android.customization.model.ResourceConstants.OVERLAY_CATEGORY_COLOR;
-import static com.android.customization.model.ResourceConstants.OVERLAY_CATEGORY_ICON_ANDROID;
-import static com.android.customization.model.ResourceConstants.OVERLAY_CATEGORY_SHAPE;
-import static com.android.customization.model.ResourceConstants.PATH_SIZE;
-
-import android.content.Context;
-import android.content.pm.PackageManager;
-import android.content.pm.PackageManager.NameNotFoundException;
-import android.content.res.Resources;
-import android.content.res.Resources.NotFoundException;
-import android.graphics.drawable.Drawable;
-import android.graphics.drawable.ShapeDrawable;
-import android.graphics.drawable.shapes.PathShape;
-import android.os.UserHandle;
-import android.text.TextUtils;
-import android.util.Log;
-
-import androidx.core.graphics.PathParser;
-
-import com.android.customization.model.ResourceConstants;
-import com.android.customization.model.theme.OverlayManagerCompat;
-import com.android.customization.model.theme.custom.ThemeComponentOption.ColorOption;
-import com.android.wallpaper.R;
-
-import java.util.ArrayList;
-import java.util.List;
-
-/**
- * Implementation of {@link ThemeComponentOptionProvider} that reads {@link ColorOption}s from
- * icon overlays.
- */
-public class ColorOptionsProvider extends ThemeComponentOptionProvider<ColorOption> {
-
- private static final String TAG = "ColorOptionsProvider";
- private final CustomThemeManager mCustomThemeManager;
- private final String mDefaultThemePackage;
-
- public ColorOptionsProvider(Context context, OverlayManagerCompat manager,
- CustomThemeManager customThemeManager) {
- super(context, manager, OVERLAY_CATEGORY_COLOR);
- mCustomThemeManager = customThemeManager;
- // System color is set with a static overlay for android.theme category, so let's try to
- // find that first, and if that's not present, we'll default to System resources.
- // (see #addDefault())
- List<String> themePackages = manager.getOverlayPackagesForCategory(
- OVERLAY_CATEGORY_ANDROID_THEME, UserHandle.myUserId(), ANDROID_PACKAGE);
- mDefaultThemePackage = themePackages.isEmpty() ? null : themePackages.get(0);
- }
-
- @Override
- protected void loadOptions() {
- List<Drawable> previewIcons = new ArrayList<>();
- String iconPackage =
- mCustomThemeManager.getOverlayPackages().get(OVERLAY_CATEGORY_ICON_ANDROID);
- if (TextUtils.isEmpty(iconPackage)) {
- iconPackage = ANDROID_PACKAGE;
- }
- for (String iconName : ICONS_FOR_PREVIEW) {
- try {
- previewIcons.add(loadIconPreviewDrawable(iconName, iconPackage));
- } catch (NameNotFoundException | NotFoundException e) {
- Log.w(TAG, String.format("Couldn't load icon in %s for color preview, will skip it",
- iconPackage), e);
- }
- }
- String shapePackage = mCustomThemeManager.getOverlayPackages().get(OVERLAY_CATEGORY_SHAPE);
- if (TextUtils.isEmpty(shapePackage)) {
- shapePackage = ANDROID_PACKAGE;
- }
- Drawable shape = loadShape(shapePackage);
- addDefault(previewIcons, shape);
- for (String overlayPackage : mOverlayPackages) {
- try {
- Resources overlayRes = getOverlayResources(overlayPackage);
- int lightColor = overlayRes.getColor(
- overlayRes.getIdentifier(ACCENT_COLOR_LIGHT_NAME, "color", overlayPackage),
- null);
- int darkColor = overlayRes.getColor(
- overlayRes.getIdentifier(ACCENT_COLOR_DARK_NAME, "color", overlayPackage),
- null);
- PackageManager pm = mContext.getPackageManager();
- String label = pm.getApplicationInfo(overlayPackage, 0).loadLabel(pm).toString();
- ColorOption option = new ColorOption(overlayPackage, label, lightColor, darkColor);
- option.setPreviewIcons(previewIcons);
- option.setShapeDrawable(shape);
- mOptions.add(option);
- } catch (NameNotFoundException | NotFoundException e) {
- Log.w(TAG, String.format("Couldn't load color overlay %s, will skip it",
- overlayPackage), e);
- }
- }
- }
-
- private void addDefault(List<Drawable> previewIcons, Drawable shape) {
- int lightColor, darkColor;
- Resources system = Resources.getSystem();
- try {
- Resources r = getOverlayResources(mDefaultThemePackage);
- lightColor = r.getColor(
- r.getIdentifier(ACCENT_COLOR_LIGHT_NAME, "color", mDefaultThemePackage),
- null);
- darkColor = r.getColor(
- r.getIdentifier(ACCENT_COLOR_DARK_NAME, "color", mDefaultThemePackage),
- null);
- } catch (NotFoundException | NameNotFoundException e) {
- Log.d(TAG, "Didn't find default color, will use system option", e);
-
- lightColor = system.getColor(
- system.getIdentifier(ACCENT_COLOR_LIGHT_NAME, "color", ANDROID_PACKAGE), null);
-
- darkColor = system.getColor(
- system.getIdentifier(ACCENT_COLOR_DARK_NAME, "color", ANDROID_PACKAGE), null);
- }
- ColorOption option = new ColorOption(null,
- mContext.getString(R.string.default_theme_title), lightColor, darkColor);
- option.setPreviewIcons(previewIcons);
- option.setShapeDrawable(shape);
- mOptions.add(option);
- }
-
- private Drawable loadIconPreviewDrawable(String drawableName, String packageName)
- throws NameNotFoundException, NotFoundException {
-
- Resources overlayRes = getOverlayResources(packageName);
- return overlayRes.getDrawable(
- overlayRes.getIdentifier(drawableName, "drawable", packageName), null);
- }
-
- private Drawable loadShape(String packageName) {
- String path = null;
- try {
- Resources r = getOverlayResources(packageName);
-
- path = ResourceConstants.getIconMask(r, packageName);
- } catch (NameNotFoundException e) {
- Log.d(TAG, String.format("Couldn't load shape icon for %s, skipping.", packageName), e);
- }
- ShapeDrawable shapeDrawable = null;
- if (!TextUtils.isEmpty(path)) {
- PathShape shape = new PathShape(PathParser.createPathFromPathData(path),
- PATH_SIZE, PATH_SIZE);
- shapeDrawable = new ShapeDrawable(shape);
- shapeDrawable.setIntrinsicHeight((int) PATH_SIZE);
- shapeDrawable.setIntrinsicWidth((int) PATH_SIZE);
- }
- return shapeDrawable;
- }
-
-}
diff --git a/src/com/android/customization/model/theme/custom/CustomTheme.java b/src/com/android/customization/model/theme/custom/CustomTheme.java
deleted file mode 100644
index a1ee106..0000000
--- a/src/com/android/customization/model/theme/custom/CustomTheme.java
+++ /dev/null
@@ -1,106 +0,0 @@
-/*
- * 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.
- */
-package com.android.customization.model.theme.custom;
-
-import android.content.Context;
-import android.view.View;
-
-import androidx.annotation.NonNull;
-import androidx.annotation.Nullable;
-
-import com.android.customization.model.CustomizationManager;
-import com.android.customization.model.theme.ThemeBundle;
-import com.android.wallpaper.R;
-
-import java.util.Map;
-import java.util.UUID;
-
-public class CustomTheme extends ThemeBundle {
-
- public static String newId() {
- return UUID.randomUUID().toString();
- }
-
- /**
- * Used to uniquely identify a custom theme since names can change.
- */
- private final String mId;
-
- private CustomTheme(@NonNull String id, String title, Map<String, String> overlayPackages,
- @Nullable PreviewInfo previewInfo) {
- super(title, overlayPackages, false, previewInfo);
- mId = id;
- }
-
- public String getId() {
- return mId;
- }
-
- @Override
- public boolean equals(Object obj) {
- if (!(obj instanceof CustomTheme)) {
- return false;
- }
- CustomTheme other = (CustomTheme) obj;
- return mId.equals(other.mId);
- }
-
- @Override
- public int hashCode() {
- return mId.hashCode();
- }
-
- @Override
- public void bindThumbnailTile(View view) {
- if (isDefined()) {
- super.bindThumbnailTile(view);
- }
- }
-
- @Override
- public int getLayoutResId() {
- return isDefined() ? R.layout.theme_option : R.layout.custom_theme_option;
- }
-
- @Override
- public boolean isActive(CustomizationManager<ThemeBundle> manager) {
- return isDefined() && super.isActive(manager);
- }
-
- @Override
- public boolean isEquivalent(ThemeBundle other) {
- return isDefined() && super.isEquivalent(other);
- }
-
- public boolean isDefined() {
- return getPreviewInfo() != null;
- }
-
- public static class Builder extends ThemeBundle.Builder {
- private String mId;
-
- @Override
- public CustomTheme build(Context context) {
- return new CustomTheme(mId, mTitle, mPackages,
- mPackages.isEmpty() ? null : createPreviewInfo(context));
- }
-
- public Builder setId(String id) {
- mId = id;
- return this;
- }
- }
-}
diff --git a/src/com/android/customization/model/theme/custom/CustomThemeManager.java b/src/com/android/customization/model/theme/custom/CustomThemeManager.java
deleted file mode 100644
index 42d73e6..0000000
--- a/src/com/android/customization/model/theme/custom/CustomThemeManager.java
+++ /dev/null
@@ -1,116 +0,0 @@
-/*
- * 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.
- */
-package com.android.customization.model.theme.custom;
-
-import android.content.Context;
-import android.os.Bundle;
-import android.text.TextUtils;
-import android.util.Log;
-
-import androidx.annotation.Nullable;
-
-import com.android.customization.model.CustomizationManager;
-import com.android.customization.model.theme.ThemeBundle.PreviewInfo;
-import com.android.customization.model.theme.ThemeBundleProvider;
-import com.android.customization.model.theme.ThemeManager;
-import com.android.customization.model.theme.custom.CustomTheme.Builder;
-
-import org.json.JSONException;
-
-import java.util.Map;
-
-public class CustomThemeManager implements CustomizationManager<ThemeComponentOption> {
-
- private static final String TAG = "CustomThemeManager";
- private static final String KEY_STATE_CURRENT_SELECTION = "CustomThemeManager.currentSelection";
-
- private final CustomTheme mOriginalTheme;
- private CustomTheme.Builder mBuilder;
-
- private CustomThemeManager(Map<String, String> overlayPackages,
- @Nullable CustomTheme originalTheme) {
- mBuilder = new Builder();
- overlayPackages.forEach(mBuilder::addOverlayPackage);
- mOriginalTheme = originalTheme;
- }
-
- @Override
- public boolean isAvailable() {
- return true;
- }
-
- @Override
- public void apply(ThemeComponentOption option, @Nullable Callback callback) {
- option.buildStep(mBuilder);
- if (callback != null) {
- callback.onSuccess();
- }
- }
-
- public Map<String, String> getOverlayPackages() {
- return mBuilder.getPackages();
- }
-
- public CustomTheme buildPartialCustomTheme(Context context, String id, String title) {
- return ((CustomTheme.Builder)mBuilder.setId(id).setTitle(title)).build(context);
- }
-
- @Override
- public void fetchOptions(OptionsFetchedListener<ThemeComponentOption> callback, boolean reload) {
- //Unused
- }
-
- public CustomTheme getOriginalTheme() {
- return mOriginalTheme;
- }
-
- public PreviewInfo buildCustomThemePreviewInfo(Context context) {
- return mBuilder.createPreviewInfo(context);
- }
-
- /** Saves the custom theme selections while system config changes. */
- public void saveCustomTheme(Context context, Bundle savedInstanceState) {
- CustomTheme customTheme =
- buildPartialCustomTheme(context, /* id= */ null, /* title= */ null);
- savedInstanceState.putString(KEY_STATE_CURRENT_SELECTION,
- customTheme.getSerializedPackages());
- }
-
- /** Reads the saved custom theme after system config changed. */
- public void readCustomTheme(ThemeBundleProvider themeBundleProvider,
- Bundle savedInstanceState) {
- String packages = savedInstanceState.getString(KEY_STATE_CURRENT_SELECTION);
- if (!TextUtils.isEmpty(packages)) {
- try {
- mBuilder = themeBundleProvider.parseCustomTheme(packages);
- } catch (JSONException e) {
- Log.w(TAG, "Couldn't parse provided custom theme.");
- }
- } else {
- Log.w(TAG, "No custom theme being restored.");
- }
- }
-
- public static CustomThemeManager create(
- @Nullable CustomTheme customTheme, ThemeManager themeManager) {
- if (customTheme != null && customTheme.isDefined()) {
- return new CustomThemeManager(customTheme.getPackagesByCategory(), customTheme);
- }
- // Seed the first custom theme with the currently applied theme.
- return new CustomThemeManager(themeManager.getCurrentOverlays(), customTheme);
- }
-
-}
diff --git a/src/com/android/customization/model/theme/custom/FontOptionsProvider.java b/src/com/android/customization/model/theme/custom/FontOptionsProvider.java
deleted file mode 100644
index 53568c9..0000000
--- a/src/com/android/customization/model/theme/custom/FontOptionsProvider.java
+++ /dev/null
@@ -1,86 +0,0 @@
-/*
- * 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.
- */
-package com.android.customization.model.theme.custom;
-
-import static com.android.customization.model.ResourceConstants.ANDROID_PACKAGE;
-import static com.android.customization.model.ResourceConstants.CONFIG_BODY_FONT_FAMILY;
-import static com.android.customization.model.ResourceConstants.CONFIG_HEADLINE_FONT_FAMILY;
-import static com.android.customization.model.ResourceConstants.OVERLAY_CATEGORY_FONT;
-
-import android.content.Context;
-import android.content.pm.PackageManager;
-import android.content.pm.PackageManager.NameNotFoundException;
-import android.content.res.Resources;
-import android.content.res.Resources.NotFoundException;
-import android.graphics.Typeface;
-import android.util.Log;
-
-import com.android.customization.model.ResourceConstants;
-import com.android.customization.model.theme.OverlayManagerCompat;
-import com.android.customization.model.theme.custom.ThemeComponentOption.FontOption;
-import com.android.wallpaper.R;
-
-/**
- * Implementation of {@link ThemeComponentOptionProvider} that reads {@link FontOption}s from
- * font overlays.
- */
-public class FontOptionsProvider extends ThemeComponentOptionProvider<FontOption> {
-
- private static final String TAG = "FontOptionsProvider";
-
- public FontOptionsProvider(Context context, OverlayManagerCompat manager) {
- super(context, manager, OVERLAY_CATEGORY_FONT);
- }
-
- @Override
- protected void loadOptions() {
- addDefault();
- for (String overlayPackage : mOverlayPackages) {
- try {
- Resources overlayRes = getOverlayResources(overlayPackage);
- Typeface headlineFont = Typeface.create(
- getFontFamily(overlayPackage, overlayRes, CONFIG_HEADLINE_FONT_FAMILY),
- Typeface.NORMAL);
- Typeface bodyFont = Typeface.create(
- getFontFamily(overlayPackage, overlayRes, CONFIG_BODY_FONT_FAMILY),
- Typeface.NORMAL);
- PackageManager pm = mContext.getPackageManager();
- String label = pm.getApplicationInfo(overlayPackage, 0).loadLabel(pm).toString();
- mOptions.add(new FontOption(overlayPackage, label, headlineFont, bodyFont));
- } catch (NameNotFoundException | NotFoundException e) {
- Log.w(TAG, String.format("Couldn't load font overlay %s, will skip it",
- overlayPackage), e);
- }
- }
- }
-
- private void addDefault() {
- Resources system = Resources.getSystem();
- Typeface headlineFont = Typeface.create(system.getString(system.getIdentifier(
- ResourceConstants.CONFIG_HEADLINE_FONT_FAMILY,"string", ANDROID_PACKAGE)),
- Typeface.NORMAL);
- Typeface bodyFont = Typeface.create(system.getString(system.getIdentifier(
- ResourceConstants.CONFIG_BODY_FONT_FAMILY,
- "string", ANDROID_PACKAGE)),
- Typeface.NORMAL);
- mOptions.add(new FontOption(null, mContext.getString(R.string.default_theme_title),
- headlineFont, bodyFont));
- }
-
- private String getFontFamily(String overlayPackage, Resources overlayRes, String configName) {
- return overlayRes.getString(overlayRes.getIdentifier(configName, "string", overlayPackage));
- }
-}
diff --git a/src/com/android/customization/model/theme/custom/IconOptionsProvider.java b/src/com/android/customization/model/theme/custom/IconOptionsProvider.java
deleted file mode 100644
index f7b669b..0000000
--- a/src/com/android/customization/model/theme/custom/IconOptionsProvider.java
+++ /dev/null
@@ -1,153 +0,0 @@
-/*
- * 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.
- */
-package com.android.customization.model.theme.custom;
-
-import static com.android.customization.model.ResourceConstants.ANDROID_PACKAGE;
-import static com.android.customization.model.ResourceConstants.ICONS_FOR_PREVIEW;
-import static com.android.customization.model.ResourceConstants.OVERLAY_CATEGORY_ICON_ANDROID;
-import static com.android.customization.model.ResourceConstants.OVERLAY_CATEGORY_ICON_LAUNCHER;
-import static com.android.customization.model.ResourceConstants.OVERLAY_CATEGORY_ICON_SETTINGS;
-import static com.android.customization.model.ResourceConstants.OVERLAY_CATEGORY_ICON_SYSUI;
-import static com.android.customization.model.ResourceConstants.OVERLAY_CATEGORY_ICON_THEMEPICKER;
-
-import android.content.Context;
-import android.content.pm.PackageManager.NameNotFoundException;
-import android.content.res.Resources;
-import android.content.res.Resources.NotFoundException;
-import android.graphics.drawable.Drawable;
-import android.os.UserHandle;
-import android.util.Log;
-
-import com.android.customization.model.ResourceConstants;
-import com.android.customization.model.theme.OverlayManagerCompat;
-import com.android.customization.model.theme.custom.ThemeComponentOption.IconOption;
-import com.android.wallpaper.R;
-
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-/**
- * Implementation of {@link ThemeComponentOptionProvider} that reads {@link IconOption}s from
- * icon overlays.
- */
-public class IconOptionsProvider extends ThemeComponentOptionProvider<IconOption> {
-
- private static final String TAG = "IconOptionsProvider";
-
- private final List<String> mSysUiIconsOverlayPackages = new ArrayList<>();
- private final List<String> mSettingsIconsOverlayPackages = new ArrayList<>();
- private final List<String> mLauncherIconsOverlayPackages = new ArrayList<>();
- private final List<String> mThemePickerIconsOverlayPackages = new ArrayList<>();
-
- public IconOptionsProvider(Context context, OverlayManagerCompat manager) {
- super(context, manager, OVERLAY_CATEGORY_ICON_ANDROID);
- String[] targetPackages = ResourceConstants.getPackagesToOverlay(context);
- mSysUiIconsOverlayPackages.addAll(manager.getOverlayPackagesForCategory(
- OVERLAY_CATEGORY_ICON_SYSUI, UserHandle.myUserId(), targetPackages));
- mSettingsIconsOverlayPackages.addAll(manager.getOverlayPackagesForCategory(
- OVERLAY_CATEGORY_ICON_SETTINGS, UserHandle.myUserId(), targetPackages));
- mLauncherIconsOverlayPackages.addAll(manager.getOverlayPackagesForCategory(
- OVERLAY_CATEGORY_ICON_LAUNCHER, UserHandle.myUserId(), targetPackages));
- mThemePickerIconsOverlayPackages.addAll(manager.getOverlayPackagesForCategory(
- OVERLAY_CATEGORY_ICON_THEMEPICKER, UserHandle.myUserId(), targetPackages));
- }
-
- @Override
- protected void loadOptions() {
- addDefault();
-
- Map<String, IconOption> optionsByPrefix = new HashMap<>();
- for (String overlayPackage : mOverlayPackages) {
- IconOption option = addOrUpdateOption(optionsByPrefix, overlayPackage,
- OVERLAY_CATEGORY_ICON_ANDROID);
- try{
- for (String iconName : ICONS_FOR_PREVIEW) {
- option.addIcon(loadIconPreviewDrawable(iconName, overlayPackage));
- }
- } catch (NotFoundException | NameNotFoundException e) {
- Log.w(TAG, String.format("Couldn't load icon overlay details for %s, will skip it",
- overlayPackage), e);
- }
- }
-
- for (String overlayPackage : mSysUiIconsOverlayPackages) {
- addOrUpdateOption(optionsByPrefix, overlayPackage, OVERLAY_CATEGORY_ICON_SYSUI);
- }
-
- for (String overlayPackage : mSettingsIconsOverlayPackages) {
- addOrUpdateOption(optionsByPrefix, overlayPackage, OVERLAY_CATEGORY_ICON_SETTINGS);
- }
-
- for (String overlayPackage : mLauncherIconsOverlayPackages) {
- addOrUpdateOption(optionsByPrefix, overlayPackage, OVERLAY_CATEGORY_ICON_LAUNCHER);
- }
-
- for (String overlayPackage : mThemePickerIconsOverlayPackages) {
- addOrUpdateOption(optionsByPrefix, overlayPackage, OVERLAY_CATEGORY_ICON_THEMEPICKER);
- }
-
- for (IconOption option : optionsByPrefix.values()) {
- if (option.isValid(mContext)) {
- mOptions.add(option);
- option.setLabel(mContext.getString(R.string.icon_component_label, mOptions.size()));
- }
- }
- }
-
- private IconOption addOrUpdateOption(Map<String, IconOption> optionsByPrefix,
- String overlayPackage, String category) {
- String prefix = overlayPackage.substring(0, overlayPackage.lastIndexOf("."));
- IconOption option;
- if (!optionsByPrefix.containsKey(prefix)) {
- option = new IconOption();
- optionsByPrefix.put(prefix, option);
- } else {
- option = optionsByPrefix.get(prefix);
- }
- option.addOverlayPackage(category, overlayPackage);
- return option;
- }
-
- private Drawable loadIconPreviewDrawable(String drawableName, String packageName)
- throws NameNotFoundException, NotFoundException {
- final Resources resources = ANDROID_PACKAGE.equals(packageName)
- ? Resources.getSystem()
- : mContext.getPackageManager().getResourcesForApplication(packageName);
- return resources.getDrawable(
- resources.getIdentifier(drawableName, "drawable", packageName), null);
- }
-
- private void addDefault() {
- IconOption option = new IconOption();
- option.setLabel(mContext.getString(R.string.default_theme_title));
- try {
- for (String iconName : ICONS_FOR_PREVIEW) {
- option.addIcon(loadIconPreviewDrawable(iconName, ANDROID_PACKAGE));
- }
- } catch (NameNotFoundException | NotFoundException e) {
- Log.w(TAG, "Didn't find SystemUi package icons, will skip option", e);
- }
- option.addOverlayPackage(OVERLAY_CATEGORY_ICON_ANDROID, null);
- option.addOverlayPackage(OVERLAY_CATEGORY_ICON_SYSUI, null);
- option.addOverlayPackage(OVERLAY_CATEGORY_ICON_SETTINGS, null);
- option.addOverlayPackage(OVERLAY_CATEGORY_ICON_LAUNCHER, null);
- option.addOverlayPackage(OVERLAY_CATEGORY_ICON_THEMEPICKER, null);
- mOptions.add(option);
- }
-
-}
diff --git a/src/com/android/customization/model/theme/custom/ShapeOptionsProvider.java b/src/com/android/customization/model/theme/custom/ShapeOptionsProvider.java
deleted file mode 100644
index f93b892..0000000
--- a/src/com/android/customization/model/theme/custom/ShapeOptionsProvider.java
+++ /dev/null
@@ -1,154 +0,0 @@
-/*
- * 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.
- */
-package com.android.customization.model.theme.custom;
-
-import static com.android.customization.model.ResourceConstants.ANDROID_PACKAGE;
-import static com.android.customization.model.ResourceConstants.CONFIG_CORNERRADIUS;
-import static com.android.customization.model.ResourceConstants.CONFIG_ICON_MASK;
-import static com.android.customization.model.ResourceConstants.OVERLAY_CATEGORY_SHAPE;
-import static com.android.customization.model.ResourceConstants.PATH_SIZE;
-
-import android.content.Context;
-import android.content.pm.ApplicationInfo;
-import android.content.pm.PackageManager;
-import android.content.pm.PackageManager.NameNotFoundException;
-import android.content.res.Resources;
-import android.content.res.Resources.NotFoundException;
-import android.graphics.Path;
-import android.graphics.drawable.AdaptiveIconDrawable;
-import android.graphics.drawable.Drawable;
-import android.graphics.drawable.ShapeDrawable;
-import android.graphics.drawable.shapes.PathShape;
-import android.text.TextUtils;
-import android.util.Log;
-
-import androidx.annotation.Dimension;
-import androidx.core.graphics.PathParser;
-
-import com.android.customization.model.ResourceConstants;
-import com.android.customization.model.theme.OverlayManagerCompat;
-import com.android.customization.model.theme.ThemeBundle.PreviewInfo.ShapeAppIcon;
-import com.android.customization.model.theme.custom.ThemeComponentOption.ShapeOption;
-import com.android.customization.widget.DynamicAdaptiveIconDrawable;
-import com.android.wallpaper.R;
-
-import java.util.ArrayList;
-import java.util.List;
-
-/**
- * Implementation of {@link ThemeComponentOptionProvider} that reads {@link ShapeOption}s from
- * icon overlays.
- */
-public class ShapeOptionsProvider extends ThemeComponentOptionProvider<ShapeOption> {
-
- private static final String TAG = "ShapeOptionsProvider";
- private final String[] mShapePreviewIconPackages;
- private int mThumbSize;
-
- public ShapeOptionsProvider(Context context, OverlayManagerCompat manager) {
- super(context, manager, OVERLAY_CATEGORY_SHAPE);
- mShapePreviewIconPackages = context.getResources().getStringArray(
- R.array.icon_shape_preview_packages);
- mThumbSize = mContext.getResources().getDimensionPixelSize(
- R.dimen.component_shape_thumb_size);
- }
-
- @Override
- protected void loadOptions() {
- addDefault();
- for (String overlayPackage : mOverlayPackages) {
- try {
- Path path = loadPath(mContext.getPackageManager()
- .getResourcesForApplication(overlayPackage), overlayPackage);
- PackageManager pm = mContext.getPackageManager();
- String label = pm.getApplicationInfo(overlayPackage, 0).loadLabel(pm).toString();
- mOptions.add(new ShapeOption(overlayPackage, label, path,
- loadCornerRadius(overlayPackage), createShapeDrawable(path),
- getShapedAppIcons(path)));
- } catch (NameNotFoundException | NotFoundException e) {
- Log.w(TAG, String.format("Couldn't load shape overlay %s, will skip it",
- overlayPackage), e);
- }
- }
- }
-
- private void addDefault() {
- Resources system = Resources.getSystem();
- Path path = loadPath(system, ANDROID_PACKAGE);
- mOptions.add(new ShapeOption(null, mContext.getString(R.string.default_theme_title), path,
- system.getDimensionPixelOffset(
- system.getIdentifier(ResourceConstants.CONFIG_CORNERRADIUS,
- "dimen", ResourceConstants.ANDROID_PACKAGE)),
- createShapeDrawable(path), getShapedAppIcons(path)));
- }
-
- private ShapeDrawable createShapeDrawable(Path path) {
- PathShape shape = new PathShape(path, PATH_SIZE, PATH_SIZE);
- ShapeDrawable shapeDrawable = new ShapeDrawable(shape);
- shapeDrawable.setIntrinsicHeight(mThumbSize);
- shapeDrawable.setIntrinsicWidth(mThumbSize);
- return shapeDrawable;
- }
-
- private List<ShapeAppIcon> getShapedAppIcons(Path path) {
- List<ShapeAppIcon> shapedAppIcons = new ArrayList<>();
- for (String packageName : mShapePreviewIconPackages) {
- Drawable icon = null;
- CharSequence name = null;
- try {
- Drawable appIcon = mContext.getPackageManager().getApplicationIcon(packageName);
- if (appIcon instanceof AdaptiveIconDrawable) {
- AdaptiveIconDrawable adaptiveIcon = (AdaptiveIconDrawable) appIcon;
- icon = new DynamicAdaptiveIconDrawable(adaptiveIcon.getBackground(),
- adaptiveIcon.getForeground(), path);
-
- ApplicationInfo appInfo = mContext.getPackageManager()
- .getApplicationInfo(packageName, /* flag= */ 0);
- name = mContext.getPackageManager().getApplicationLabel(appInfo);
- }
- } catch (NameNotFoundException e) {
- Log.d(TAG, "Couldn't find app " + packageName
- + ", won't use it for icon shape preview");
- } finally {
- if (icon != null && !TextUtils.isEmpty(name)) {
- shapedAppIcons.add(new ShapeAppIcon(icon, name));
- }
- }
- }
- return shapedAppIcons;
- }
-
- private Path loadPath(Resources overlayRes, String packageName) {
- String shape = overlayRes.getString(overlayRes.getIdentifier(CONFIG_ICON_MASK, "string",
- packageName));
-
- if (!TextUtils.isEmpty(shape)) {
- return PathParser.createPathFromPathData(shape);
- }
- return null;
- }
-
- @Dimension
- private int loadCornerRadius(String packageName)
- throws NameNotFoundException, NotFoundException {
-
- Resources overlayRes =
- mContext.getPackageManager().getResourcesForApplication(
- packageName);
- return overlayRes.getDimensionPixelOffset(overlayRes.getIdentifier(
- CONFIG_CORNERRADIUS, "dimen", packageName));
- }
-}
diff --git a/src/com/android/customization/model/theme/custom/ThemeComponentOption.java b/src/com/android/customization/model/theme/custom/ThemeComponentOption.java
deleted file mode 100644
index 78be0fc..0000000
--- a/src/com/android/customization/model/theme/custom/ThemeComponentOption.java
+++ /dev/null
@@ -1,556 +0,0 @@
-/*
- * 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.
- */
-package com.android.customization.model.theme.custom;
-
-import static com.android.customization.model.ResourceConstants.OVERLAY_CATEGORY_COLOR;
-import static com.android.customization.model.ResourceConstants.OVERLAY_CATEGORY_FONT;
-import static com.android.customization.model.ResourceConstants.OVERLAY_CATEGORY_ICON_ANDROID;
-import static com.android.customization.model.ResourceConstants.OVERLAY_CATEGORY_ICON_LAUNCHER;
-import static com.android.customization.model.ResourceConstants.OVERLAY_CATEGORY_ICON_SETTINGS;
-import static com.android.customization.model.ResourceConstants.OVERLAY_CATEGORY_ICON_SYSUI;
-import static com.android.customization.model.ResourceConstants.OVERLAY_CATEGORY_ICON_THEMEPICKER;
-import static com.android.customization.model.ResourceConstants.OVERLAY_CATEGORY_SHAPE;
-import static com.android.customization.model.ResourceConstants.getLauncherPackage;
-
-import android.content.Context;
-import android.content.pm.PackageManager.NameNotFoundException;
-import android.content.res.ColorStateList;
-import android.content.res.Configuration;
-import android.content.res.Resources;
-import android.content.res.Resources.NotFoundException;
-import android.content.res.Resources.Theme;
-import android.content.res.TypedArray;
-import android.graphics.Path;
-import android.graphics.Typeface;
-import android.graphics.drawable.Drawable;
-import android.graphics.drawable.LayerDrawable;
-import android.graphics.drawable.ShapeDrawable;
-import android.graphics.drawable.StateListDrawable;
-import android.text.TextUtils;
-import android.view.Gravity;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.view.ViewGroup;
-import android.widget.CompoundButton;
-import android.widget.ImageView;
-import android.widget.SeekBar;
-import android.widget.Switch;
-import android.widget.TextView;
-
-import androidx.annotation.ColorInt;
-import androidx.annotation.Dimension;
-import androidx.annotation.DrawableRes;
-import androidx.annotation.Nullable;
-import androidx.annotation.StringRes;
-import androidx.core.graphics.ColorUtils;
-
-import com.android.customization.model.CustomizationManager;
-import com.android.customization.model.CustomizationOption;
-import com.android.customization.model.ResourceConstants;
-import com.android.customization.model.theme.ThemeBundle.PreviewInfo.ShapeAppIcon;
-import com.android.customization.model.theme.custom.CustomTheme.Builder;
-import com.android.wallpaper.R;
-import com.android.wallpaper.util.ResourceUtils;
-
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Objects;
-
-/**
- * Represents an option of a component of a custom Theme (for example, a possible color, or font,
- * shape, etc).
- * Extending classes correspond to each component's options and provide the structure to bind
- * preview and thumbnails.
- * // TODO (santie): refactor the logic to bind preview cards to reuse between ThemeFragment and
- * // here
- */
-public abstract class ThemeComponentOption implements CustomizationOption<ThemeComponentOption> {
-
- protected final Map<String, String> mOverlayPackageNames = new HashMap<>();
-
- protected void addOverlayPackage(String category, String packageName) {
- mOverlayPackageNames.put(category, packageName);
- }
-
- public Map<String, String> getOverlayPackages() {
- return mOverlayPackageNames;
- }
-
- @Override
- public String getTitle() {
- return null;
- }
-
- public abstract void bindPreview(ViewGroup container);
-
- public Builder buildStep(Builder builder) {
- getOverlayPackages().forEach(builder::addOverlayPackage);
- return builder;
- }
-
- public static class FontOption extends ThemeComponentOption {
-
- private final String mLabel;
- private final Typeface mHeadlineFont;
- private final Typeface mBodyFont;
-
- public FontOption(String packageName, String label, Typeface headlineFont,
- Typeface bodyFont) {
- addOverlayPackage(OVERLAY_CATEGORY_FONT, packageName);
- mLabel = label;
- mHeadlineFont = headlineFont;
- mBodyFont = bodyFont;
- }
-
- @Override
- public String getTitle() {
- return null;
- }
-
- @Override
- public void bindThumbnailTile(View view) {
- ((TextView) view.findViewById(R.id.thumbnail_text)).setTypeface(
- mHeadlineFont);
- view.setContentDescription(mLabel);
- }
-
- @Override
- public boolean isActive(CustomizationManager<ThemeComponentOption> manager) {
- CustomThemeManager customThemeManager = (CustomThemeManager) manager;
- return Objects.equals(getOverlayPackages().get(OVERLAY_CATEGORY_FONT),
- customThemeManager.getOverlayPackages().get(OVERLAY_CATEGORY_FONT));
- }
-
- @Override
- public int getLayoutResId() {
- return R.layout.theme_font_option;
- }
-
- @Override
- public void bindPreview(ViewGroup container) {
- container.setContentDescription(
- container.getContext().getString(R.string.font_preview_content_description));
-
- bindPreviewHeader(container, R.string.preview_name_font, R.drawable.ic_font, null);
-
- ViewGroup cardBody = container.findViewById(R.id.theme_preview_card_body_container);
- if (cardBody.getChildCount() == 0) {
- LayoutInflater.from(container.getContext()).inflate(
- R.layout.preview_card_font_content,
- cardBody, true);
- }
- TextView title = container.findViewById(R.id.font_card_title);
- title.setTypeface(mHeadlineFont);
- TextView bodyText = container.findViewById(R.id.font_card_body);
- bodyText.setTypeface(mBodyFont);
- container.findViewById(R.id.font_card_divider).setBackgroundColor(
- title.getCurrentTextColor());
- }
-
- @Override
- public Builder buildStep(Builder builder) {
- builder.setHeadlineFontFamily(mHeadlineFont).setBodyFontFamily(mBodyFont);
- return super.buildStep(builder);
- }
- }
-
- void bindPreviewHeader(ViewGroup container, @StringRes int headerTextResId,
- @DrawableRes int headerIcon, String drawableName) {
- TextView header = container.findViewById(R.id.theme_preview_card_header);
- header.setText(headerTextResId);
-
- Context context = container.getContext();
- Drawable icon;
- if (!TextUtils.isEmpty(drawableName)) {
- try {
- Resources resources = context.getPackageManager()
- .getResourcesForApplication(getLauncherPackage(context));
- icon = resources.getDrawable(resources.getIdentifier(
- drawableName, "drawable", getLauncherPackage(context)), null);
- } catch (NameNotFoundException | NotFoundException e) {
- icon = context.getResources().getDrawable(headerIcon, context.getTheme());
- }
- } else {
- icon = context.getResources().getDrawable(headerIcon, context.getTheme());
- }
- int size = context.getResources().getDimensionPixelSize(R.dimen.card_header_icon_size);
- icon.setBounds(0, 0, size, size);
-
- header.setCompoundDrawables(null, icon, null, null);
- header.setCompoundDrawableTintList(ColorStateList.valueOf(
- header.getCurrentTextColor()));
- }
-
- public static class IconOption extends ThemeComponentOption {
-
- public static final int THUMBNAIL_ICON_POSITION = 0;
- private static int[] mIconIds = {
- R.id.preview_icon_0, R.id.preview_icon_1, R.id.preview_icon_2, R.id.preview_icon_3,
- R.id.preview_icon_4, R.id.preview_icon_5
- };
-
- private List<Drawable> mIcons = new ArrayList<>();
- private String mLabel;
-
- @Override
- public void bindThumbnailTile(View view) {
- Resources res = view.getContext().getResources();
- Drawable icon = mIcons.get(THUMBNAIL_ICON_POSITION)
- .getConstantState().newDrawable().mutate();
- icon.setTint(ResourceUtils.getColorAttr(
- view.getContext(), android.R.attr.textColorSecondary));
- ((ImageView) view.findViewById(R.id.option_icon)).setImageDrawable(
- icon);
- view.setContentDescription(mLabel);
- }
-
- @Override
- public boolean isActive(CustomizationManager<ThemeComponentOption> manager) {
- CustomThemeManager customThemeManager = (CustomThemeManager) manager;
- Map<String, String> themePackages = customThemeManager.getOverlayPackages();
- if (getOverlayPackages().isEmpty()) {
- return themePackages.get(OVERLAY_CATEGORY_ICON_SYSUI) == null &&
- themePackages.get(OVERLAY_CATEGORY_ICON_SETTINGS) == null &&
- themePackages.get(OVERLAY_CATEGORY_ICON_ANDROID) == null &&
- themePackages.get(OVERLAY_CATEGORY_ICON_LAUNCHER) == null &&
- themePackages.get(OVERLAY_CATEGORY_ICON_THEMEPICKER) == null;
- }
- for (Map.Entry<String, String> overlayEntry : getOverlayPackages().entrySet()) {
- if(!Objects.equals(overlayEntry.getValue(),
- themePackages.get(overlayEntry.getKey()))) {
- return false;
- }
- }
- return true;
- }
-
- @Override
- public int getLayoutResId() {
- return R.layout.theme_icon_option;
- }
-
- @Override
- public void bindPreview(ViewGroup container) {
- container.setContentDescription(
- container.getContext().getString(R.string.icon_preview_content_description));
-
- bindPreviewHeader(container, R.string.preview_name_icon, R.drawable.ic_widget,
- "ic_widget");
-
- ViewGroup cardBody = container.findViewById(R.id.theme_preview_card_body_container);
- if (cardBody.getChildCount() == 0) {
- LayoutInflater.from(container.getContext()).inflate(
- R.layout.preview_card_icon_content, cardBody, true);
- }
- for (int i = 0; i < mIconIds.length && i < mIcons.size(); i++) {
- ((ImageView) container.findViewById(mIconIds[i])).setImageDrawable(
- mIcons.get(i));
- }
- }
-
- public void addIcon(Drawable previewIcon) {
- mIcons.add(previewIcon);
- }
-
- /**
- * @return whether this icon option has overlays and previews for all the required packages
- */
- public boolean isValid(Context context) {
- return getOverlayPackages().keySet().size() ==
- ResourceConstants.getPackagesToOverlay(context).length;
- }
-
- public void setLabel(String label) {
- mLabel = label;
- }
-
- @Override
- public Builder buildStep(Builder builder) {
- for (Drawable icon : mIcons) {
- builder.addIcon(icon);
- }
- return super.buildStep(builder);
- }
- }
-
- public static class ColorOption extends ThemeComponentOption {
-
- /**
- * Ids of views used to represent quick setting tiles in the color preview screen
- */
- private static int[] COLOR_TILE_IDS = {
- R.id.preview_color_qs_0_bg, R.id.preview_color_qs_1_bg, R.id.preview_color_qs_2_bg
- };
-
- /**
- * Ids of the views for the foreground of the icon, mapping to the corresponding index of
- * the actual icon drawable.
- */
- static int[][] COLOR_TILES_ICON_IDS = {
- new int[]{ R.id.preview_color_qs_0_icon, 0},
- new int[]{ R.id.preview_color_qs_1_icon, 1},
- new int[] { R.id.preview_color_qs_2_icon, 3}
- };
-
- /**
- * Ids of views used to represent control buttons in the color preview screen
- */
- private static int[] COLOR_BUTTON_IDS = {
- R.id.preview_check_selected, R.id.preview_radio_selected,
- R.id.preview_toggle_selected
- };
-
- @ColorInt private int mColorAccentLight;
- @ColorInt private int mColorAccentDark;
- /**
- * Icons shown as example of QuickSettings tiles in the color preview screen.
- */
- private List<Drawable> mIcons = new ArrayList<>();
-
- /**
- * Drawable with the currently selected shape to be used as background of the sample
- * QuickSetting icons in the color preview screen.
- */
- private Drawable mShapeDrawable;
-
- private String mLabel;
-
- ColorOption(String packageName, String label, @ColorInt int lightColor,
- @ColorInt int darkColor) {
- addOverlayPackage(OVERLAY_CATEGORY_COLOR, packageName);
- mLabel = label;
- mColorAccentLight = lightColor;
- mColorAccentDark = darkColor;
- }
-
- @Override
- public void bindThumbnailTile(View view) {
- @ColorInt int color = resolveColor(view.getResources());
- LayerDrawable selectedOption = (LayerDrawable) view.getResources().getDrawable(
- R.drawable.color_chip_hollow, view.getContext().getTheme());
- Drawable unselectedOption = view.getResources().getDrawable(
- R.drawable.color_chip_filled, view.getContext().getTheme());
-
- selectedOption.findDrawableByLayerId(R.id.center_fill).setTintList(
- ColorStateList.valueOf(color));
- unselectedOption.setTintList(ColorStateList.valueOf(color));
-
- StateListDrawable stateListDrawable = new StateListDrawable();
- stateListDrawable.addState(new int[] {android.R.attr.state_activated}, selectedOption);
- stateListDrawable.addState(
- new int[] {-android.R.attr.state_activated}, unselectedOption);
-
- ((ImageView) view.findViewById(R.id.option_tile)).setImageDrawable(stateListDrawable);
- view.setContentDescription(mLabel);
- }
-
- @ColorInt
- private int resolveColor(Resources res) {
- Configuration configuration = res.getConfiguration();
- return (configuration.uiMode & Configuration.UI_MODE_NIGHT_MASK)
- == Configuration.UI_MODE_NIGHT_YES ? mColorAccentDark : mColorAccentLight;
- }
-
- @Override
- public boolean isActive(CustomizationManager<ThemeComponentOption> manager) {
- CustomThemeManager customThemeManager = (CustomThemeManager) manager;
- return Objects.equals(getOverlayPackages().get(OVERLAY_CATEGORY_COLOR),
- customThemeManager.getOverlayPackages().get(OVERLAY_CATEGORY_COLOR));
- }
-
- @Override
- public int getLayoutResId() {
- return R.layout.theme_color_option;
- }
-
- @Override
- public void bindPreview(ViewGroup container) {
- container.setContentDescription(
- container.getContext().getString(R.string.color_preview_content_description));
-
- bindPreviewHeader(container, R.string.preview_name_color, R.drawable.ic_colorize_24px,
- null);
-
- ViewGroup cardBody = container.findViewById(R.id.theme_preview_card_body_container);
- if (cardBody.getChildCount() == 0) {
- LayoutInflater.from(container.getContext()).inflate(
- R.layout.preview_card_color_content, cardBody, true);
- }
- Resources res = container.getResources();
- @ColorInt int accentColor = resolveColor(res);
- @ColorInt int controlGreyColor = ResourceUtils.getColorAttr(
- container.getContext(),
- android.R.attr.textColorTertiary);
- ColorStateList tintList = new ColorStateList(
- new int[][]{
- new int[]{android.R.attr.state_selected},
- new int[]{android.R.attr.state_checked},
- new int[]{-android.R.attr.state_enabled}
- },
- new int[] {
- accentColor,
- accentColor,
- controlGreyColor
- }
- );
-
- for (int i = 0; i < COLOR_BUTTON_IDS.length; i++) {
- CompoundButton button = container.findViewById(COLOR_BUTTON_IDS[i]);
- button.setButtonTintList(tintList);
- }
-
- Switch enabledSwitch = container.findViewById(R.id.preview_toggle_selected);
- enabledSwitch.setThumbTintList(tintList);
- enabledSwitch.setTrackTintList(tintList);
-
- ColorStateList seekbarTintList = ColorStateList.valueOf(accentColor);
- SeekBar seekbar = container.findViewById(R.id.preview_seekbar);
- seekbar.setThumbTintList(seekbarTintList);
- seekbar.setProgressTintList(seekbarTintList);
- seekbar.setProgressBackgroundTintList(seekbarTintList);
- // Disable seekbar
- seekbar.setOnTouchListener((view, motionEvent) -> true);
-
- int iconFgColor = ResourceUtils.getColorAttr(container.getContext(),
- android.R.attr.colorBackground);
- if (!mIcons.isEmpty() && mShapeDrawable != null) {
- for (int i = 0; i < COLOR_TILE_IDS.length; i++) {
- Drawable icon = mIcons.get(COLOR_TILES_ICON_IDS[i][1]).getConstantState()
- .newDrawable();
- icon.setTint(iconFgColor);
- //TODO: load and set the shape.
- Drawable bgShape = mShapeDrawable.getConstantState().newDrawable();
- bgShape.setTint(accentColor);
-
- ImageView bg = container.findViewById(COLOR_TILE_IDS[i]);
- bg.setImageDrawable(bgShape);
- ImageView fg = container.findViewById(COLOR_TILES_ICON_IDS[i][0]);
- fg.setImageDrawable(icon);
- }
- }
- }
-
- public void setPreviewIcons(List<Drawable> icons) {
- mIcons.addAll(icons);
- }
-
- public void setShapeDrawable(@Nullable Drawable shapeDrawable) {
- mShapeDrawable = shapeDrawable;
- }
-
- @Override
- public Builder buildStep(Builder builder) {
- builder.setColorAccentDark(mColorAccentDark).setColorAccentLight(mColorAccentLight);
- return super.buildStep(builder);
- }
- }
-
- public static class ShapeOption extends ThemeComponentOption {
-
- private final LayerDrawable mShape;
- private final List<ShapeAppIcon> mAppIcons;
- private final String mLabel;
- private final Path mPath;
- private final int mCornerRadius;
- private int[] mShapeIconIds = {
- R.id.shape_preview_icon_0, R.id.shape_preview_icon_1, R.id.shape_preview_icon_2,
- R.id.shape_preview_icon_3, R.id.shape_preview_icon_4, R.id.shape_preview_icon_5
- };
-
- ShapeOption(String packageName, String label, Path path,
- @Dimension int cornerRadius, Drawable shapeDrawable,
- List<ShapeAppIcon> appIcons) {
- addOverlayPackage(OVERLAY_CATEGORY_SHAPE, packageName);
- mLabel = label;
- mAppIcons = appIcons;
- mPath = path;
- mCornerRadius = cornerRadius;
- Drawable background = shapeDrawable.getConstantState().newDrawable();
- Drawable foreground = shapeDrawable.getConstantState().newDrawable();
- mShape = new LayerDrawable(new Drawable[]{background, foreground});
- mShape.setLayerGravity(0, Gravity.CENTER);
- mShape.setLayerGravity(1, Gravity.CENTER);
- }
-
- @Override
- public void bindThumbnailTile(View view) {
- ImageView thumb = view.findViewById(R.id.shape_thumbnail);
- Resources res = view.getResources();
- Theme theme = view.getContext().getTheme();
- int borderWidth = 2 * res.getDimensionPixelSize(R.dimen.option_border_width);
-
- Drawable background = mShape.getDrawable(0);
- background.setTintList(res.getColorStateList(R.color.option_border_color, theme));
-
- ShapeDrawable foreground = (ShapeDrawable) mShape.getDrawable(1);
-
- foreground.setIntrinsicHeight(background.getIntrinsicHeight() - borderWidth);
- foreground.setIntrinsicWidth(background.getIntrinsicWidth() - borderWidth);
- TypedArray ta = view.getContext().obtainStyledAttributes(
- new int[]{android.R.attr.colorPrimary});
- int primaryColor = ta.getColor(0, 0);
- ta.recycle();
- int foregroundColor =
- ResourceUtils.getColorAttr(view.getContext(), android.R.attr.textColorPrimary);
-
- foreground.setTint(ColorUtils.blendARGB(primaryColor, foregroundColor, .05f));
-
- thumb.setImageDrawable(mShape);
- view.setContentDescription(mLabel);
- }
-
- @Override
- public boolean isActive(CustomizationManager<ThemeComponentOption> manager) {
- CustomThemeManager customThemeManager = (CustomThemeManager) manager;
- return Objects.equals(getOverlayPackages().get(OVERLAY_CATEGORY_SHAPE),
- customThemeManager.getOverlayPackages().get(OVERLAY_CATEGORY_SHAPE));
- }
-
- @Override
- public int getLayoutResId() {
- return R.layout.theme_shape_option;
- }
-
- @Override
- public void bindPreview(ViewGroup container) {
- container.setContentDescription(
- container.getContext().getString(R.string.shape_preview_content_description));
-
- bindPreviewHeader(container, R.string.preview_name_shape, R.drawable.ic_shapes_24px,
- null);
-
- ViewGroup cardBody = container.findViewById(R.id.theme_preview_card_body_container);
- if (cardBody.getChildCount() == 0) {
- LayoutInflater.from(container.getContext()).inflate(
- R.layout.preview_card_shape_content, cardBody, true);
- }
- for (int i = 0; i < mShapeIconIds.length && i < mAppIcons.size(); i++) {
- ImageView iconView = cardBody.findViewById(mShapeIconIds[i]);
- iconView.setBackground(mAppIcons.get(i).getDrawableCopy());
- }
- }
-
- @Override
- public Builder buildStep(Builder builder) {
- builder.setShapePath(mPath)
- .setBottomSheetCornerRadius(mCornerRadius)
- .setShapePreviewIcons(mAppIcons);
- return super.buildStep(builder);
- }
- }
-}
diff --git a/src/com/android/customization/model/theme/custom/ThemeComponentOptionProvider.java b/src/com/android/customization/model/theme/custom/ThemeComponentOptionProvider.java
deleted file mode 100644
index 992c47c..0000000
--- a/src/com/android/customization/model/theme/custom/ThemeComponentOptionProvider.java
+++ /dev/null
@@ -1,78 +0,0 @@
-/*
- * 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.
- */
-package com.android.customization.model.theme.custom;
-
-import android.content.Context;
-import android.content.pm.PackageManager.NameNotFoundException;
-import android.content.res.Resources;
-import android.os.UserHandle;
-
-import com.android.customization.model.CustomizationManager.OptionsFetchedListener;
-import com.android.customization.model.ResourceConstants;
-import com.android.customization.model.theme.OverlayManagerCompat;
-
-import java.util.ArrayList;
-import java.util.List;
-
-/**
- * Base class used to retrieve Custom Theme Component options (eg, different fonts)
- * from the system.
- */
-public abstract class ThemeComponentOptionProvider<T extends ThemeComponentOption> {
-
- protected final Context mContext;
- protected final List<String> mOverlayPackages;
- protected List<T> mOptions;
-
- public ThemeComponentOptionProvider(Context context, OverlayManagerCompat manager,
- String... categories) {
- mContext = context;
- mOverlayPackages = new ArrayList<>();
- for (String category : categories) {
- mOverlayPackages.addAll(manager.getOverlayPackagesForCategory(category,
- UserHandle.myUserId(), ResourceConstants.getPackagesToOverlay(mContext)));
- }
- }
-
- /**
- * Returns whether there are options for this component available in the current setup.
- */
- public boolean isAvailable() {
- return !mOverlayPackages.isEmpty();
- }
-
- /**
- * Retrieve the available options for this component.
- * @param callback called when the themes have been retrieved (or immediately if cached)
- * @param reload whether to reload themes if they're cached.
- */
- public void fetch(OptionsFetchedListener<T> callback, boolean reload) {
- if (mOptions == null || reload) {
- mOptions = new ArrayList<>();
- loadOptions();
- }
-
- if(callback != null) {
- callback.onOptionsLoaded(mOptions);
- }
- }
-
- protected abstract void loadOptions();
-
- protected Resources getOverlayResources(String overlayPackage) throws NameNotFoundException {
- return mContext.getPackageManager().getResourcesForApplication(overlayPackage);
- }
-}
diff --git a/src/com/android/customization/module/CustomizationInjector.kt b/src/com/android/customization/module/CustomizationInjector.kt
index f954d33..30550d0 100644
--- a/src/com/android/customization/module/CustomizationInjector.kt
+++ b/src/com/android/customization/module/CustomizationInjector.kt
@@ -18,10 +18,6 @@
import android.content.Context
import android.content.res.Resources
import androidx.activity.ComponentActivity
-import androidx.fragment.app.FragmentActivity
-import com.android.customization.model.theme.OverlayManagerCompat
-import com.android.customization.model.theme.ThemeBundleProvider
-import com.android.customization.model.theme.ThemeManager
import com.android.customization.picker.clock.domain.interactor.ClockPickerInteractor
import com.android.customization.picker.clock.ui.view.ClockViewFactory
import com.android.customization.picker.clock.ui.viewmodel.ClockCarouselViewModel
@@ -38,13 +34,6 @@
interface CustomizationInjector : Injector {
fun getCustomizationPreferences(context: Context): CustomizationPreferences
- fun getThemeManager(
- provider: ThemeBundleProvider,
- activity: FragmentActivity,
- overlayManagerCompat: OverlayManagerCompat,
- logger: ThemesUserEventLogger,
- ): ThemeManager
-
fun getKeyguardQuickAffordancePickerInteractor(
context: Context,
): KeyguardQuickAffordancePickerInteractor
diff --git a/src/com/android/customization/module/StatsLogUserEventLogger.java b/src/com/android/customization/module/StatsLogUserEventLogger.java
index 232d43a..8fbf996 100644
--- a/src/com/android/customization/module/StatsLogUserEventLogger.java
+++ b/src/com/android/customization/module/StatsLogUserEventLogger.java
@@ -15,9 +15,6 @@
*/
package com.android.customization.module;
-import static com.android.customization.model.ResourceConstants.OVERLAY_CATEGORY_COLOR;
-import static com.android.customization.model.ResourceConstants.OVERLAY_CATEGORY_FONT;
-import static com.android.customization.model.ResourceConstants.OVERLAY_CATEGORY_SHAPE;
import static com.android.systemui.shared.system.SysUiStatsLog.STYLE_UICHANGED__ACTION__APP_LAUNCHED;
import static com.android.systemui.shared.system.SysUiStatsLog.STYLE_UICHANGED__LAUNCHED_PREFERENCE__LAUNCHED_CROP_AND_SET_ACTION;
import static com.android.systemui.shared.system.SysUiStatsLog.STYLE_UICHANGED__LAUNCHED_PREFERENCE__LAUNCHED_DEEP_LINK;
@@ -45,14 +42,10 @@
import com.android.customization.model.color.ColorOption;
import com.android.customization.model.grid.GridOption;
-import com.android.customization.model.theme.ThemeBundle;
import com.android.wallpaper.module.NoOpUserEventLogger;
import com.android.wallpaper.module.WallpaperPreferences;
import com.android.wallpaper.module.WallpaperStatusChecker;
-import java.util.Map;
-import java.util.Objects;
-
/**
* StatsLog-backed implementation of {@link ThemesUserEventLogger}.
*/
@@ -161,34 +154,6 @@
.log();
}
- @Nullable
- private String getThemePackage(ThemeBundle theme, String category) {
- Map<String, String> packages = theme.getPackagesByCategory();
- return packages.get(category);
- }
-
- @Override
- public void logThemeSelected(ThemeBundle theme, boolean isCustomTheme) {
- new SysUiStatsLogger(StyleEnums.PICKER_SELECT)
- .setColorPackageHash(
- Objects.hashCode(getThemePackage(theme, OVERLAY_CATEGORY_COLOR)))
- .setFontPackageHash(Objects.hashCode(getThemePackage(theme, OVERLAY_CATEGORY_FONT)))
- .setShapePackageHash(
- Objects.hashCode(getThemePackage(theme, OVERLAY_CATEGORY_SHAPE)))
- .log();
- }
-
- @Override
- public void logThemeApplied(ThemeBundle theme, boolean isCustomTheme) {
- new SysUiStatsLogger(StyleEnums.PICKER_APPLIED)
- .setColorPackageHash(
- Objects.hashCode(getThemePackage(theme, OVERLAY_CATEGORY_COLOR)))
- .setFontPackageHash(Objects.hashCode(getThemePackage(theme, OVERLAY_CATEGORY_FONT)))
- .setShapePackageHash(
- Objects.hashCode(getThemePackage(theme, OVERLAY_CATEGORY_SHAPE)))
- .log();
- }
-
@Override
public void logColorApplied(int action, ColorOption colorOption) {
new SysUiStatsLogger(action)
diff --git a/src/com/android/customization/module/ThemePickerInjector.kt b/src/com/android/customization/module/ThemePickerInjector.kt
index 74bcdef..c7c9c4c 100644
--- a/src/com/android/customization/module/ThemePickerInjector.kt
+++ b/src/com/android/customization/module/ThemePickerInjector.kt
@@ -23,7 +23,6 @@
import android.net.Uri
import android.text.TextUtils
import androidx.activity.ComponentActivity
-import androidx.fragment.app.FragmentActivity
import androidx.lifecycle.DefaultLifecycleObserver
import androidx.lifecycle.LifecycleOwner
import androidx.lifecycle.ViewModelProvider
@@ -33,8 +32,6 @@
import com.android.customization.model.grid.GridOptionsManager
import com.android.customization.model.mode.DarkModeSnapshotRestorer
import com.android.customization.model.theme.OverlayManagerCompat
-import com.android.customization.model.theme.ThemeBundleProvider
-import com.android.customization.model.theme.ThemeManager
import com.android.customization.model.themedicon.ThemedIconSwitchProvider
import com.android.customization.model.themedicon.data.repository.ThemeIconRepository
import com.android.customization.model.themedicon.domain.interactor.ThemedIconInteractor
@@ -204,15 +201,6 @@
return getPreferences(context) as CustomizationPreferences
}
- override fun getThemeManager(
- provider: ThemeBundleProvider,
- activity: FragmentActivity,
- overlayManagerCompat: OverlayManagerCompat,
- logger: ThemesUserEventLogger
- ): ThemeManager {
- return ThemeManager(provider, activity, overlayManagerCompat, logger)
- }
-
override fun getWallpaperInteractor(context: Context): WallpaperInteractor {
val appContext = context.applicationContext
return wallpaperInteractor
diff --git a/src/com/android/customization/module/ThemesUserEventLogger.java b/src/com/android/customization/module/ThemesUserEventLogger.java
index b1a87b9..2deb2e5 100644
--- a/src/com/android/customization/module/ThemesUserEventLogger.java
+++ b/src/com/android/customization/module/ThemesUserEventLogger.java
@@ -17,7 +17,6 @@
import com.android.customization.model.color.ColorOption;
import com.android.customization.model.grid.GridOption;
-import com.android.customization.model.theme.ThemeBundle;
import com.android.wallpaper.module.UserEventLogger;
/**
@@ -25,10 +24,6 @@
*/
public interface ThemesUserEventLogger extends UserEventLogger {
- void logThemeSelected(ThemeBundle theme, boolean isCustomTheme);
-
- void logThemeApplied(ThemeBundle theme, boolean isCustomTheme);
-
/**
* Logs the color usage while color is applied.
*
diff --git a/src/com/android/customization/picker/theme/CustomThemeActivity.java b/src/com/android/customization/picker/theme/CustomThemeActivity.java
deleted file mode 100644
index 62a2f26..0000000
--- a/src/com/android/customization/picker/theme/CustomThemeActivity.java
+++ /dev/null
@@ -1,421 +0,0 @@
-/*
- * 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.
- */
-package com.android.customization.picker.theme;
-
-import android.app.AlertDialog.Builder;
-import android.content.Intent;
-import android.os.Bundle;
-import android.util.Log;
-import android.view.View;
-import android.widget.TextView;
-import android.widget.Toast;
-
-import androidx.annotation.Nullable;
-import androidx.annotation.StringRes;
-import androidx.fragment.app.Fragment;
-import androidx.fragment.app.FragmentActivity;
-import androidx.fragment.app.FragmentManager;
-import androidx.fragment.app.FragmentTransaction;
-
-import com.android.customization.model.CustomizationManager.Callback;
-import com.android.customization.model.theme.DefaultThemeProvider;
-import com.android.customization.model.theme.OverlayManagerCompat;
-import com.android.customization.model.theme.ThemeBundle;
-import com.android.customization.model.theme.ThemeBundleProvider;
-import com.android.customization.model.theme.ThemeManager;
-import com.android.customization.model.theme.custom.ColorOptionsProvider;
-import com.android.customization.model.theme.custom.CustomTheme;
-import com.android.customization.model.theme.custom.CustomThemeManager;
-import com.android.customization.model.theme.custom.FontOptionsProvider;
-import com.android.customization.model.theme.custom.IconOptionsProvider;
-import com.android.customization.model.theme.custom.ShapeOptionsProvider;
-import com.android.customization.model.theme.custom.ThemeComponentOption;
-import com.android.customization.model.theme.custom.ThemeComponentOption.ColorOption;
-import com.android.customization.model.theme.custom.ThemeComponentOption.FontOption;
-import com.android.customization.model.theme.custom.ThemeComponentOption.IconOption;
-import com.android.customization.model.theme.custom.ThemeComponentOption.ShapeOption;
-import com.android.customization.model.theme.custom.ThemeComponentOptionProvider;
-import com.android.customization.module.CustomizationInjector;
-import com.android.customization.module.ThemesUserEventLogger;
-import com.android.customization.picker.theme.CustomThemeStepFragment.CustomThemeComponentStepHost;
-import com.android.wallpaper.R;
-import com.android.wallpaper.module.InjectorProvider;
-import com.android.wallpaper.picker.AppbarFragment.AppbarFragmentHost;
-
-import org.json.JSONException;
-
-import java.util.ArrayList;
-import java.util.List;
-
-public class CustomThemeActivity extends FragmentActivity implements
- AppbarFragmentHost, CustomThemeComponentStepHost {
- public static final String EXTRA_THEME_ID = "CustomThemeActivity.ThemeId";
- public static final String EXTRA_THEME_TITLE = "CustomThemeActivity.ThemeTitle";
- public static final String EXTRA_THEME_PACKAGES = "CustomThemeActivity.ThemePackages";
- public static final int REQUEST_CODE_CUSTOM_THEME = 1;
- public static final int RESULT_THEME_DELETED = 10;
- public static final int RESULT_THEME_APPLIED = 20;
-
- private static final String TAG = "CustomThemeActivity";
- private static final String KEY_STATE_CURRENT_STEP = "CustomThemeActivity.currentStep";
-
- private ThemesUserEventLogger mUserEventLogger;
- private List<ComponentStep<?>> mSteps;
- private int mCurrentStep;
- private CustomThemeManager mCustomThemeManager;
- private ThemeManager mThemeManager;
- private TextView mNextButton;
- private TextView mPreviousButton;
-
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- CustomizationInjector injector = (CustomizationInjector) InjectorProvider.getInjector();
- mUserEventLogger = (ThemesUserEventLogger) injector.getUserEventLogger(this);
- ThemeBundleProvider themeProvider =
- new DefaultThemeProvider(this, injector.getCustomizationPreferences(this));
- Intent intent = getIntent();
- CustomTheme customTheme = null;
- if (intent != null && intent.hasExtra(EXTRA_THEME_PACKAGES)
- && intent.hasExtra(EXTRA_THEME_TITLE) && intent.hasExtra(EXTRA_THEME_ID)) {
- try {
- CustomTheme.Builder themeBuilder = themeProvider.parseCustomTheme(
- intent.getStringExtra(EXTRA_THEME_PACKAGES));
- if (themeBuilder != null) {
- themeBuilder.setId(intent.getStringExtra(EXTRA_THEME_ID));
- themeBuilder.setTitle(intent.getStringExtra(EXTRA_THEME_TITLE));
- customTheme = themeBuilder.build(this);
- }
- } catch (JSONException e) {
- Log.w(TAG, "Couldn't parse provided custom theme, will override it");
- }
- }
-
- mThemeManager = injector.getThemeManager(
- new DefaultThemeProvider(this, injector.getCustomizationPreferences(this)),
- this,
- new OverlayManagerCompat(this),
- mUserEventLogger);
- mThemeManager.fetchOptions(null, false);
- mCustomThemeManager = CustomThemeManager.create(customTheme, mThemeManager);
- if (savedInstanceState != null) {
- mCustomThemeManager.readCustomTheme(themeProvider, savedInstanceState);
- }
-
- int currentStep = 0;
- if (savedInstanceState != null) {
- currentStep = savedInstanceState.getInt(KEY_STATE_CURRENT_STEP);
- }
- initSteps(currentStep);
-
- super.onCreate(savedInstanceState);
- setContentView(R.layout.activity_custom_theme);
- mNextButton = findViewById(R.id.next_button);
- mNextButton.setOnClickListener(view -> onNextOrApply());
- mPreviousButton = findViewById(R.id.previous_button);
- mPreviousButton.setOnClickListener(view -> onBackPressed());
-
- FragmentManager fm = getSupportFragmentManager();
- Fragment fragment = fm.findFragmentById(R.id.fragment_container);
- if (fragment == null) {
- // Navigate to the first step
- navigateToStep(0);
- }
- }
-
- @Override
- protected void onSaveInstanceState(Bundle outState) {
- super.onSaveInstanceState(outState);
- outState.putInt(KEY_STATE_CURRENT_STEP, mCurrentStep);
- if (mCustomThemeManager != null) {
- mCustomThemeManager.saveCustomTheme(this, outState);
- }
- }
-
- private void navigateToStep(int i) {
- FragmentManager fragmentManager = getSupportFragmentManager();
- ComponentStep step = mSteps.get(i);
- Fragment fragment = step.getFragment(mCustomThemeManager.getOriginalTheme().getTitle());
-
- FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
- fragmentTransaction.replace(R.id.fragment_container, fragment);
- // Don't add step 0 to the back stack so that going back from it just finishes the Activity
- if (i > 0) {
- fragmentTransaction.addToBackStack("Step " + i);
- }
- fragmentTransaction.commit();
- fragmentManager.executePendingTransactions();
- updateNavigationButtonLabels();
- }
-
- private void initSteps(int currentStep) {
- mSteps = new ArrayList<>();
- OverlayManagerCompat manager = new OverlayManagerCompat(this);
- mSteps.add(new FontStep(new FontOptionsProvider(this, manager), 0));
- mSteps.add(new IconStep(new IconOptionsProvider(this, manager), 1));
- mSteps.add(new ColorStep(new ColorOptionsProvider(this, manager, mCustomThemeManager), 2));
- mSteps.add(new ShapeStep(new ShapeOptionsProvider(this, manager), 3));
- mSteps.add(new NameStep(4));
- mCurrentStep = currentStep;
- }
-
- private void onNextOrApply() {
- CustomThemeStepFragment stepFragment = getCurrentStepFragment();
- if (stepFragment instanceof CustomThemeComponentFragment) {
- CustomThemeComponentFragment fragment = (CustomThemeComponentFragment) stepFragment;
- mCustomThemeManager.apply(fragment.getSelectedOption(), new Callback() {
- @Override
- public void onSuccess() {
- navigateToStep(mCurrentStep + 1);
- }
-
- @Override
- public void onError(@Nullable Throwable throwable) {
- Log.w(TAG, "Error applying custom theme component", throwable);
- Toast.makeText(CustomThemeActivity.this, R.string.apply_theme_error_msg,
- Toast.LENGTH_LONG).show();
- }
- });
- } else if (stepFragment instanceof CustomThemeNameFragment) {
- CustomThemeNameFragment fragment = (CustomThemeNameFragment) stepFragment;
- CustomTheme originalTheme = mCustomThemeManager.getOriginalTheme();
-
- // We're on the last step, apply theme and leave
- CustomTheme themeToApply = mCustomThemeManager.buildPartialCustomTheme(this,
- originalTheme.getId(), fragment.getThemeName());
-
- // If the current theme is equal to the original theme being edited, then
- // don't search for an equivalent, let the user apply the same one by keeping
- // it null.
- ThemeBundle equivalent = (originalTheme.isEquivalent(themeToApply))
- ? null : mThemeManager.findThemeByPackages(themeToApply);
-
- if (equivalent != null) {
- Builder builder =
- new Builder(CustomThemeActivity.this);
- builder.setTitle(getString(R.string.use_style_instead_title,
- equivalent.getTitle()))
- .setMessage(getString(R.string.use_style_instead_body,
- equivalent.getTitle()))
- .setPositiveButton(getString(R.string.use_style_button,
- equivalent.getTitle()),
- (dialogInterface, i) -> applyTheme(equivalent))
- .setNegativeButton(R.string.no_thanks, null)
- .create()
- .show();
- } else {
- applyTheme(themeToApply);
- }
- } else {
- throw new IllegalStateException("Unknown CustomThemeStepFragment");
- }
- }
-
- private void applyTheme(ThemeBundle themeToApply) {
- mThemeManager.apply(themeToApply, new Callback() {
- @Override
- public void onSuccess() {
- overridePendingTransition(R.anim.fade_in, R.anim.fade_out);
- Toast.makeText(getApplicationContext(), R.string.applied_theme_msg,
- Toast.LENGTH_LONG).show();
- setResult(RESULT_THEME_APPLIED);
- finish();
- }
-
- @Override
- public void onError(@Nullable Throwable throwable) {
- Log.w(TAG, "Error applying custom theme", throwable);
- Toast.makeText(CustomThemeActivity.this,
- R.string.apply_theme_error_msg,
- Toast.LENGTH_LONG).show();
- }
- });
- }
-
- private CustomThemeStepFragment getCurrentStepFragment() {
- return (CustomThemeStepFragment)
- getSupportFragmentManager().findFragmentById(R.id.fragment_container);
- }
-
- @Override
- public void setCurrentStep(int i) {
- mCurrentStep = i;
- updateNavigationButtonLabels();
- }
-
- private void updateNavigationButtonLabels() {
- mPreviousButton.setVisibility(mCurrentStep == 0 ? View.INVISIBLE : View.VISIBLE);
- mNextButton.setText((mCurrentStep < mSteps.size() -1) ? R.string.custom_theme_next
- : R.string.apply_btn);
- }
-
- @Override
- public void delete() {
- mThemeManager.removeCustomTheme(mCustomThemeManager.getOriginalTheme());
- setResult(RESULT_THEME_DELETED);
- finish();
- }
-
- @Override
- public void cancel() {
- finish();
- }
-
- @Override
- public ThemeComponentOptionProvider<? extends ThemeComponentOption> getComponentOptionProvider(
- int position) {
- return mSteps.get(position).provider;
- }
-
- @Override
- public CustomThemeManager getCustomThemeManager() {
- return mCustomThemeManager;
- }
-
- @Override
- public void onUpArrowPressed() {
- // Skip it because CustomThemeStepFragment will implement cancel button
- // (instead of up arrow) on action bar.
- }
-
- @Override
- public boolean isUpArrowSupported() {
- // Skip it because CustomThemeStepFragment will implement cancel button
- // (instead of up arrow) on action bar.
- return false;
- }
-
- /**
- * Represents a step in selecting a custom theme, picking a particular component (eg font,
- * color, shape, etc).
- * Each step has a Fragment instance associated that instances of this class will provide.
- */
- private static abstract class ComponentStep<T extends ThemeComponentOption> {
- @StringRes final int titleResId;
- @StringRes final int accessibilityResId;
- final ThemeComponentOptionProvider<T> provider;
- final int position;
- private CustomThemeStepFragment mFragment;
-
- protected ComponentStep(@StringRes int titleResId, @StringRes int accessibilityResId,
- ThemeComponentOptionProvider<T> provider, int position) {
- this.titleResId = titleResId;
- this.accessibilityResId = accessibilityResId;
- this.provider = provider;
- this.position = position;
- }
-
- CustomThemeStepFragment getFragment(String title) {
- if (mFragment == null) {
- mFragment = createFragment(title);
- }
- return mFragment;
- }
-
- /**
- * @return a newly created fragment that will handle this step's UI.
- */
- abstract CustomThemeStepFragment createFragment(String title);
- }
-
- private class FontStep extends ComponentStep<FontOption> {
-
- protected FontStep(ThemeComponentOptionProvider<FontOption> provider,
- int position) {
- super(R.string.font_component_title, R.string.accessibility_custom_font_title, provider,
- position);
- }
-
- @Override
- CustomThemeComponentFragment createFragment(String title) {
- return CustomThemeComponentFragment.newInstance(
- title,
- position,
- titleResId,
- accessibilityResId);
- }
- }
-
- private class IconStep extends ComponentStep<IconOption> {
-
- protected IconStep(ThemeComponentOptionProvider<IconOption> provider,
- int position) {
- super(R.string.icon_component_title, R.string.accessibility_custom_icon_title, provider,
- position);
- }
-
- @Override
- CustomThemeComponentFragment createFragment(String title) {
- return CustomThemeComponentFragment.newInstance(
- title,
- position,
- titleResId,
- accessibilityResId);
- }
- }
-
- private class ColorStep extends ComponentStep<ColorOption> {
-
- protected ColorStep(ThemeComponentOptionProvider<ColorOption> provider,
- int position) {
- super(R.string.color_component_title, R.string.accessibility_custom_color_title,
- provider, position);
- }
-
- @Override
- CustomThemeComponentFragment createFragment(String title) {
- return CustomThemeComponentFragment.newInstance(
- title,
- position,
- titleResId,
- accessibilityResId);
- }
- }
-
- private class ShapeStep extends ComponentStep<ShapeOption> {
-
- protected ShapeStep(ThemeComponentOptionProvider<ShapeOption> provider,
- int position) {
- super(R.string.shape_component_title, R.string.accessibility_custom_shape_title,
- provider, position);
- }
-
- @Override
- CustomThemeComponentFragment createFragment(String title) {
- return CustomThemeComponentFragment.newInstance(
- title,
- position,
- titleResId,
- accessibilityResId);
- }
- }
-
- private class NameStep extends ComponentStep {
-
- protected NameStep(int position) {
- super(R.string.name_component_title, R.string.accessibility_custom_name_title, null,
- position);
- }
-
- @Override
- CustomThemeNameFragment createFragment(String title) {
- return CustomThemeNameFragment.newInstance(
- title,
- position,
- titleResId,
- accessibilityResId);
- }
- }
-}
diff --git a/src/com/android/customization/picker/theme/CustomThemeComponentFragment.java b/src/com/android/customization/picker/theme/CustomThemeComponentFragment.java
deleted file mode 100644
index a1e9967..0000000
--- a/src/com/android/customization/picker/theme/CustomThemeComponentFragment.java
+++ /dev/null
@@ -1,121 +0,0 @@
-/*
- * 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.
- */
-package com.android.customization.picker.theme;
-
-import android.os.Bundle;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.view.ViewGroup;
-
-import androidx.annotation.NonNull;
-import androidx.annotation.Nullable;
-import androidx.recyclerview.widget.RecyclerView;
-
-import com.android.customization.model.theme.custom.ThemeComponentOption;
-import com.android.customization.model.theme.custom.ThemeComponentOptionProvider;
-import com.android.customization.widget.OptionSelectorController;
-import com.android.customization.widget.OptionSelectorController.CheckmarkStyle;
-import com.android.wallpaper.R;
-import com.android.wallpaper.picker.AppbarFragment;
-
-public class CustomThemeComponentFragment extends CustomThemeStepFragment {
- private static final String ARG_USE_GRID_LAYOUT = "CustomThemeComponentFragment.use_grid";;
-
- public static CustomThemeComponentFragment newInstance(CharSequence toolbarTitle, int position,
- int titleResId, int accessibilityResId) {
- return newInstance(toolbarTitle, position, titleResId, accessibilityResId, false);
- }
-
- public static CustomThemeComponentFragment newInstance(CharSequence toolbarTitle, int position,
- int titleResId, int accessibilityResId, boolean allowGridLayout) {
- CustomThemeComponentFragment fragment = new CustomThemeComponentFragment();
- Bundle arguments = AppbarFragment.createArguments(toolbarTitle);
- arguments.putInt(ARG_KEY_POSITION, position);
- arguments.putInt(ARG_KEY_TITLE_RES_ID, titleResId);
- arguments.putInt(ARG_KEY_ACCESSIBILITY_RES_ID, accessibilityResId);
- arguments.putBoolean(ARG_USE_GRID_LAYOUT, allowGridLayout);
- fragment.setArguments(arguments);
- return fragment;
- }
-
- private ThemeComponentOptionProvider<? extends ThemeComponentOption> mProvider;
- private boolean mUseGridLayout;
-
- private RecyclerView mOptionsContainer;
- private OptionSelectorController<ThemeComponentOption> mOptionsController;
- private ThemeComponentOption mSelectedOption;
-
- @Override
- public void onCreate(@Nullable Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- mUseGridLayout = getArguments().getBoolean(ARG_USE_GRID_LAYOUT);
- mProvider = mHost.getComponentOptionProvider(mPosition);
- }
-
- @Nullable
- @Override
- public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container,
- @Nullable Bundle savedInstanceState) {
- View view = super.onCreateView(inflater, container, savedInstanceState);
- mOptionsContainer = view.findViewById(R.id.options_container);
- mPreviewContainer = view.findViewById(R.id.component_preview_content);
- mTitle = view.findViewById(R.id.component_options_title);
- mTitle.setText(mTitleResId);
- setUpOptions();
-
- return view;
- }
-
- @Override
- protected int getFragmentLayoutResId() {
- return R.layout.fragment_custom_theme_component;
- }
-
- public ThemeComponentOption getSelectedOption() {
- return mSelectedOption;
- }
-
- private void bindPreview() {
- mSelectedOption.bindPreview(mPreviewContainer);
- }
-
- private void setUpOptions() {
- mProvider.fetch(options -> {
- mOptionsController = new OptionSelectorController(
- mOptionsContainer, options, mUseGridLayout, CheckmarkStyle.NONE);
-
- mOptionsController.addListener(selected -> {
- mSelectedOption = (ThemeComponentOption) selected;
- bindPreview();
- // Preview and apply. The selection will be kept whatever user goes to previous page
- // or encounter system config changes, the current selection can be recovered.
- mCustomThemeManager.apply(mSelectedOption, /* callback= */ null);
- });
- mOptionsController.initOptions(mCustomThemeManager);
-
- for (ThemeComponentOption option : options) {
- if (option.isActive(mCustomThemeManager)) {
- mSelectedOption = option;
- break;
- }
- }
- if (mSelectedOption == null) {
- mSelectedOption = options.get(0);
- }
- mOptionsController.setSelectedOption(mSelectedOption);
- }, false);
- }
-}
diff --git a/src/com/android/customization/picker/theme/CustomThemeNameFragment.java b/src/com/android/customization/picker/theme/CustomThemeNameFragment.java
deleted file mode 100644
index ea9099f..0000000
--- a/src/com/android/customization/picker/theme/CustomThemeNameFragment.java
+++ /dev/null
@@ -1,132 +0,0 @@
-/*
- * 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.
- */
-package com.android.customization.picker.theme;
-
-import android.os.Bundle;
-import android.text.TextUtils;
-import android.util.Log;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.view.ViewGroup;
-import android.widget.EditText;
-import android.widget.ImageView;
-
-import androidx.annotation.NonNull;
-import androidx.annotation.Nullable;
-
-import com.android.customization.model.theme.ThemeBundle.PreviewInfo;
-import com.android.customization.model.theme.custom.CustomTheme;
-import com.android.customization.module.CustomizationInjector;
-import com.android.customization.module.CustomizationPreferences;
-import com.android.customization.picker.WallpaperPreviewer;
-import com.android.wallpaper.R;
-import com.android.wallpaper.module.CurrentWallpaperInfoFactory;
-import com.android.wallpaper.module.InjectorProvider;
-import com.android.wallpaper.picker.AppbarFragment;
-
-import org.json.JSONArray;
-import org.json.JSONException;
-
-/** Fragment of naming a custom theme. */
-public class CustomThemeNameFragment extends CustomThemeStepFragment {
-
- private static final String TAG = "CustomThemeNameFragment";
-
- public static CustomThemeNameFragment newInstance(CharSequence toolbarTitle, int position,
- int titleResId, int accessibilityResId) {
- CustomThemeNameFragment fragment = new CustomThemeNameFragment();
- Bundle arguments = AppbarFragment.createArguments(toolbarTitle);
- arguments.putInt(ARG_KEY_POSITION, position);
- arguments.putInt(ARG_KEY_TITLE_RES_ID, titleResId);
- arguments.putInt(ARG_KEY_ACCESSIBILITY_RES_ID, accessibilityResId);
- fragment.setArguments(arguments);
- return fragment;
- }
-
- private EditText mNameEditor;
- private ImageView mWallpaperImage;
- private ThemeOptionPreviewer mThemeOptionPreviewer;
- private CustomizationPreferences mCustomizationPreferences;
-
- @Nullable
- @Override
- public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container,
- @Nullable Bundle savedInstanceState) {
- View view = super.onCreateView(inflater, container, savedInstanceState);
- mTitle = view.findViewById(R.id.component_options_title);
- mTitle.setText(mTitleResId);
- CurrentWallpaperInfoFactory currentWallpaperFactory = InjectorProvider.getInjector()
- .getCurrentWallpaperInfoFactory(getActivity().getApplicationContext());
- CustomizationInjector injector = (CustomizationInjector) InjectorProvider.getInjector();
- mCustomizationPreferences = injector.getCustomizationPreferences(getContext());
-
- // Set theme option.
- ViewGroup previewContainer = view.findViewById(R.id.theme_preview_container);
- mThemeOptionPreviewer = new ThemeOptionPreviewer(getLifecycle(), getContext(),
- previewContainer);
- PreviewInfo previewInfo = mCustomThemeManager.buildCustomThemePreviewInfo(getContext());
- mThemeOptionPreviewer.setPreviewInfo(previewInfo);
-
- // Set wallpaper background.
- mWallpaperImage = view.findViewById(R.id.wallpaper_preview_image);
- final WallpaperPreviewer wallpaperPreviewer = new WallpaperPreviewer(
- getLifecycle(),
- getActivity(),
- mWallpaperImage,
- view.findViewById(R.id.wallpaper_preview_surface));
- currentWallpaperFactory.createCurrentWallpaperInfos(
- (homeWallpaper, lockWallpaper, presentationMode) -> {
- wallpaperPreviewer.setWallpaper(homeWallpaper,
- mThemeOptionPreviewer::updateColorForLauncherWidgets);
- }, false);
-
- // Set theme default name.
- mNameEditor = view.findViewById(R.id.custom_theme_name);
- mNameEditor.setText(getOriginalThemeName());
- return view;
- }
-
- private String getOriginalThemeName() {
- CustomTheme originalTheme = mCustomThemeManager.getOriginalTheme();
- if (originalTheme == null || !originalTheme.isDefined()) {
- // For new custom theme. use custom themes amount plus 1 as default naming.
- String serializedThemes = mCustomizationPreferences.getSerializedCustomThemes();
- int customThemesCount = 0;
- if (!TextUtils.isEmpty(serializedThemes)) {
- try {
- JSONArray customThemes = new JSONArray(serializedThemes);
- customThemesCount = customThemes.length();
- } catch (JSONException e) {
- Log.w(TAG, "Couldn't read stored custom theme");
- }
- }
- return getContext().getString(
- R.string.custom_theme_title, customThemesCount + 1);
- } else {
- // For existing custom theme, keep its name as default naming.
- return originalTheme.getTitle();
- }
- }
-
- @Override
- protected int getFragmentLayoutResId() {
- return R.layout.fragment_custom_theme_name;
- }
-
- public String getThemeName() {
- return mNameEditor.getText().toString();
- }
-}
diff --git a/src/com/android/customization/picker/theme/CustomThemeStepFragment.java b/src/com/android/customization/picker/theme/CustomThemeStepFragment.java
deleted file mode 100644
index 3f07431..0000000
--- a/src/com/android/customization/picker/theme/CustomThemeStepFragment.java
+++ /dev/null
@@ -1,116 +0,0 @@
-package com.android.customization.picker.theme;
-
-import android.app.AlertDialog;
-import android.content.Context;
-import android.graphics.drawable.Drawable;
-import android.os.Bundle;
-import android.view.LayoutInflater;
-import android.view.MenuItem;
-import android.view.View;
-import android.view.ViewGroup;
-import android.widget.TextView;
-
-import androidx.annotation.NonNull;
-import androidx.annotation.Nullable;
-import androidx.annotation.StringRes;
-
-import com.android.customization.model.theme.custom.CustomThemeManager;
-import com.android.customization.model.theme.custom.ThemeComponentOption;
-import com.android.customization.model.theme.custom.ThemeComponentOptionProvider;
-import com.android.wallpaper.R;
-import com.android.wallpaper.picker.AppbarFragment;
-
-abstract class CustomThemeStepFragment extends AppbarFragment {
- protected static final String ARG_KEY_POSITION = "CustomThemeStepFragment.position";
- protected static final String ARG_KEY_TITLE_RES_ID = "CustomThemeStepFragment.title_res";
- protected static final String ARG_KEY_ACCESSIBILITY_RES_ID =
- "CustomThemeStepFragment.accessibility_res";
- protected CustomThemeComponentStepHost mHost;
- protected CustomThemeManager mCustomThemeManager;
- protected int mPosition;
- protected ViewGroup mPreviewContainer;
- protected TextView mTitle;
- @StringRes
- protected int mTitleResId;
- @StringRes
- protected int mAccessibilityResId;
-
- @Override
- public void onAttach(Context context) {
- super.onAttach(context);
- mHost = (CustomThemeComponentStepHost) context;
- }
-
- @Override
- public void onResume() {
- super.onResume();
- mHost.setCurrentStep(mPosition);
- }
-
- @Override
- public void onCreate(@Nullable Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- mPosition = getArguments().getInt(ARG_KEY_POSITION);
- mTitleResId = getArguments().getInt(ARG_KEY_TITLE_RES_ID);
- mAccessibilityResId = getArguments().getInt(ARG_KEY_ACCESSIBILITY_RES_ID);
- mCustomThemeManager = mHost.getCustomThemeManager();
- }
-
- @Override
- public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container,
- @Nullable Bundle savedInstanceState) {
- View view = inflater.inflate(
- getFragmentLayoutResId(), container, /* attachToRoot */ false);
- // No original theme means it's a new one, so no toolbar icon for deleting it is needed
- if (mCustomThemeManager.getOriginalTheme() == null
- || !mCustomThemeManager.getOriginalTheme().isDefined()) {
- setUpToolbar(view);
- } else {
- setUpToolbar(view, R.menu.custom_theme_editor_menu);
- mToolbar.getMenu().getItem(0).setIconTintList(
- getContext().getColorStateList(R.color.toolbar_icon_tint));
- }
- Drawable closeIcon = getResources().getDrawable(R.drawable.ic_close_24px, null).mutate();
- closeIcon.setTintList(getResources().getColorStateList(R.color.toolbar_icon_tint, null));
- mToolbar.setNavigationIcon(closeIcon);
-
- mToolbar.setNavigationContentDescription(R.string.cancel);
- mToolbar.setNavigationOnClickListener(v -> mHost.cancel());
-
- mPreviewContainer = view.findViewById(R.id.component_preview_content);
- return view;
- }
-
- @Override
- protected String getAccessibilityTitle() {
- return getString(mAccessibilityResId);
- }
-
- @Override
- public boolean onMenuItemClick(MenuItem item) {
- if (item.getItemId() == R.id.custom_theme_delete) {
- AlertDialog.Builder builder = new AlertDialog.Builder(getContext());
- builder.setMessage(R.string.delete_custom_theme_confirmation)
- .setPositiveButton(R.string.delete_custom_theme_button,
- (dialogInterface, i) -> mHost.delete())
- .setNegativeButton(R.string.cancel, null)
- .create()
- .show();
- return true;
- }
- return super.onMenuItemClick(item);
- }
-
- protected abstract int getFragmentLayoutResId();
-
- public interface CustomThemeComponentStepHost {
- void delete();
- void cancel();
- ThemeComponentOptionProvider<? extends ThemeComponentOption> getComponentOptionProvider(
- int position);
-
- CustomThemeManager getCustomThemeManager();
-
- void setCurrentStep(int step);
- }
-}
diff --git a/src/com/android/customization/picker/theme/ThemeFragment.java b/src/com/android/customization/picker/theme/ThemeFragment.java
deleted file mode 100644
index 3a9a56f..0000000
--- a/src/com/android/customization/picker/theme/ThemeFragment.java
+++ /dev/null
@@ -1,402 +0,0 @@
-/*
- * Copyright (C) 2018 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.customization.picker.theme;
-
-import static android.app.Activity.RESULT_OK;
-
-import static com.android.wallpaper.widget.BottomActionBar.BottomAction.APPLY;
-import static com.android.wallpaper.widget.BottomActionBar.BottomAction.CUSTOMIZE;
-import static com.android.wallpaper.widget.BottomActionBar.BottomAction.INFORMATION;
-
-import android.content.Context;
-import android.content.Intent;
-import android.os.Bundle;
-import android.util.Log;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.view.ViewGroup;
-import android.widget.ImageView;
-import android.widget.Toast;
-
-import androidx.annotation.NonNull;
-import androidx.annotation.Nullable;
-import androidx.core.widget.ContentLoadingProgressBar;
-import androidx.recyclerview.widget.RecyclerView;
-
-import com.android.customization.model.CustomizationManager.Callback;
-import com.android.customization.model.CustomizationManager.OptionsFetchedListener;
-import com.android.customization.model.CustomizationOption;
-import com.android.customization.model.theme.ThemeBundle;
-import com.android.customization.model.theme.ThemeManager;
-import com.android.customization.model.theme.custom.CustomTheme;
-import com.android.customization.module.ThemesUserEventLogger;
-import com.android.customization.picker.WallpaperPreviewer;
-import com.android.customization.widget.OptionSelectorController;
-import com.android.wallpaper.R;
-import com.android.wallpaper.model.WallpaperInfo;
-import com.android.wallpaper.module.CurrentWallpaperInfoFactory;
-import com.android.wallpaper.module.InjectorProvider;
-import com.android.wallpaper.picker.AppbarFragment;
-import com.android.wallpaper.widget.BottomActionBar;
-import com.android.wallpaper.widget.BottomActionBar.AccessibilityCallback;
-import com.android.wallpaper.widget.BottomActionBar.BottomSheetContent;
-
-import java.util.List;
-
-/**
- * Fragment that contains the main UI for selecting and applying a ThemeBundle.
- */
-public class ThemeFragment extends AppbarFragment {
-
- private static final String TAG = "ThemeFragment";
- private static final String KEY_SELECTED_THEME = "ThemeFragment.SelectedThemeBundle";
- private static final String KEY_STATE_BOTTOM_ACTION_BAR_VISIBLE =
- "ThemeFragment.bottomActionBarVisible";
- private static final int FULL_PREVIEW_REQUEST_CODE = 1000;
-
- /**
- * Interface to be implemented by an Activity hosting a {@link ThemeFragment}
- */
- public interface ThemeFragmentHost {
- ThemeManager getThemeManager();
- }
- public static ThemeFragment newInstance(CharSequence title) {
- ThemeFragment fragment = new ThemeFragment();
- fragment.setArguments(AppbarFragment.createArguments(title));
- return fragment;
- }
-
- private RecyclerView mOptionsContainer;
- private OptionSelectorController<ThemeBundle> mOptionsController;
- private ThemeManager mThemeManager;
- private ThemesUserEventLogger mEventLogger;
- private ThemeBundle mSelectedTheme;
- private ContentLoadingProgressBar mLoading;
- private View mContent;
- private View mError;
- private WallpaperInfo mCurrentHomeWallpaper;
- private CurrentWallpaperInfoFactory mCurrentWallpaperFactory;
- private BottomActionBar mBottomActionBar;
- private WallpaperPreviewer mWallpaperPreviewer;
- private ImageView mWallpaperImage;
- private ThemeOptionPreviewer mThemeOptionPreviewer;
- private ThemeInfoView mThemeInfoView;
-
- @Override
- public void onAttach(Context context) {
- super.onAttach(context);
- mThemeManager = ((ThemeFragmentHost) context).getThemeManager();
- mEventLogger = (ThemesUserEventLogger)
- InjectorProvider.getInjector().getUserEventLogger(context);
- }
-
- @Nullable
- @Override
- public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container,
- @Nullable Bundle savedInstanceState) {
- View view = inflater.inflate(
- R.layout.fragment_theme_picker, container, /* attachToRoot */ false);
- setUpToolbar(view);
-
- mContent = view.findViewById(R.id.content_section);
- mLoading = view.findViewById(R.id.loading_indicator);
- mError = view.findViewById(R.id.error_section);
- mCurrentWallpaperFactory = InjectorProvider.getInjector()
- .getCurrentWallpaperInfoFactory(getActivity().getApplicationContext());
- mOptionsContainer = view.findViewById(R.id.options_container);
-
- mThemeOptionPreviewer = new ThemeOptionPreviewer(
- getLifecycle(),
- getContext(),
- view.findViewById(R.id.theme_preview_container));
-
- // Set Wallpaper background.
- mWallpaperImage = view.findViewById(R.id.wallpaper_preview_image);
- mWallpaperPreviewer = new WallpaperPreviewer(
- getLifecycle(),
- getActivity(),
- mWallpaperImage,
- view.findViewById(R.id.wallpaper_preview_surface));
- mCurrentWallpaperFactory.createCurrentWallpaperInfos(
- (homeWallpaper, lockWallpaper, presentationMode) -> {
- mCurrentHomeWallpaper = homeWallpaper;
- mWallpaperPreviewer.setWallpaper(mCurrentHomeWallpaper,
- mThemeOptionPreviewer::updateColorForLauncherWidgets);
- }, false);
- return view;
- }
-
- @Override
- protected void onBottomActionBarReady(BottomActionBar bottomActionBar) {
- super.onBottomActionBarReady(bottomActionBar);
- mBottomActionBar = bottomActionBar;
- mBottomActionBar.showActionsOnly(INFORMATION, APPLY);
- mBottomActionBar.setActionClickListener(APPLY, v -> {
- mBottomActionBar.disableActions();
- applyTheme();
- });
-
- mBottomActionBar.bindBottomSheetContentWithAction(
- new ThemeInfoContent(getContext()), INFORMATION);
- mBottomActionBar.setActionClickListener(CUSTOMIZE, this::onCustomizeClicked);
-
- // Update target view's accessibility param since it will be blocked by the bottom sheet
- // when expanded.
- mBottomActionBar.setAccessibilityCallback(new AccessibilityCallback() {
- @Override
- public void onBottomSheetCollapsed() {
- mOptionsContainer.setImportantForAccessibility(
- View.IMPORTANT_FOR_ACCESSIBILITY_YES);
- }
-
- @Override
- public void onBottomSheetExpanded() {
- mOptionsContainer.setImportantForAccessibility(
- View.IMPORTANT_FOR_ACCESSIBILITY_NO_HIDE_DESCENDANTS);
- }
- });
- }
-
- @Override
- public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
- super.onViewCreated(view, savedInstanceState);
- // Setup options here when all views are ready(including BottomActionBar), since we need to
- // update views after options are loaded.
- setUpOptions(savedInstanceState);
- }
-
- private void applyTheme() {
- mThemeManager.apply(mSelectedTheme, new Callback() {
- @Override
- public void onSuccess() {
- Toast.makeText(getContext(), R.string.applied_theme_msg, Toast.LENGTH_LONG).show();
- getActivity().overridePendingTransition(R.anim.fade_in, R.anim.fade_out);
- getActivity().finish();
- }
-
- @Override
- public void onError(@Nullable Throwable throwable) {
- Log.w(TAG, "Error applying theme", throwable);
- // Since we disabled it when clicked apply button.
- mBottomActionBar.enableActions();
- mBottomActionBar.hide();
- Toast.makeText(getContext(), R.string.apply_theme_error_msg,
- Toast.LENGTH_LONG).show();
- }
- });
- }
-
- @Override
- public void onSaveInstanceState(@NonNull Bundle outState) {
- super.onSaveInstanceState(outState);
- if (mSelectedTheme != null && !mSelectedTheme.isActive(mThemeManager)) {
- outState.putString(KEY_SELECTED_THEME, mSelectedTheme.getSerializedPackages());
- }
- if (mBottomActionBar != null) {
- outState.putBoolean(KEY_STATE_BOTTOM_ACTION_BAR_VISIBLE, mBottomActionBar.isVisible());
- }
- }
-
- @Override
- public void onActivityResult(int requestCode, int resultCode, Intent data) {
- if (requestCode == CustomThemeActivity.REQUEST_CODE_CUSTOM_THEME) {
- if (resultCode == CustomThemeActivity.RESULT_THEME_DELETED) {
- mSelectedTheme = null;
- reloadOptions();
- } else if (resultCode == CustomThemeActivity.RESULT_THEME_APPLIED) {
- getActivity().overridePendingTransition(R.anim.fade_in, R.anim.fade_out);
- getActivity().finish();
- } else {
- if (mSelectedTheme != null) {
- mOptionsController.setSelectedOption(mSelectedTheme);
- // Set selected option above will show BottomActionBar,
- // hide BottomActionBar for the mis-trigger.
- mBottomActionBar.hide();
- } else {
- reloadOptions();
- }
- }
- } else if (requestCode == FULL_PREVIEW_REQUEST_CODE && resultCode == RESULT_OK) {
- applyTheme();
- }
- super.onActivityResult(requestCode, resultCode, data);
- }
-
- private void onCustomizeClicked(View view) {
- if (mSelectedTheme instanceof CustomTheme) {
- navigateToCustomTheme((CustomTheme) mSelectedTheme);
- }
- }
-
- private void hideError() {
- mContent.setVisibility(View.VISIBLE);
- mError.setVisibility(View.GONE);
- }
-
- private void showError() {
- mLoading.hide();
- mContent.setVisibility(View.GONE);
- mError.setVisibility(View.VISIBLE);
- }
-
- private void setUpOptions(@Nullable Bundle savedInstanceState) {
- hideError();
- mLoading.show();
- mThemeManager.fetchOptions(new OptionsFetchedListener<ThemeBundle>() {
- @Override
- public void onOptionsLoaded(List<ThemeBundle> options) {
- mOptionsController = new OptionSelectorController<>(mOptionsContainer, options);
- mOptionsController.initOptions(mThemeManager);
-
- // Find out the selected theme option.
- // 1. Find previously selected theme.
- String previouslySelected = savedInstanceState != null
- ? savedInstanceState.getString(KEY_SELECTED_THEME) : null;
- ThemeBundle previouslySelectedTheme = null;
- ThemeBundle activeTheme = null;
- for (ThemeBundle theme : options) {
- if (previouslySelected != null
- && previouslySelected.equals(theme.getSerializedPackages())) {
- previouslySelectedTheme = theme;
- }
- if (theme.isActive(mThemeManager)) {
- activeTheme = theme;
- }
- }
- // 2. Use active theme if no previously selected theme.
- mSelectedTheme = previouslySelectedTheme != null
- ? previouslySelectedTheme
- : activeTheme;
- // 3. Select the first system theme(default theme currently)
- // if there is no matching custom enabled theme.
- if (mSelectedTheme == null) {
- mSelectedTheme = findFirstSystemThemeBundle(options);
- }
-
- mOptionsController.setSelectedOption(mSelectedTheme);
- onOptionSelected(mSelectedTheme);
- restoreBottomActionBarVisibility(savedInstanceState);
-
- mOptionsController.addListener(selectedOption -> {
- onOptionSelected(selectedOption);
- if (!isAddCustomThemeOption(selectedOption)) {
- mBottomActionBar.show();
- }
- });
- mLoading.hide();
- }
- @Override
- public void onError(@Nullable Throwable throwable) {
- if (throwable != null) {
- Log.e(TAG, "Error loading theme bundles", throwable);
- }
- showError();
- }
- }, false);
- }
-
- private void reloadOptions() {
- mThemeManager.fetchOptions(options -> {
- mOptionsController.resetOptions(options);
- for (ThemeBundle theme : options) {
- if (theme.isActive(mThemeManager)) {
- mSelectedTheme = theme;
- break;
- }
- }
- if (mSelectedTheme == null) {
- mSelectedTheme = findFirstSystemThemeBundle(options);
- }
- mOptionsController.setSelectedOption(mSelectedTheme);
- // Set selected option above will show BottomActionBar,
- // hide BottomActionBar for the mis-trigger.
- mBottomActionBar.hide();
- }, true);
- }
-
- private ThemeBundle findFirstSystemThemeBundle(List<ThemeBundle> options) {
- for (ThemeBundle bundle : options) {
- if (!(bundle instanceof CustomTheme)) {
- return bundle;
- }
- }
- return null;
- }
-
- private void onOptionSelected(CustomizationOption selectedOption) {
- if (isAddCustomThemeOption(selectedOption)) {
- navigateToCustomTheme((CustomTheme) selectedOption);
- } else {
- mSelectedTheme = (ThemeBundle) selectedOption;
- mSelectedTheme.setOverrideThemeWallpaper(mCurrentHomeWallpaper);
- mEventLogger.logThemeSelected(mSelectedTheme,
- selectedOption instanceof CustomTheme);
- mThemeOptionPreviewer.setPreviewInfo(mSelectedTheme.getPreviewInfo());
- if (mThemeInfoView != null && mSelectedTheme != null) {
- mThemeInfoView.populateThemeInfo(mSelectedTheme);
- }
-
- if (selectedOption instanceof CustomTheme) {
- mBottomActionBar.showActionsOnly(INFORMATION, CUSTOMIZE, APPLY);
- } else {
- mBottomActionBar.showActionsOnly(INFORMATION, APPLY);
- }
- }
- }
-
- private void restoreBottomActionBarVisibility(@Nullable Bundle savedInstanceState) {
- boolean isBottomActionBarVisible = savedInstanceState != null
- && savedInstanceState.getBoolean(KEY_STATE_BOTTOM_ACTION_BAR_VISIBLE);
- if (isBottomActionBarVisible) {
- mBottomActionBar.show();
- } else {
- mBottomActionBar.hide();
- }
- }
-
- private boolean isAddCustomThemeOption(CustomizationOption option) {
- return option instanceof CustomTheme && !((CustomTheme) option).isDefined();
- }
-
- private void navigateToCustomTheme(CustomTheme themeToEdit) {
- Intent intent = new Intent(getActivity(), CustomThemeActivity.class);
- intent.putExtra(CustomThemeActivity.EXTRA_THEME_TITLE, themeToEdit.getTitle());
- intent.putExtra(CustomThemeActivity.EXTRA_THEME_ID, themeToEdit.getId());
- intent.putExtra(CustomThemeActivity.EXTRA_THEME_PACKAGES,
- themeToEdit.getSerializedPackages());
- startActivityForResult(intent, CustomThemeActivity.REQUEST_CODE_CUSTOM_THEME);
- }
-
- private final class ThemeInfoContent extends BottomSheetContent<ThemeInfoView> {
-
- private ThemeInfoContent(Context context) {
- super(context);
- }
-
- @Override
- public int getViewId() {
- return R.layout.theme_info_view;
- }
-
- @Override
- public void onViewCreated(ThemeInfoView view) {
- mThemeInfoView = view;
- if (mSelectedTheme != null) {
- mThemeInfoView.populateThemeInfo(mSelectedTheme);
- }
- }
- }
-}
diff --git a/src/com/android/customization/picker/theme/ThemeFullPreviewFragment.java b/src/com/android/customization/picker/theme/ThemeFullPreviewFragment.java
deleted file mode 100644
index 3ba64ec..0000000
--- a/src/com/android/customization/picker/theme/ThemeFullPreviewFragment.java
+++ /dev/null
@@ -1,165 +0,0 @@
-/*
- * 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.customization.picker.theme;
-
-import static android.app.Activity.RESULT_OK;
-
-import static com.android.wallpaper.widget.BottomActionBar.BottomAction.APPLY;
-import static com.android.wallpaper.widget.BottomActionBar.BottomAction.INFORMATION;
-
-import android.app.Activity;
-import android.content.Context;
-import android.content.Intent;
-import android.os.Bundle;
-import android.util.Log;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.view.ViewGroup;
-import android.widget.ImageView;
-
-import androidx.annotation.NonNull;
-import androidx.annotation.Nullable;
-
-import com.android.customization.model.theme.DefaultThemeProvider;
-import com.android.customization.model.theme.ThemeBundle;
-import com.android.customization.model.theme.ThemeBundleProvider;
-import com.android.customization.module.CustomizationInjector;
-import com.android.customization.picker.WallpaperPreviewer;
-import com.android.wallpaper.R;
-import com.android.wallpaper.model.WallpaperInfo;
-import com.android.wallpaper.module.InjectorProvider;
-import com.android.wallpaper.picker.AppbarFragment;
-import com.android.wallpaper.widget.BottomActionBar;
-import com.android.wallpaper.widget.BottomActionBar.BottomSheetContent;
-
-import com.bumptech.glide.Glide;
-
-import org.json.JSONException;
-
-/** A Fragment for theme full preview page. */
-public class ThemeFullPreviewFragment extends AppbarFragment {
- private static final String TAG = "ThemeFullPreviewFragment";
-
- public static final String EXTRA_THEME_OPTION_TITLE = "theme_option_title";
- protected static final String EXTRA_THEME_OPTION = "theme_option";
- protected static final String EXTRA_WALLPAPER_INFO = "wallpaper_info";
- protected static final String EXTRA_CAN_APPLY_FROM_FULL_PREVIEW = "can_apply";
-
- private WallpaperInfo mWallpaper;
- private ThemeBundle mThemeBundle;
- private boolean mCanApplyFromFullPreview;
-
- /**
- * Returns a new {@link ThemeFullPreviewFragment} with the provided title and bundle arguments
- * set.
- */
- public static ThemeFullPreviewFragment newInstance(CharSequence title, Bundle intentBundle) {
- ThemeFullPreviewFragment fragment = new ThemeFullPreviewFragment();
- Bundle bundle = new Bundle();
- bundle.putAll(AppbarFragment.createArguments(title));
- bundle.putAll(intentBundle);
- fragment.setArguments(bundle);
- return fragment;
- }
-
- @Override
- public void onCreate(@Nullable Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- mWallpaper = getArguments().getParcelable(EXTRA_WALLPAPER_INFO);
- mCanApplyFromFullPreview = getArguments().getBoolean(EXTRA_CAN_APPLY_FROM_FULL_PREVIEW);
- CustomizationInjector injector = (CustomizationInjector) InjectorProvider.getInjector();
- ThemeBundleProvider themeProvider = new DefaultThemeProvider(
- getContext(), injector.getCustomizationPreferences(getContext()));
- try {
- ThemeBundle.Builder builder = themeProvider.parseThemeBundle(
- getArguments().getString(EXTRA_THEME_OPTION));
- if (builder != null) {
- builder.setTitle(getArguments().getString(EXTRA_THEME_OPTION_TITLE));
- mThemeBundle = builder.build(getContext());
- }
- } catch (JSONException e) {
- Log.w(TAG, "Couldn't parse provided custom theme, will override it");
- // TODO(chihhangchuang): Handle the error case.
- }
- }
-
- @Nullable
- @Override
- public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container,
- @Nullable Bundle savedInstanceState) {
- View view = inflater.inflate(
- R.layout.fragment_theme_full_preview, container, /* attachToRoot */ false);
- setUpToolbar(view);
- Glide.get(getContext()).clearMemory();
-
- // Set theme option.
- final ThemeOptionPreviewer themeOptionPreviewer = new ThemeOptionPreviewer(
- getLifecycle(),
- getContext(),
- view.findViewById(R.id.theme_preview_container));
- themeOptionPreviewer.setPreviewInfo(mThemeBundle.getPreviewInfo());
-
- // Set wallpaper background.
- ImageView wallpaperImageView = view.findViewById(R.id.wallpaper_preview_image);
- final WallpaperPreviewer wallpaperPreviewer = new WallpaperPreviewer(
- getLifecycle(),
- getActivity(),
- wallpaperImageView,
- view.findViewById(R.id.wallpaper_preview_surface));
- wallpaperPreviewer.setWallpaper(mWallpaper,
- themeOptionPreviewer::updateColorForLauncherWidgets);
- return view;
- }
-
- @Override
- protected void onBottomActionBarReady(BottomActionBar bottomActionBar) {
- super.onBottomActionBarReady(bottomActionBar);
- if (mCanApplyFromFullPreview) {
- bottomActionBar.showActionsOnly(INFORMATION, APPLY);
- bottomActionBar.setActionClickListener(APPLY, v -> finishActivityWithResultOk());
- } else {
- bottomActionBar.showActionsOnly(INFORMATION);
- }
- bottomActionBar.bindBottomSheetContentWithAction(
- new ThemeInfoContent(getContext()), INFORMATION);
- bottomActionBar.show();
- }
-
- private void finishActivityWithResultOk() {
- Activity activity = requireActivity();
- activity.overridePendingTransition(R.anim.fade_in, R.anim.fade_out);
- Intent intent = new Intent();
- activity.setResult(RESULT_OK, intent);
- activity.finish();
- }
-
- private final class ThemeInfoContent extends BottomSheetContent<ThemeInfoView> {
-
- private ThemeInfoContent(Context context) {
- super(context);
- }
-
- @Override
- public int getViewId() {
- return R.layout.theme_info_view;
- }
-
- @Override
- public void onViewCreated(ThemeInfoView view) {
- view.populateThemeInfo(mThemeBundle);
- }
- }
-}
diff --git a/src/com/android/customization/picker/theme/ThemeInfoView.java b/src/com/android/customization/picker/theme/ThemeInfoView.java
deleted file mode 100644
index e929c4d..0000000
--- a/src/com/android/customization/picker/theme/ThemeInfoView.java
+++ /dev/null
@@ -1,84 +0,0 @@
-/*
- * 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.customization.picker.theme;
-
-import android.content.Context;
-import android.content.res.ColorStateList;
-import android.util.AttributeSet;
-import android.widget.ImageView;
-import android.widget.LinearLayout;
-import android.widget.TextView;
-
-import androidx.annotation.NonNull;
-import androidx.annotation.Nullable;
-
-import com.android.customization.model.theme.ThemeBundle;
-import com.android.wallpaper.R;
-
-/** A view for displaying style info. */
-public class ThemeInfoView extends LinearLayout {
- private static final int WIFI_ICON_PREVIEW_INDEX = 0;
- private static final int SHAPE_PREVIEW_INDEX = 0;
-
- private TextView mTitle;
- private TextView mFontPreviewTextView;
- private ImageView mIconPreviewImageView;
- private ImageView mAppPreviewImageView;
- private ImageView mShapePreviewImageView;
-
- public ThemeInfoView(Context context, @Nullable AttributeSet attrs) {
- super(context, attrs);
- }
-
- @Override
- protected void onFinishInflate() {
- super.onFinishInflate();
- mTitle = findViewById(R.id.style_info_title);
- mFontPreviewTextView = findViewById(R.id.font_preview);
- mIconPreviewImageView = findViewById(R.id.qs_preview_icon);
- mAppPreviewImageView = findViewById(R.id.app_preview_icon);
- mShapePreviewImageView = findViewById(R.id.shape_preview_icon);
- }
-
- /** Populates theme info. */
- public void populateThemeInfo(@NonNull ThemeBundle selectedTheme) {
- ThemeBundle.PreviewInfo previewInfo = selectedTheme.getPreviewInfo();
-
- if (previewInfo != null) {
- mTitle.setText(getContext().getString(R.string.style_info_description));
- if (previewInfo.headlineFontFamily != null) {
- mTitle.setTypeface(previewInfo.headlineFontFamily);
- mFontPreviewTextView.setTypeface(previewInfo.headlineFontFamily);
- }
-
- if (previewInfo.icons.get(WIFI_ICON_PREVIEW_INDEX) != null) {
- mIconPreviewImageView.setImageDrawable(
- previewInfo.icons.get(WIFI_ICON_PREVIEW_INDEX));
- }
-
- if (previewInfo.shapeAppIcons.get(SHAPE_PREVIEW_INDEX) != null) {
- mAppPreviewImageView.setBackground(
- previewInfo.shapeAppIcons.get(SHAPE_PREVIEW_INDEX).getDrawableCopy());
- }
-
- if (previewInfo.shapeDrawable != null) {
- mShapePreviewImageView.setImageDrawable(previewInfo.shapeDrawable);
- mShapePreviewImageView.setImageTintList(
- ColorStateList.valueOf(previewInfo.resolveAccentColor(getResources())));
- }
- }
- }
-}
diff --git a/src/com/android/customization/picker/theme/ThemeOptionPreviewer.java b/src/com/android/customization/picker/theme/ThemeOptionPreviewer.java
deleted file mode 100644
index 14b53ec..0000000
--- a/src/com/android/customization/picker/theme/ThemeOptionPreviewer.java
+++ /dev/null
@@ -1,405 +0,0 @@
-/*
- * 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.customization.picker.theme;
-
-import static android.view.View.MeasureSpec.EXACTLY;
-import static android.view.View.MeasureSpec.makeMeasureSpec;
-
-import android.app.WallpaperColors;
-import android.content.Context;
-import android.content.res.ColorStateList;
-import android.content.res.Configuration;
-import android.content.res.Resources;
-import android.graphics.Typeface;
-import android.graphics.drawable.Drawable;
-import android.graphics.drawable.GradientDrawable;
-import android.text.format.DateFormat;
-import android.util.DisplayMetrics;
-import android.util.TypedValue;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.view.ViewGroup;
-import android.view.animation.AnimationUtils;
-import android.widget.CompoundButton;
-import android.widget.ImageView;
-import android.widget.Switch;
-import android.widget.TextView;
-
-import androidx.annotation.MainThread;
-import androidx.annotation.Nullable;
-import androidx.cardview.widget.CardView;
-import androidx.lifecycle.Lifecycle;
-import androidx.lifecycle.LifecycleObserver;
-import androidx.lifecycle.OnLifecycleEvent;
-
-import com.android.customization.model.theme.ThemeBundle;
-import com.android.customization.model.theme.ThemeBundle.PreviewInfo;
-import com.android.customization.model.theme.ThemeBundle.PreviewInfo.ShapeAppIcon;
-import com.android.wallpaper.R;
-import com.android.wallpaper.util.ResourceUtils;
-import com.android.wallpaper.util.ScreenSizeCalculator;
-import com.android.wallpaper.util.TimeUtils;
-import com.android.wallpaper.util.TimeUtils.TimeTicker;
-
-import java.util.Calendar;
-import java.util.List;
-import java.util.Locale;
-import java.util.TimeZone;
-
-/** A class to load the {@link ThemeBundle} preview to the view. */
-class ThemeOptionPreviewer implements LifecycleObserver {
- private static final String DATE_FORMAT = "EEEE, MMM d";
-
- // Maps which icon from ResourceConstants#ICONS_FOR_PREVIEW.
- private static final int ICON_WIFI = 0;
- private static final int ICON_BLUETOOTH = 1;
- private static final int ICON_FLASHLIGHT = 3;
- private static final int ICON_AUTO_ROTATE = 4;
- private static final int ICON_CELLULAR_SIGNAL = 6;
- private static final int ICON_BATTERY = 7;
-
- // Icons in the top bar (fake "status bar") with the particular order.
- private static final int [] sTopBarIconToPreviewIcon = new int [] {
- ICON_WIFI, ICON_CELLULAR_SIGNAL, ICON_BATTERY };
-
- // Ids of app icon shape preview.
- private int[] mShapeAppIconIds = {
- R.id.shape_preview_icon_0, R.id.shape_preview_icon_1,
- R.id.shape_preview_icon_2, R.id.shape_preview_icon_3
- };
- private int[] mShapeIconAppNameIds = {
- R.id.shape_preview_icon_app_name_0, R.id.shape_preview_icon_app_name_1,
- R.id.shape_preview_icon_app_name_2, R.id.shape_preview_icon_app_name_3
- };
-
- // Ids of color/icons section.
- private int[][] mColorTileIconIds = {
- new int[] { R.id.preview_color_qs_0_icon, ICON_WIFI},
- new int[] { R.id.preview_color_qs_1_icon, ICON_BLUETOOTH},
- new int[] { R.id.preview_color_qs_2_icon, ICON_FLASHLIGHT},
- new int[] { R.id.preview_color_qs_3_icon, ICON_AUTO_ROTATE},
- };
- private int[] mColorTileIds = {
- R.id.preview_color_qs_0_bg, R.id.preview_color_qs_1_bg,
- R.id.preview_color_qs_2_bg, R.id.preview_color_qs_3_bg
- };
- private int[] mColorButtonIds = {
- R.id.preview_check_selected, R.id.preview_radio_selected, R.id.preview_toggle_selected
- };
-
- private final Context mContext;
-
- private View mContentView;
- private TextView mStatusBarClock;
- private TextView mSmartSpaceDate;
- private TimeTicker mTicker;
-
- private boolean mHasPreviewInfoSet;
- private boolean mHasWallpaperColorSet;
-
- ThemeOptionPreviewer(Lifecycle lifecycle, Context context, ViewGroup previewContainer) {
- lifecycle.addObserver(this);
-
- mContext = context;
- mContentView = LayoutInflater.from(context).inflate(
- R.layout.theme_preview_content, /* root= */ null);
- mContentView.setVisibility(View.INVISIBLE);
- mStatusBarClock = mContentView.findViewById(R.id.theme_preview_clock);
- mSmartSpaceDate = mContentView.findViewById(R.id.smart_space_date);
- updateTime();
- final float screenAspectRatio =
- ScreenSizeCalculator.getInstance().getScreenAspectRatio(mContext);
- Configuration config = mContext.getResources().getConfiguration();
- final boolean directionLTR = config.getLayoutDirection() == View.LAYOUT_DIRECTION_LTR;
- previewContainer.addOnLayoutChangeListener(new View.OnLayoutChangeListener() {
- @Override
- public void onLayoutChange(View view, int left, int top, int right, int bottom,
- int oldLeft, int oldTop, int oldRight, int oldBottom) {
- // Calculate the full preview card height and width.
- final int fullPreviewCardHeight = getFullPreviewCardHeight();
- final int fullPreviewCardWidth = (int) (fullPreviewCardHeight / screenAspectRatio);
-
- // Relayout the content view to match full preview card size.
- mContentView.measure(
- makeMeasureSpec(fullPreviewCardWidth, EXACTLY),
- makeMeasureSpec(fullPreviewCardHeight, EXACTLY));
- mContentView.layout(0, 0, fullPreviewCardWidth, fullPreviewCardHeight);
-
- // Scale the content view from full preview size to the container size. For full
- // preview, the scale value is 1.
- float scale = (float) previewContainer.getMeasuredHeight() / fullPreviewCardHeight;
- mContentView.setScaleX(scale);
- mContentView.setScaleY(scale);
- // The pivot point is centered by default, set to (0, 0).
- mContentView.setPivotX(directionLTR ? 0f : mContentView.getMeasuredWidth());
- mContentView.setPivotY(0f);
-
- // Ensure there will be only one content view in the container.
- previewContainer.removeAllViews();
- // Finally, add the content view to the container.
- previewContainer.addView(
- mContentView,
- mContentView.getMeasuredWidth(),
- mContentView.getMeasuredHeight());
-
- previewContainer.removeOnLayoutChangeListener(this);
- }
- });
- }
-
- /** Loads the Theme option preview into the container view. */
- public void setPreviewInfo(PreviewInfo previewInfo) {
- setHeadlineFont(previewInfo.headlineFontFamily);
- setBodyFont(previewInfo.bodyFontFamily);
- setTopBarIcons(previewInfo.icons);
- setAppIconShape(previewInfo.shapeAppIcons);
- setColorAndIconsSection(previewInfo.icons, previewInfo.shapeDrawable,
- previewInfo.resolveAccentColor(mContext.getResources()));
- setColorAndIconsBoxRadius(previewInfo.bottomSheeetCornerRadius);
- setQsbRadius(previewInfo.bottomSheeetCornerRadius);
- mHasPreviewInfoSet = true;
- showPreviewIfHasAllConfigSet();
- }
-
- /**
- * Updates the color of widgets in launcher (like top status bar, smart space, and app name
- * text) which will change its content color according to different wallpapers.
- *
- * @param colors the {@link WallpaperColors} of the wallpaper, or {@code null} to use light
- * color as default
- */
- public void updateColorForLauncherWidgets(@Nullable WallpaperColors colors) {
- boolean useLightTextColor = colors == null
- || (colors.getColorHints() & WallpaperColors.HINT_SUPPORTS_DARK_TEXT) == 0;
- int textColor = mContext.getColor(useLightTextColor
- ? android.R.color.white
- : android.R.color.black);
- int textShadowColor = mContext.getColor(useLightTextColor
- ? android.R.color.tertiary_text_dark
- : android.R.color.transparent);
- // Update the top status bar clock text color.
- mStatusBarClock.setTextColor(textColor);
- // Update the top status bar icon color.
- ViewGroup iconsContainer = mContentView.findViewById(R.id.theme_preview_top_bar_icons);
- for (int i = 0; i < iconsContainer.getChildCount(); i++) {
- ((ImageView) iconsContainer.getChildAt(i))
- .setImageTintList(ColorStateList.valueOf(textColor));
- }
- // Update smart space date color.
- mSmartSpaceDate.setTextColor(textColor);
- mSmartSpaceDate.setShadowLayer(
- mContext.getResources().getDimension(
- R.dimen.smartspace_preview_key_ambient_shadow_blur),
- /* dx = */ 0,
- /* dy = */ 0,
- textShadowColor);
-
- // Update shape app icon name text color.
- for (int id : mShapeIconAppNameIds) {
- TextView appName = mContentView.findViewById(id);
- appName.setTextColor(textColor);
- appName.setShadowLayer(
- mContext.getResources().getDimension(
- R.dimen.preview_theme_app_name_key_ambient_shadow_blur),
- /* dx = */ 0,
- /* dy = */ 0,
- textShadowColor);
- }
-
- mHasWallpaperColorSet = true;
- showPreviewIfHasAllConfigSet();
- }
-
- @OnLifecycleEvent(Lifecycle.Event.ON_RESUME)
- @MainThread
- public void onResume() {
- mTicker = TimeTicker.registerNewReceiver(mContext, this::updateTime);
- updateTime();
- }
-
- @OnLifecycleEvent(Lifecycle.Event.ON_PAUSE)
- @MainThread
- public void onPause() {
- if (mContext != null) {
- mContext.unregisterReceiver(mTicker);
- }
- }
-
- private void showPreviewIfHasAllConfigSet() {
- if (mHasPreviewInfoSet && mHasWallpaperColorSet
- && mContentView.getVisibility() != View.VISIBLE) {
- mContentView.setAlpha(0f);
- mContentView.setVisibility(View.VISIBLE);
- mContentView.animate().alpha(1f)
- .setStartDelay(50)
- .setDuration(200)
- .setInterpolator(AnimationUtils.loadInterpolator(mContext,
- android.R.interpolator.fast_out_linear_in))
- .start();
- }
- }
-
- private void setHeadlineFont(Typeface headlineFont) {
- mStatusBarClock.setTypeface(headlineFont);
- mSmartSpaceDate.setTypeface(headlineFont);
-
- // Update font of color/icons section title.
- TextView colorIconsSectionTitle = mContentView.findViewById(R.id.color_icons_section_title);
- colorIconsSectionTitle.setTypeface(headlineFont);
- }
-
- private void setBodyFont(Typeface bodyFont) {
- // Update font of app names.
- for (int id : mShapeIconAppNameIds) {
- TextView appName = mContentView.findViewById(id);
- appName.setTypeface(bodyFont);
- }
- }
-
- private void setTopBarIcons(List<Drawable> icons) {
- ViewGroup iconsContainer = mContentView.findViewById(R.id.theme_preview_top_bar_icons);
- for (int i = 0; i < iconsContainer.getChildCount(); i++) {
- int iconIndex = sTopBarIconToPreviewIcon[i];
- if (iconIndex < icons.size()) {
- ((ImageView) iconsContainer.getChildAt(i))
- .setImageDrawable(icons.get(iconIndex).getConstantState()
- .newDrawable().mutate());
- } else {
- iconsContainer.getChildAt(i).setVisibility(View.GONE);
- }
- }
- }
-
- private void setAppIconShape(List<ShapeAppIcon> appIcons) {
- for (int i = 0; i < mShapeAppIconIds.length && i < mShapeIconAppNameIds.length
- && i < appIcons.size(); i++) {
- ShapeAppIcon icon = appIcons.get(i);
- // Set app icon.
- ImageView iconView = mContentView.findViewById(mShapeAppIconIds[i]);
- iconView.setBackground(icon.getDrawableCopy());
- // Set app name.
- TextView appName = mContentView.findViewById(mShapeIconAppNameIds[i]);
- appName.setText(icon.getAppName());
- }
- }
-
- private void setColorAndIconsSection(List<Drawable> icons, Drawable shapeDrawable,
- int accentColor) {
- // Set QS icons and background.
- for (int i = 0; i < mColorTileIconIds.length && i < icons.size(); i++) {
- Drawable icon = icons.get(mColorTileIconIds[i][1]).getConstantState()
- .newDrawable().mutate();
- Drawable bgShape = shapeDrawable.getConstantState().newDrawable();
- bgShape.setTint(accentColor);
-
- ImageView bg = mContentView.findViewById(mColorTileIds[i]);
- bg.setImageDrawable(bgShape);
- ImageView fg = mContentView.findViewById(mColorTileIconIds[i][0]);
- fg.setImageDrawable(icon);
- }
-
- // Set color for Buttons (CheckBox, RadioButton, and Switch).
- ColorStateList tintList = getColorStateList(accentColor);
- for (int mColorButtonId : mColorButtonIds) {
- CompoundButton button = mContentView.findViewById(mColorButtonId);
- button.setButtonTintList(tintList);
- if (button instanceof Switch) {
- ((Switch) button).setThumbTintList(tintList);
- ((Switch) button).setTrackTintList(tintList);
- }
- }
- }
-
- private void setColorAndIconsBoxRadius(int cornerRadius) {
- ((CardView) mContentView.findViewById(R.id.color_icons_section)).setRadius(cornerRadius);
- }
-
- private void setQsbRadius(int cornerRadius) {
- View qsb = mContentView.findViewById(R.id.theme_qsb);
- if (qsb != null && qsb.getVisibility() == View.VISIBLE) {
- if (qsb.getBackground() instanceof GradientDrawable) {
- GradientDrawable bg = (GradientDrawable) qsb.getBackground();
- float radius = useRoundedQSB(cornerRadius)
- ? (float) qsb.getLayoutParams().height / 2 : cornerRadius;
- bg.setCornerRadii(new float[]{
- radius, radius, radius, radius,
- radius, radius, radius, radius});
- }
- }
- }
-
- private void updateTime() {
- Calendar calendar = Calendar.getInstance(TimeZone.getDefault());
- if (mStatusBarClock != null) {
- mStatusBarClock.setText(TimeUtils.getFormattedTime(mContext, calendar));
- }
- if (mSmartSpaceDate != null) {
- String datePattern =
- DateFormat.getBestDateTimePattern(Locale.getDefault(), DATE_FORMAT);
- mSmartSpaceDate.setText(DateFormat.format(datePattern, calendar));
- }
- }
-
- private boolean useRoundedQSB(int cornerRadius) {
- return cornerRadius >= mContext.getResources().getDimensionPixelSize(
- R.dimen.roundCornerThreshold);
- }
-
- private ColorStateList getColorStateList(int accentColor) {
- int controlGreyColor =
- ResourceUtils.getColorAttr(mContext, android.R.attr.textColorTertiary);
- return new ColorStateList(
- new int[][]{
- new int[]{android.R.attr.state_selected},
- new int[]{android.R.attr.state_checked},
- new int[]{-android.R.attr.state_enabled},
- },
- new int[] {
- accentColor,
- accentColor,
- controlGreyColor
- }
- );
- }
-
- /**
- * Gets the screen height which does not include the system status bar and bottom navigation
- * bar.
- */
- private int getDisplayHeight() {
- final DisplayMetrics dm = mContext.getResources().getDisplayMetrics();
- return dm.heightPixels;
- }
-
- // The height of top tool bar (R.layout.section_header).
- private int getTopToolBarHeight() {
- final TypedValue typedValue = new TypedValue();
- return mContext.getTheme().resolveAttribute(
- android.R.attr.actionBarSize, typedValue, true)
- ? TypedValue.complexToDimensionPixelSize(
- typedValue.data, mContext.getResources().getDisplayMetrics())
- : 0;
- }
-
- private int getFullPreviewCardHeight() {
- final Resources res = mContext.getResources();
- return getDisplayHeight()
- - getTopToolBarHeight()
- - res.getDimensionPixelSize(R.dimen.bottom_actions_height)
- - res.getDimensionPixelSize(R.dimen.full_preview_page_default_padding_top)
- - res.getDimensionPixelSize(R.dimen.full_preview_page_default_padding_bottom);
- }
-}
diff --git a/src/com/android/customization/widget/OptionSelectorController.java b/src/com/android/customization/widget/OptionSelectorController.java
deleted file mode 100644
index 8c7af00..0000000
--- a/src/com/android/customization/widget/OptionSelectorController.java
+++ /dev/null
@@ -1,469 +0,0 @@
-/*
- * Copyright (C) 2018 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.customization.widget;
-
-import static com.android.internal.util.Preconditions.checkNotNull;
-
-import android.content.Context;
-import android.content.res.Resources;
-import android.graphics.Rect;
-import android.graphics.drawable.Drawable;
-import android.graphics.drawable.LayerDrawable;
-import android.text.TextUtils;
-import android.util.DisplayMetrics;
-import android.util.TypedValue;
-import android.view.Gravity;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.view.ViewGroup;
-import android.view.WindowManager;
-import android.view.accessibility.AccessibilityEvent;
-import android.widget.TextView;
-
-import androidx.annotation.Dimension;
-import androidx.annotation.IntDef;
-import androidx.annotation.NonNull;
-import androidx.recyclerview.widget.GridLayoutManager;
-import androidx.recyclerview.widget.LinearLayoutManager;
-import androidx.recyclerview.widget.RecyclerView;
-import androidx.recyclerview.widget.RecyclerViewAccessibilityDelegate;
-
-import com.android.customization.model.CustomizationManager;
-import com.android.customization.model.CustomizationOption;
-import com.android.wallpaper.R;
-
-import java.util.HashSet;
-import java.util.List;
-import java.util.Set;
-
-/**
- * Simple controller for a RecyclerView-based widget to hold the options for each customization
- * section (eg, thumbnails for themes, clocks, grid sizes).
- * To use, just pass the RV that will contain the tiles and the list of {@link CustomizationOption}
- * representing each option, and call {@link #initOptions(CustomizationManager)} to populate the
- * widget.
- */
-public class OptionSelectorController<T extends CustomizationOption<T>> {
-
- /**
- * Interface to be notified when an option is selected by the user.
- */
- public interface OptionSelectedListener {
-
- /**
- * Called when an option has been selected (and marked as such in the UI)
- */
- void onOptionSelected(CustomizationOption selected);
- }
-
- @IntDef({CheckmarkStyle.NONE, CheckmarkStyle.CORNER, CheckmarkStyle.CENTER,
- CheckmarkStyle.CENTER_CHANGE_COLOR_WHEN_NOT_SELECTED})
- public @interface CheckmarkStyle {
- int NONE = 0;
- int CORNER = 1;
- int CENTER = 2;
- int CENTER_CHANGE_COLOR_WHEN_NOT_SELECTED = 3;
- }
-
- private final float mLinearLayoutHorizontalDisplayOptionsMax;
-
- private final RecyclerView mContainer;
- private final List<T> mOptions;
- private final boolean mUseGrid;
- @CheckmarkStyle
- private final int mCheckmarkStyle;
-
- private final Set<OptionSelectedListener> mListeners = new HashSet<>();
- private RecyclerView.Adapter<TileViewHolder> mAdapter;
- private T mSelectedOption;
- private T mAppliedOption;
-
- public OptionSelectorController(RecyclerView container, List<T> options) {
- this(container, options, true, CheckmarkStyle.CORNER);
- }
-
- public OptionSelectorController(RecyclerView container, List<T> options,
- boolean useGrid, @CheckmarkStyle int checkmarkStyle) {
- mContainer = container;
- mOptions = options;
- mUseGrid = useGrid;
- mCheckmarkStyle = checkmarkStyle;
- TypedValue typedValue = new TypedValue();
- mContainer.getResources().getValue(R.dimen.linear_layout_horizontal_display_options_max,
- typedValue, true);
- mLinearLayoutHorizontalDisplayOptionsMax = typedValue.getFloat();
- }
-
- public void addListener(OptionSelectedListener listener) {
- mListeners.add(listener);
- }
-
- public void removeListener(OptionSelectedListener listener) {
- mListeners.remove(listener);
- }
-
- /**
- * Mark the given option as selected
- */
- public void setSelectedOption(T option) {
- if (!mOptions.contains(option)) {
- throw new IllegalArgumentException("Invalid option");
- }
- T lastSelectedOption = mSelectedOption;
- mSelectedOption = option;
- mAdapter.notifyItemChanged(mOptions.indexOf(option));
- if (lastSelectedOption != null) {
- mAdapter.notifyItemChanged(mOptions.indexOf(lastSelectedOption));
- }
- notifyListeners();
- }
-
- /**
- * @return whether this controller contains the given option
- */
- public boolean containsOption(T option) {
- return mOptions.contains(option);
- }
-
- /**
- * Mark an option as the one which is currently applied on the device. This will result in a
- * check being displayed in the lower-right corner of the corresponding ViewHolder.
- */
- public void setAppliedOption(T option) {
- if (!mOptions.contains(option)) {
- throw new IllegalArgumentException("Invalid option");
- }
- T lastAppliedOption = mAppliedOption;
- mAppliedOption = option;
- mAdapter.notifyItemChanged(mOptions.indexOf(option));
- if (lastAppliedOption != null) {
- mAdapter.notifyItemChanged(mOptions.indexOf(lastAppliedOption));
- }
- }
-
- /**
- * Notify that a given option has changed.
- *
- * @param option the option that changed
- */
- public void optionChanged(T option) {
- if (!mOptions.contains(option)) {
- throw new IllegalArgumentException("Invalid option");
- }
- mAdapter.notifyItemChanged(mOptions.indexOf(option));
- }
-
- /**
- * Initializes the UI for the options passed in the constructor of this class.
- */
- public void initOptions(final CustomizationManager<T> manager) {
- mContainer.setAccessibilityDelegateCompat(
- new OptionSelectorAccessibilityDelegate(mContainer));
-
- mAdapter = new RecyclerView.Adapter<TileViewHolder>() {
- @Override
- public int getItemViewType(int position) {
- return mOptions.get(position).getLayoutResId();
- }
-
- @NonNull
- @Override
- public TileViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
- View v = LayoutInflater.from(parent.getContext()).inflate(viewType, parent, false);
- // Provide width constraint when a grid layout manager is not use and width is set
- // to match parent
- if (!mUseGrid
- && v.getLayoutParams().width == RecyclerView.LayoutParams.MATCH_PARENT) {
- Resources res = mContainer.getContext().getResources();
- RecyclerView.LayoutParams layoutParams = new RecyclerView.LayoutParams(
- res.getDimensionPixelSize(R.dimen.option_tile_width),
- RecyclerView.LayoutParams.WRAP_CONTENT);
- v.setLayoutParams(layoutParams);
- }
- return new TileViewHolder(v);
- }
-
- @Override
- public void onBindViewHolder(@NonNull TileViewHolder holder, int position) {
- T option = mOptions.get(position);
- if (option.isActive(manager)) {
- mAppliedOption = option;
- if (mSelectedOption == null) {
- mSelectedOption = option;
- }
- }
- if (holder.labelView != null) {
- holder.labelView.setText(option.getTitle());
- }
- holder.itemView.setActivated(option.equals(mSelectedOption));
- option.bindThumbnailTile(holder.tileView);
- holder.itemView.setOnClickListener(view -> setSelectedOption(option));
-
- Resources res = mContainer.getContext().getResources();
- if (mCheckmarkStyle == CheckmarkStyle.CORNER && option.equals(mAppliedOption)) {
- drawCheckmark(option, holder,
- res.getDrawable(R.drawable.check_circle_accent_24dp,
- mContainer.getContext().getTheme()),
- Gravity.BOTTOM | Gravity.RIGHT,
- res.getDimensionPixelSize(R.dimen.check_size),
- res.getDimensionPixelOffset(R.dimen.check_offset), true);
- } else if (mCheckmarkStyle == CheckmarkStyle.CENTER
- && option.equals(mAppliedOption)) {
- drawCheckmark(option, holder,
- res.getDrawable(R.drawable.check_circle_grey_large,
- mContainer.getContext().getTheme()),
- Gravity.CENTER, res.getDimensionPixelSize(R.dimen.center_check_size),
- 0, true);
- } else if (mCheckmarkStyle == CheckmarkStyle.CENTER_CHANGE_COLOR_WHEN_NOT_SELECTED
- && option.equals(mAppliedOption)) {
- int drawableRes = option.equals(mSelectedOption)
- ? R.drawable.check_circle_grey_large
- : R.drawable.check_circle_grey_large_not_select;
- drawCheckmark(option, holder,
- res.getDrawable(drawableRes,
- mContainer.getContext().getTheme()),
- Gravity.CENTER, res.getDimensionPixelSize(R.dimen.center_check_size),
- 0, option.equals(mSelectedOption));
- } else if (option.equals(mAppliedOption)) {
- // Initialize with "previewed" description if we don't show checkmark
- holder.setContentDescription(mContainer.getContext(), option,
- R.string.option_previewed_description);
- } else if (mCheckmarkStyle != CheckmarkStyle.NONE) {
- if (mCheckmarkStyle == CheckmarkStyle.CENTER_CHANGE_COLOR_WHEN_NOT_SELECTED) {
- if (option.equals(mSelectedOption)) {
- holder.setContentDescription(mContainer.getContext(), option,
- R.string.option_previewed_description);
- } else {
- holder.setContentDescription(mContainer.getContext(), option,
- R.string.option_change_applied_previewed_description);
- }
- }
-
- holder.tileView.setForeground(null);
- }
- }
-
- @Override
- public int getItemCount() {
- return mOptions.size();
- }
-
- private void drawCheckmark(CustomizationOption<?> option, TileViewHolder holder,
- Drawable checkmark, int gravity, @Dimension int checkSize,
- @Dimension int checkOffset, boolean currentlyPreviewed) {
- Drawable frame = holder.tileView.getForeground();
- Drawable[] layers = {frame, checkmark};
- if (frame == null) {
- layers = new Drawable[]{checkmark};
- }
- LayerDrawable checkedFrame = new LayerDrawable(layers);
-
- // Position according to the given gravity and offset
- int idx = layers.length - 1;
- checkedFrame.setLayerGravity(idx, gravity);
- checkedFrame.setLayerWidth(idx, checkSize);
- checkedFrame.setLayerHeight(idx, checkSize);
- checkedFrame.setLayerInsetBottom(idx, checkOffset);
- checkedFrame.setLayerInsetRight(idx, checkOffset);
- holder.tileView.setForeground(checkedFrame);
-
- // Initialize the currently applied option
- if (currentlyPreviewed) {
- holder.setContentDescription(mContainer.getContext(), option,
- R.string.option_applied_previewed_description);
- } else {
- holder.setContentDescription(mContainer.getContext(), option,
- R.string.option_applied_description);
- }
- }
- };
-
- Resources res = mContainer.getContext().getResources();
- mContainer.setAdapter(mAdapter);
- final DisplayMetrics metrics = new DisplayMetrics();
- mContainer.getContext().getSystemService(WindowManager.class)
- .getDefaultDisplay().getMetrics(metrics);
- final boolean hasDecoration = mContainer.getItemDecorationCount() != 0;
-
- if (mUseGrid) {
- int numColumns = res.getInteger(R.integer.options_grid_num_columns);
- GridLayoutManager gridLayoutManager = new GridLayoutManager(mContainer.getContext(),
- numColumns);
- mContainer.setLayoutManager(gridLayoutManager);
- } else {
- final int padding = res.getDimensionPixelSize(
- R.dimen.option_tile_linear_padding_horizontal);
- final int widthPerItem = res.getDimensionPixelSize(R.dimen.option_tile_width) + (
- hasDecoration ? 0 : 2 * padding);
- mContainer.setLayoutManager(new LinearLayoutManager(mContainer.getContext(),
- LinearLayoutManager.HORIZONTAL, false));
- mContainer.measure(View.MeasureSpec.UNSPECIFIED, View.MeasureSpec.UNSPECIFIED);
- int availableWidth = metrics.widthPixels;
- int extraSpace = availableWidth - mContainer.getMeasuredWidth();
- if (extraSpace >= 0) {
- mContainer.setOverScrollMode(View.OVER_SCROLL_NEVER);
- }
-
- if (mAdapter.getItemCount() >= mLinearLayoutHorizontalDisplayOptionsMax) {
- int spaceBetweenItems = availableWidth
- - Math.round(widthPerItem * mLinearLayoutHorizontalDisplayOptionsMax)
- - mContainer.getPaddingLeft();
- int itemEndMargin =
- spaceBetweenItems / (int) mLinearLayoutHorizontalDisplayOptionsMax;
- itemEndMargin = Math.max(itemEndMargin, res.getDimensionPixelOffset(
- R.dimen.option_tile_margin_horizontal));
- mContainer.addItemDecoration(new ItemEndHorizontalSpaceItemDecoration(
- mContainer.getContext(), itemEndMargin));
- return;
- }
-
- int spaceBetweenItems = extraSpace / (mAdapter.getItemCount() + 1);
- int itemSideMargin = spaceBetweenItems / 2;
- mContainer.addItemDecoration(new HorizontalSpacerItemDecoration(itemSideMargin));
- }
- }
-
- public void resetOptions(List<T> options) {
- mOptions.clear();
- mOptions.addAll(options);
- mAdapter.notifyDataSetChanged();
- }
-
- private void notifyListeners() {
- if (mListeners.isEmpty()) {
- return;
- }
- T option = mSelectedOption;
- Set<OptionSelectedListener> iterableListeners = new HashSet<>(mListeners);
- for (OptionSelectedListener listener : iterableListeners) {
- listener.onOptionSelected(option);
- }
- }
-
- private static class TileViewHolder extends RecyclerView.ViewHolder {
- TextView labelView;
- View tileView;
- CharSequence title;
-
- TileViewHolder(@NonNull View itemView) {
- super(itemView);
- labelView = itemView.findViewById(R.id.option_label);
- tileView = itemView.findViewById(R.id.option_tile);
- title = null;
- }
-
- /**
- * Set the content description for this holder using the given string id.
- * If the option does not have a label, the description will be set on the tile view.
- *
- * @param context The view's context
- * @param option The customization option
- * @param id Resource ID of the string to use for the content description
- */
- public void setContentDescription(Context context, CustomizationOption<?> option, int id) {
- title = option.getTitle();
- if (TextUtils.isEmpty(title) && tileView != null) {
- title = tileView.getContentDescription();
- }
-
- CharSequence cd = context.getString(id, title);
- if (labelView != null && !TextUtils.isEmpty(labelView.getText())) {
- labelView.setAccessibilityPaneTitle(cd);
- labelView.setContentDescription(cd);
- } else if (tileView != null) {
- tileView.setAccessibilityPaneTitle(cd);
- tileView.setContentDescription(cd);
- }
- }
-
- public void resetContentDescription() {
- if (labelView != null && !TextUtils.isEmpty(labelView.getText())) {
- labelView.setAccessibilityPaneTitle(title);
- labelView.setContentDescription(title);
- } else if (tileView != null) {
- tileView.setAccessibilityPaneTitle(title);
- tileView.setContentDescription(title);
- }
- }
- }
-
- private class OptionSelectorAccessibilityDelegate extends RecyclerViewAccessibilityDelegate {
-
- OptionSelectorAccessibilityDelegate(RecyclerView recyclerView) {
- super(recyclerView);
- }
-
- @Override
- public boolean onRequestSendAccessibilityEvent(
- ViewGroup host, View child, AccessibilityEvent event) {
-
- // Apply this workaround to horizontal recyclerview only,
- // since the symptom is TalkBack will lose focus when navigating horizontal list items.
- if (mContainer.getLayoutManager() != null
- && mContainer.getLayoutManager().canScrollHorizontally()
- && event.getEventType() == AccessibilityEvent.TYPE_VIEW_ACCESSIBILITY_FOCUSED) {
- int itemPos = mContainer.getChildLayoutPosition(child);
- int itemWidth = mContainer.getContext().getResources()
- .getDimensionPixelOffset(R.dimen.option_tile_width);
- int itemMarginHorizontal = mContainer.getContext().getResources()
- .getDimensionPixelOffset(R.dimen.option_tile_margin_horizontal) * 2;
- int scrollOffset = itemWidth + itemMarginHorizontal;
-
- // Make focusing item's previous/next item totally visible when changing focus,
- // ensure TalkBack won't lose focus when recyclerview scrolling.
- if (itemPos >= ((LinearLayoutManager) mContainer.getLayoutManager())
- .findLastCompletelyVisibleItemPosition()) {
- mContainer.scrollBy(scrollOffset, 0);
- } else if (itemPos <= ((LinearLayoutManager) mContainer.getLayoutManager())
- .findFirstCompletelyVisibleItemPosition() && itemPos != 0) {
- mContainer.scrollBy(-scrollOffset, 0);
- }
- }
- return super.onRequestSendAccessibilityEvent(host, child, event);
- }
- }
-
- /** Custom ItemDecorator to add specific spacing between items in the list. */
- private static final class ItemEndHorizontalSpaceItemDecoration
- extends RecyclerView.ItemDecoration {
- private final int mHorizontalSpacePx;
- private final boolean mDirectionLTR;
-
- private ItemEndHorizontalSpaceItemDecoration(Context context, int horizontalSpacePx) {
- mDirectionLTR = context.getResources().getConfiguration().getLayoutDirection()
- == View.LAYOUT_DIRECTION_LTR;
- mHorizontalSpacePx = horizontalSpacePx;
- }
-
- @Override
- public void getItemOffsets(Rect outRect, View view, RecyclerView recyclerView,
- RecyclerView.State state) {
- if (recyclerView.getAdapter() == null) {
- return;
- }
-
- if (recyclerView.getChildAdapterPosition(view)
- != checkNotNull(recyclerView.getAdapter()).getItemCount() - 1) {
- // Don't add spacing behind the last item
- if (mDirectionLTR) {
- outRect.right = mHorizontalSpacePx;
- } else {
- outRect.left = mHorizontalSpacePx;
- }
- }
- }
- }
-}
diff --git a/tests/common/src/com/android/customization/testing/TestCustomizationInjector.kt b/tests/common/src/com/android/customization/testing/TestCustomizationInjector.kt
index e610818..cd587d6 100644
--- a/tests/common/src/com/android/customization/testing/TestCustomizationInjector.kt
+++ b/tests/common/src/com/android/customization/testing/TestCustomizationInjector.kt
@@ -3,10 +3,6 @@
import android.content.Context
import android.content.res.Resources
import androidx.activity.ComponentActivity
-import androidx.fragment.app.FragmentActivity
-import com.android.customization.model.theme.OverlayManagerCompat
-import com.android.customization.model.theme.ThemeBundleProvider
-import com.android.customization.model.theme.ThemeManager
import com.android.customization.module.CustomizationInjector
import com.android.customization.module.CustomizationPreferences
import com.android.customization.module.ThemesUserEventLogger
@@ -29,7 +25,6 @@
@Singleton
open class TestCustomizationInjector @Inject constructor() : TestInjector(), CustomizationInjector {
private var customizationPrefs: CustomizationPreferences? = null
- private var themeManager: ThemeManager? = null
private var themesUserEventLogger: ThemesUserEventLogger? = null
/////////////////
@@ -41,18 +36,6 @@
?: TestDefaultCustomizationPreferences(context).also { customizationPrefs = it }
}
- override fun getThemeManager(
- provider: ThemeBundleProvider,
- activity: FragmentActivity,
- overlayManagerCompat: OverlayManagerCompat,
- logger: ThemesUserEventLogger,
- ): ThemeManager {
- return themeManager
- ?: TestThemeManager(provider, activity, overlayManagerCompat, logger).also {
- themeManager = it
- }
- }
-
override fun getKeyguardQuickAffordancePickerInteractor(
context: Context
): KeyguardQuickAffordancePickerInteractor {
diff --git a/tests/common/src/com/android/customization/testing/TestThemeManager.java b/tests/common/src/com/android/customization/testing/TestThemeManager.java
deleted file mode 100644
index 5175b24..0000000
--- a/tests/common/src/com/android/customization/testing/TestThemeManager.java
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- * 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.
- */
-package com.android.customization.testing;
-
-import androidx.fragment.app.FragmentActivity;
-
-import com.android.customization.model.theme.OverlayManagerCompat;
-import com.android.customization.model.theme.ThemeBundleProvider;
-import com.android.customization.model.theme.ThemeManager;
-import com.android.customization.module.ThemesUserEventLogger;
-
-/**
- * Test implementation of {@link ThemeManager}.
- */
-public class TestThemeManager extends ThemeManager {
-
- private static boolean sIsAvailable;
-
- public TestThemeManager(
- ThemeBundleProvider provider,
- FragmentActivity activity,
- OverlayManagerCompat overlayManagerCompat,
- ThemesUserEventLogger logger) {
- super(provider, activity, overlayManagerCompat, logger);
- }
-
- @Override
- public boolean isAvailable() {
- return sIsAvailable;
- }
-
- public static void setAvailable(boolean available) {
- sIsAvailable = available;
- }
-}
diff --git a/tests/common/src/com/android/customization/testing/TestThemesUserEventLogger.java b/tests/common/src/com/android/customization/testing/TestThemesUserEventLogger.java
index 22a5b94..26fd22f 100644
--- a/tests/common/src/com/android/customization/testing/TestThemesUserEventLogger.java
+++ b/tests/common/src/com/android/customization/testing/TestThemesUserEventLogger.java
@@ -17,7 +17,6 @@
import com.android.customization.model.color.ColorOption;
import com.android.customization.model.grid.GridOption;
-import com.android.customization.model.theme.ThemeBundle;
import com.android.customization.module.ThemesUserEventLogger;
import com.android.wallpaper.testing.TestUserEventLogger;
@@ -27,16 +26,6 @@
public class TestThemesUserEventLogger extends TestUserEventLogger
implements ThemesUserEventLogger {
@Override
- public void logThemeSelected(ThemeBundle theme, boolean isCustomTheme) {
- // Do nothing.
- }
-
- @Override
- public void logThemeApplied(ThemeBundle theme, boolean isCustomTheme) {
- // Do nothing.
- }
-
- @Override
public void logColorApplied(int action, ColorOption colorOption) {
// Do nothing.
}
diff --git a/tests/robotests/src/com/android/customization/model/theme/ThemeManagerTest.java b/tests/robotests/src/com/android/customization/model/theme/ThemeManagerTest.java
deleted file mode 100644
index cfb8a33..0000000
--- a/tests/robotests/src/com/android/customization/model/theme/ThemeManagerTest.java
+++ /dev/null
@@ -1,222 +0,0 @@
-/*
- * 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.
- */
-package com.android.customization.model.theme;
-
-import static com.android.customization.model.ResourceConstants.ANDROID_PACKAGE;
-import static com.android.customization.model.ResourceConstants.OVERLAY_CATEGORY_COLOR;
-import static com.android.customization.model.ResourceConstants.OVERLAY_CATEGORY_FONT;
-import static com.android.customization.model.ResourceConstants.OVERLAY_CATEGORY_ICON_ANDROID;
-import static com.android.customization.model.ResourceConstants.OVERLAY_CATEGORY_ICON_SETTINGS;
-import static com.android.customization.model.ResourceConstants.OVERLAY_CATEGORY_ICON_SYSUI;
-import static com.android.customization.model.ResourceConstants.OVERLAY_CATEGORY_SHAPE;
-import static com.android.customization.model.ResourceConstants.SETTINGS_PACKAGE;
-import static com.android.customization.model.ResourceConstants.SYSUI_PACKAGE;
-import static com.android.customization.model.ResourceConstants.THEME_SETTING;
-
-import static junit.framework.Assert.assertFalse;
-import static junit.framework.Assert.assertTrue;
-import static junit.framework.TestCase.assertEquals;
-
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.spy;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
-
-import android.provider.Settings;
-
-import androidx.annotation.Nullable;
-import androidx.fragment.app.FragmentActivity;
-
-import com.android.customization.model.CustomizationManager.Callback;
-import com.android.customization.model.CustomizationManager.OptionsFetchedListener;
-import com.android.customization.model.theme.custom.CustomTheme;
-import com.android.customization.module.ThemesUserEventLogger;
-import com.android.customization.testutils.OverlayManagerMocks;
-
-import org.json.JSONObject;
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
-import org.robolectric.Robolectric;
-import org.robolectric.RobolectricTestRunner;
-
-@RunWith(RobolectricTestRunner.class)
-public class ThemeManagerTest {
-
- @Mock OverlayManagerCompat mMockOm;
- @Mock ThemesUserEventLogger mThemesUserEventLogger;
- @Mock ThemeBundleProvider mThemeBundleProvider;
- private OverlayManagerMocks mMockOmHelper;
- private ThemeManager mThemeManager;
- private FragmentActivity mActivity;
-
- @Before
- public void setUp() {
- MockitoAnnotations.initMocks(this);
- FragmentActivity activity = Robolectric.buildActivity(FragmentActivity.class).get();
- mActivity = spy(activity);
- mMockOmHelper = new OverlayManagerMocks();
- mMockOmHelper.setUpMock(mMockOm);
- mThemeManager = new ThemeManager(mThemeBundleProvider, activity,
- mMockOm, mThemesUserEventLogger);
- }
-
- @After
- public void cleanUp() {
- mMockOmHelper.clearOverlays();
- }
-
- @Test
- public void apply_WithDefaultTheme_StoresEmptyJsonString() {
- mMockOmHelper.addOverlay("test.package.name_color", ANDROID_PACKAGE,
- OVERLAY_CATEGORY_COLOR, true, 0);
- mMockOmHelper.addOverlay("test.package.name_font", ANDROID_PACKAGE,
- OVERLAY_CATEGORY_FONT, true, 0);
- mMockOmHelper.addOverlay("test.package.name_shape", ANDROID_PACKAGE,
- OVERLAY_CATEGORY_SHAPE, true, 0);
- mMockOmHelper.addOverlay("test.package.name_icon", ANDROID_PACKAGE,
- OVERLAY_CATEGORY_ICON_ANDROID, true, 0);
- mMockOmHelper.addOverlay("test.package.name_settings", SETTINGS_PACKAGE,
- OVERLAY_CATEGORY_ICON_SETTINGS, true, 0);
- mMockOmHelper.addOverlay("test.package.name_sysui", SYSUI_PACKAGE,
- OVERLAY_CATEGORY_ICON_SYSUI, true, 0);
- mMockOmHelper.addOverlay("test.package.name_themepicker", mActivity.getPackageName(),
- OVERLAY_CATEGORY_ICON_SYSUI, true, 0);
-
- ThemeBundle defaultTheme = new ThemeBundle.Builder().asDefault().build(mActivity);
-
- applyTheme(defaultTheme);
-
- assertEquals("Secure Setting should be empty JSON string after applying default theme",
- new JSONObject().toString(),
- Settings.Secure.getString(mActivity.getContentResolver(), THEME_SETTING));
- }
-
- @Test
- public void apply_WithOverlayTheme_StoresSerializedPackagesWithTimestamp() {
- ThemeBundle theme = getOverlayTheme();
- final String serializedPackagesWithTimestamp = theme.getSerializedPackagesWithTimestamp();
-
- theme = spy(theme);
- // Makes it return the fixed serializedPackagesWithTimestamp to test. Since we will get
- // fresh time every time, it's hard to compare for testing.
- when(theme.getSerializedPackagesWithTimestamp())
- .thenReturn(serializedPackagesWithTimestamp);
-
- applyTheme(theme);
-
- assertEquals("Secure Setting should be the overlay packages after applying theme",
- serializedPackagesWithTimestamp,
- Settings.Secure.getString(mActivity.getContentResolver(), THEME_SETTING));
- }
-
- @Test
- public void isAvailable_ThemeBundleProviderAndOverlayManagerAreAvailable_ReturnsTrue() {
- when(mThemeBundleProvider.isAvailable()).thenReturn(true);
- when(mMockOm.isAvailable()).thenReturn(true);
-
- assertTrue(mThemeManager.isAvailable());
- }
-
- @Test
- public void isAvailable_ThemeBundleProviderOrOverlayManagerIsAvailable_ReturnsFalse() {
- when(mThemeBundleProvider.isAvailable()).thenReturn(false);
- when(mMockOm.isAvailable()).thenReturn(true);
- assertFalse(mThemeManager.isAvailable());
-
- when(mThemeBundleProvider.isAvailable()).thenReturn(true);
- when(mMockOm.isAvailable()).thenReturn(false);
- assertFalse(mThemeManager.isAvailable());
- }
-
- @Test
- public void fetchOptions_ThemeBundleProviderFetches() {
- OptionsFetchedListener listener = mock(OptionsFetchedListener.class);
-
- mThemeManager.fetchOptions(listener, false);
-
- verify(mThemeBundleProvider).fetch(listener, false);
- }
-
- @Test
- public void removeCustomTheme_ThemeBundleProviderRemovesCustomTheme() {
- CustomTheme customTheme = mock(CustomTheme.class);
- mThemeManager.removeCustomTheme(customTheme);
-
- verify(mThemeBundleProvider).removeCustomTheme(customTheme);
- }
-
- @Test
- public void findThemeByPackages_ThemeBundleProviderFindsEquivalent() {
- CustomTheme theme = mock(CustomTheme.class);
- mThemeManager.findThemeByPackages(theme);
-
- verify(mThemeBundleProvider).findEquivalent(theme);
- }
-
- @Test
- public void storeEmptyTheme_SettingsSecureStoresEmptyTheme() {
- mThemeManager.storeEmptyTheme();
-
- assertEquals(
- new JSONObject().toString(),
- Settings.Secure.getString(mActivity.getContentResolver(), THEME_SETTING));
- }
-
- @Test
- public void getStoredOverlays_GetsFromSettingsSecureWithExpectedName() {
- ThemeBundle theme = getOverlayTheme();
-
- applyTheme(theme);
-
- assertEquals(
- Settings.Secure.getString(mActivity.getContentResolver(), THEME_SETTING),
- mThemeManager.getStoredOverlays());
- }
-
- private ThemeBundle getOverlayTheme() {
- final String bundleColorPackage = "test.package.name_color";
- final String bundleFontPackage = "test.package.name_font";
- final String otherPackage = "other.package.name_font";
-
- mMockOmHelper.addOverlay(bundleColorPackage, ANDROID_PACKAGE,
- OVERLAY_CATEGORY_COLOR, false, 0);
- mMockOmHelper.addOverlay(bundleFontPackage, ANDROID_PACKAGE,
- OVERLAY_CATEGORY_FONT, false, 0);
- mMockOmHelper.addOverlay(otherPackage, ANDROID_PACKAGE,
- OVERLAY_CATEGORY_FONT, false, 0);
-
- return new ThemeBundle.Builder()
- .addOverlayPackage(OVERLAY_CATEGORY_COLOR, bundleColorPackage)
- .addOverlayPackage(OVERLAY_CATEGORY_FONT, bundleFontPackage)
- .build(mActivity);
- }
-
- private void applyTheme(ThemeBundle theme) {
- mThemeManager.apply(theme, new Callback() {
- @Override
- public void onSuccess() {
- }
-
- @Override
- public void onError(@Nullable Throwable throwable) {
- }
- });
- }
-}