Custom Theme 1/n: initial structure
This CL is just laying out the groundwork, adding a new Activity and
CustomTheme class as well as a few layouts and strings needed on the UI
Bug: 124796742
Change-Id: I458995b208863a9201dd0ef6e935c8ff030587ed
diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index 129f5b9..990f043 100755
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
- package="com.android.wallpaper">
+ package="com.android.wallpaper">
<uses-sdk android:targetSdkVersion="Q" android:minSdkVersion="28"/>
@@ -12,19 +12,24 @@
android:hardwareAccelerated="true"
android:icon="@mipmap/product_logo_wallpapers_launcher_color_48"
android:label="@string/app_name"
- android:theme="@style/CustomizationTheme"
android:requiredForAllUsers="true"
android:restoreAnyVersion="true"
- android:supportsRtl="true">
-
- <activity android:name="com.android.customization.picker.CustomizationPickerActivity"
+ android:supportsRtl="true"
+ android:theme="@style/CustomizationTheme">
+ <activity
+ android:name="com.android.customization.picker.CustomizationPickerActivity"
android:label="@string/app_name"
- android:theme="@style/CustomizationTheme.NoActionBar"
- android:resizeableActivity="true">
+ android:resizeableActivity="true"
+ android:theme="@style/CustomizationTheme.NoActionBar">
<intent-filter>
<action android:name="android.intent.action.SET_WALLPAPER"/>
+
<category android:name="android.intent.category.DEFAULT"/>
</intent-filter>
</activity>
+ <activity android:name="com.android.customization.picker.theme.CustomThemeActivity"
+ android:resizeableActivity="true"
+ android:theme="@style/CustomizationTheme.NoActionBar"/>
</application>
+
</manifest>
diff --git a/res/layout/activity_custom_theme.xml b/res/layout/activity_custom_theme.xml
new file mode 100644
index 0000000..d69d9d7
--- /dev/null
+++ b/res/layout/activity_custom_theme.xml
@@ -0,0 +1,44 @@
+<?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"
+ 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="match_parent"
+ android:layout_marginBottom="@dimen/custom_theme_nav_height"/>
+
+ <FrameLayout
+ android:id="@+id/custom_theme_nav"
+ android:layout_width="match_parent"
+ android:layout_height="@dimen/custom_theme_nav_height">
+ <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>
+</FrameLayout>
diff --git a/res/layout/custom_theme_option.xml b/res/layout/custom_theme_option.xml
new file mode 100644
index 0000000..b249555
--- /dev/null
+++ b/res/layout/custom_theme_option.xml
@@ -0,0 +1,46 @@
+<?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="match_parent"
+ android:orientation="vertical">
+
+ <TextView
+ android:id="@+id/option_label"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_gravity="center_horizontal"
+ android:layout_marginBottom="@dimen/theme_option_label_margin"
+ 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">
+ <TextView
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_gravity="center"
+ android:textSize="@dimen/theme_option_add_size"
+ android:textAlignment="center"
+ android:textColor="?android:colorAccent"
+ android:text="@string/add_custom_theme"/>
+ </FrameLayout>
+</LinearLayout>
diff --git a/res/values/dimens.xml b/res/values/dimens.xml
index 1070deb..5487661 100644
--- a/res/values/dimens.xml
+++ b/res/values/dimens.xml
@@ -37,6 +37,8 @@
<dimen name="theme_option_sample_height">23dp</dimen>
<dimen name="theme_option_sample_width">23dp</dimen>
<dimen name="theme_option_sample_padding">2dp</dimen>
+ <!-- Note, using dp instead of sp as this is just the "+" symbol, not text -->
+ <dimen name="theme_option_add_size">32dp</dimen>
<dimen name="option_tile_padding_vertical">12dp</dimen>
<dimen name="option_tile_padding_horizontal">10dp</dimen>
<!-- Note, using dp instead of sp as this text is more like a "snapshot" of the font -->
@@ -56,4 +58,6 @@
<dimen name="shape_preview_image_width">236dp</dimen>
<dimen name="shape_preview_image_height">153dp</dimen>
+
+ <dimen name="custom_theme_nav_height">56dp</dimen>
</resources>
diff --git a/res/values/strings.xml b/res/values/strings.xml
index e451795..dc5f7f5 100755
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -56,6 +56,9 @@
<!-- Sample text used to show a preview of a selected font [CHAR LIMIT=3] -->
<string name="theme_font_example">ABC</string>
+ <!-- Plus sign used to indicate that the user can add a custom theme -->
+ <string name="add_custom_theme" translatable="false">+</string>
+
<!-- Name for the Android Theme that comes preset with the device [CHAR LIMIT=10]-->
<string name="default_theme_title">Default</string>
@@ -89,4 +92,12 @@
<!-- Message shown when a theme couldn't be applied in the system because of an error
[CHAR LIMIT=NONE] -->
<string name="apply_theme_error_msg">There was a problem applying the style</string>
+
+ <!-- Label for a button that takes the user to the next step when configuring a custom theme.
+ [CHAR LIMIT=20] -->
+ <string name="custom_theme_next">Next</string>
+
+ <!-- Title for a system Style/Theme (combination of fonts/colors/icons) that is defined and
+ customized by the user [CHAR LIMIT=15] -->
+ <string name="custom_theme_title">Custom</string>
</resources>
diff --git a/src/com/android/customization/model/theme/CustomTheme.java b/src/com/android/customization/model/theme/CustomTheme.java
new file mode 100644
index 0000000..289e3e4
--- /dev/null
+++ b/src/com/android/customization/model/theme/CustomTheme.java
@@ -0,0 +1,51 @@
+/*
+ * 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.view.View;
+
+import com.android.wallpaper.R;
+
+import java.util.Map;
+
+public class CustomTheme extends ThemeBundle {
+
+ public CustomTheme(String title, Map<String, String> overlayPackages,
+ PreviewInfo previewInfo) {
+ super(title, overlayPackages, false, null, previewInfo);
+ }
+
+ @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 shouldUseThemeWallpaper() {
+ return false;
+ }
+
+ public boolean isDefined() {
+ return getPreviewInfo() != null;
+ }
+}
diff --git a/src/com/android/customization/model/theme/DefaultThemeProvider.java b/src/com/android/customization/model/theme/DefaultThemeProvider.java
index a2cb95c..3dcb90e 100644
--- a/src/com/android/customization/model/theme/DefaultThemeProvider.java
+++ b/src/com/android/customization/model/theme/DefaultThemeProvider.java
@@ -225,6 +225,7 @@
e);
}
}
+ addCustomTheme();
}
/**
@@ -362,6 +363,11 @@
mThemes.add(builder.build());
}
+ private void addCustomTheme() {
+ mThemes.add(new CustomTheme(mContext.getString(R.string.custom_theme_title),
+ new HashMap<>(), null));
+ }
+
private String getOverlayPackage(String prefix, String themeName) {
return getItemStringFromStub(prefix, themeName);
}
diff --git a/src/com/android/customization/model/theme/ThemeBundle.java b/src/com/android/customization/model/theme/ThemeBundle.java
index 3af25d4..f3ced93 100644
--- a/src/com/android/customization/model/theme/ThemeBundle.java
+++ b/src/com/android/customization/model/theme/ThemeBundle.java
@@ -64,14 +64,14 @@
@Nullable private final WallpaperInfo mWallpaperInfo;
private WallpaperInfo mOverrideWallpaper;
- private ThemeBundle(String title, Map<String, String> overlayPackages,
+ protected ThemeBundle(String title, Map<String, String> overlayPackages,
boolean isDefault, @Nullable WallpaperInfo wallpaperInfo,
PreviewInfo previewInfo) {
mTitle = title;
mIsDefault = isDefault;
mPreviewInfo = previewInfo;
mWallpaperInfo = wallpaperInfo;
- mPackagesByCategory = Collections.unmodifiableMap(overlayPackages);
+ mPackagesByCategory = Collections.unmodifiableMap(overlayPackages);
}
@Override
@@ -127,7 +127,7 @@
mOverrideWallpaper = homeWallpaper;
}
- public boolean useThemeWallpaper() {
+ public boolean shouldUseThemeWallpaper() {
return mOverrideWallpaper == null && mWallpaperInfo != null;
}
diff --git a/src/com/android/customization/model/theme/ThemeManager.java b/src/com/android/customization/model/theme/ThemeManager.java
index e56503b..31e76ca 100644
--- a/src/com/android/customization/model/theme/ThemeManager.java
+++ b/src/com/android/customization/model/theme/ThemeManager.java
@@ -91,7 +91,7 @@
@Override
public void apply(ThemeBundle theme, Callback callback) {
// Set wallpaper
- if (theme.useThemeWallpaper()) {
+ if (theme.shouldUseThemeWallpaper()) {
applyWallpaper(theme, new SetWallpaperCallback() {
@Override
public void onSuccess() {
diff --git a/src/com/android/customization/picker/theme/CustomThemeActivity.java b/src/com/android/customization/picker/theme/CustomThemeActivity.java
new file mode 100644
index 0000000..9ed9f66
--- /dev/null
+++ b/src/com/android/customization/picker/theme/CustomThemeActivity.java
@@ -0,0 +1,52 @@
+/*
+ * 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 androidx.fragment.app.Fragment;
+import androidx.fragment.app.FragmentActivity;
+import androidx.fragment.app.FragmentManager;
+
+import com.android.wallpaper.R;
+import com.android.wallpaper.module.Injector;
+import com.android.wallpaper.module.InjectorProvider;
+import com.android.wallpaper.module.UserEventLogger;
+
+public class CustomThemeActivity extends FragmentActivity {
+
+ private UserEventLogger mUserEventLogger;
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ Injector injector = InjectorProvider.getInjector();
+ mUserEventLogger = injector.getUserEventLogger(this);
+ setContentView(R.layout.activity_custom_theme);
+
+ FragmentManager fm = getSupportFragmentManager();
+ Fragment fragment = fm.findFragmentById(R.id.fragment_container);
+
+ if (fragment == null) {
+ // Navigate to the first step
+ navigateToStep(0);
+ }
+ }
+
+ private void navigateToStep(int i) {
+ //TODO(santie): implement
+ }
+}
diff --git a/src/com/android/customization/picker/theme/ThemeFragment.java b/src/com/android/customization/picker/theme/ThemeFragment.java
index a1d81c3..669f21c 100644
--- a/src/com/android/customization/picker/theme/ThemeFragment.java
+++ b/src/com/android/customization/picker/theme/ThemeFragment.java
@@ -15,11 +15,10 @@
*/
package com.android.customization.picker.theme;
-import static android.app.WallpaperColors.HINT_SUPPORTS_DARK_THEME;
-
import android.app.Activity;
import android.app.WallpaperColors;
import android.content.Context;
+import android.content.Intent;
import android.content.res.ColorStateList;
import android.content.res.Resources;
import android.graphics.Bitmap;
@@ -45,6 +44,7 @@
import androidx.recyclerview.widget.RecyclerView;
import com.android.customization.model.CustomizationManager.Callback;
+import com.android.customization.model.theme.CustomTheme;
import com.android.customization.model.theme.ThemeBundle;
import com.android.customization.model.theme.ThemeBundle.PreviewInfo;
import com.android.customization.model.theme.ThemeManager;
@@ -184,9 +184,13 @@
mOptionsController = new OptionSelectorController(mOptionsContainer, options);
mOptionsController.addListener(selected -> {
- mSelectedTheme = (ThemeBundle) selected;
- mSelectedTheme.setOverrideThemeWallpaper(mCurrentHomeWallpaper);
- createAdapter();
+ if (selected instanceof CustomTheme && !((CustomTheme) selected).isDefined()) {
+ navigateToCustomTheme();
+ } else {
+ mSelectedTheme = (ThemeBundle) selected;
+ mSelectedTheme.setOverrideThemeWallpaper(mCurrentHomeWallpaper);
+ createAdapter();
+ }
});
mOptionsController.initOptions(mThemeManager);
String previouslySelected = savedInstanceState != null
@@ -198,6 +202,7 @@
mSelectedTheme = theme;
} else if (theme.isActive(mThemeManager)) {
mSelectedTheme = theme;
+ break;
}
}
mOptionsController.setSelectedOption(mSelectedTheme);
@@ -205,6 +210,11 @@
createAdapter();
}
+ private void navigateToCustomTheme() {
+ Intent intent = new Intent(getActivity(), CustomThemeActivity.class);
+ startActivity(intent);
+ }
+
private static abstract class ThemePreviewPage extends PreviewPage {
@StringRes final int nameResId;
@DrawableRes final int iconSrc;