diff --git a/res/layout/apply_change_button.xml b/res/layout/apply_change_button.xml
new file mode 100644
index 0000000..9c02665
--- /dev/null
+++ b/res/layout/apply_change_button.xml
@@ -0,0 +1,20 @@
+
+
+
+
+
+
diff --git a/res/values/evolution_arrays.xml b/res/values/evolution_arrays.xml
index 29cc967..196afd0 100644
--- a/res/values/evolution_arrays.xml
+++ b/res/values/evolution_arrays.xml
@@ -968,4 +968,49 @@
- 18
- 19
+
+
+ - @string/status_bar_date_none
+ - @string/calculator
+ - @string/media
+ - @string/clock_timer
+ - @string/torch
+ - @string/weather
+ - @string/wifi
+ - @string/data
+ - @string/ringer
+ - @string/bt
+ - @string/hotspot
+ - @string/wallet
+
+
+
+
+ - calculator
+ - media
+ - timer
+ - torch
+ - weather
+ - wifi
+ - data
+ - ringer
+ - bt
+ - hotspot
+ - wallet
+
+
+
+
+ - @string/lockscreen_widgets_style1
+ - @string/lockscreen_widgets_style2
+ - @string/lockscreen_widgets_style3
+ - @string/lockscreen_widgets_style4
+
+
+
+ - 0
+ - 1
+ - 2
+ - 3
+
diff --git a/res/values/evolution_strings.xml b/res/values/evolution_strings.xml
index 19035b0..9deb2d9 100644
--- a/res/values/evolution_strings.xml
+++ b/res/values/evolution_strings.xml
@@ -126,12 +126,12 @@
About Pulse
Pulse is a brilliant audio graphic equalizer when music plays on the device
Pulse
- Audio graphic equalizer for navigation bar and lockscreen
- Navbar Pulse
+ Audio graphic equalizer for navigation bar and lock screen
+ Navbar pulse
Audio graphic equalizer on the navigation bar
- Lockscreen Pulse
- Audio graphic equalizer on the lockscreen
- Ambient Pulse
+ Lock screen pulse
+ Audio graphic equalizer on the lock screen
+ Ambient pulse
Audio graphic equalizer on the ambient screen
Render mode
Fading blocks
@@ -154,10 +154,10 @@
Block size
Block spacing
-
+
Swipe left or right to preview clock styles
-
+
Selected clock does not support custom fonts
@@ -274,8 +274,8 @@
Display an indicator when an app accesses your location
Screen projection
Display an indicator when the screen is being projected
- Carrier name on lockscreen
- Display carrier name on lockscreen status bar
+ Carrier name on lock screen
+ Display carrier name on lock screen status bar
Status bar lyric
Show lyric in status bar (need app support)
Options
@@ -669,7 +669,7 @@
Glass blur
Frosted blur
- For wallpaper styles to work effectively, users must set the wallpapers for the lockscreen and homescreen at different times.\nThe same wallpaper can be used, but it should not be applied to both the lockscreen and homescreen at the same time.\nThis is optional when using the BOTH OPTION for wallpaper blur and dim styles.
+ For wallpaper styles to work effectively, users must set the wallpapers for the lock screen and home screen at different times.\nThe same wallpaper can be used, but it should not be applied to both the lock screen and home screen at the same time.\nThis is optional when using the BOTH OPTION for wallpaper blur and dim styles.
@@ -686,7 +686,7 @@
Depth wallpaper horizontal offset
Depth wallpaper vertical offset
- The depth wallpaper feature, inspired by iOS\'s Wallpaper Subject Segmentation, enables overlaying of a subject above the lockscreen clock to show a wallpaper depth effect.\n\nTo setup Depth Wallpaper Feature:\n1. Set a wallpaper with the subject or a background you want the subject to be above of.\n2. Select a subject image to track, this image will be overlaid above the lockscreen clock.\n3. Modify the offsets and opacity according to your needs.
+ The depth wallpaper feature, inspired by iOS\'s Wallpaper Subject Segmentation, enables overlaying of a subject above the lock screen clock to show a wallpaper depth effect.\n\nTo setup Depth Wallpaper Feature:\n1. Set a wallpaper with the subject or a background you want the subject to be above of.\n2. Select a subject image to track, this image will be overlaid above the lock screen clock.\n3. Modify the offsets and opacity according to your needs.
@@ -695,7 +695,7 @@
Media cover art fade level
Set media cover art fade level
-
+
Media cover art filter
None
Grayscale
@@ -743,10 +743,51 @@
QS widgets
Show widgets for quick access. \nLimits QS rows to 2 to avoid breaking AOSP QS Panel scrolling
+
+ Widgets
+ Enable lock screen widgets
+ Add widgets to lock screen
+ Device info widget
+ Show device info widget on lock screen
+ Big widgets
+ Big widget 1
+ Big widget 2
+ Mini widgets
+ Mini widget 1
+ Mini widget 2
+ Mini widget 3
+ Mini widget 4
+ Camera
+ Clock/Timer
+ Calculator
+ Gallery
+ Media Player
+ Torch
+ Play
+ Weather
+ Wifi
+ Data
+ Ringer
+ Bluetooth
+ Hotspot
+ Wallet
+
+
+ Lock screen widgets style
+ Material Rounded
+ Material Square
+ Translucent (Square)
+ Translucent (Rounded)
+ Translucent style widget transparency
+ Configure translucent style widget opacity level
+
Font Styles
Change system font style
The quick brown\nfox jumps over the\nlazy dog\n\nABCDEFGHIJKLM\nNOPQRSTUVWXYZ\nabcdefghijkl\nmnopqrstuvwxyz\n1234567890
Apply
Select font
+
+
+ Apply
diff --git a/res/xml/evolution_settings_lock_screen.xml b/res/xml/evolution_settings_lock_screen.xml
index 4b4a766..d0da27a 100644
--- a/res/xml/evolution_settings_lock_screen.xml
+++ b/res/xml/evolution_settings_lock_screen.xml
@@ -38,6 +38,18 @@
android:dependency="custom_aod_image_enabled" />
+
+
+
+
+
+
diff --git a/res/xml/evolution_settings_lock_screen_widgets.xml b/res/xml/evolution_settings_lock_screen_widgets.xml
new file mode 100644
index 0000000..8ac22fe
--- /dev/null
+++ b/res/xml/evolution_settings_lock_screen_widgets.xml
@@ -0,0 +1,106 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/org/evolution/settings/fragments/lockscreen/LockScreenWidgets.java b/src/org/evolution/settings/fragments/lockscreen/LockScreenWidgets.java
new file mode 100644
index 0000000..2bf3bfd
--- /dev/null
+++ b/src/org/evolution/settings/fragments/lockscreen/LockScreenWidgets.java
@@ -0,0 +1,243 @@
+/*
+ * Copyright (C) 2023-2024 the risingOS Android 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 org.evolution.settings.fragments.lockscreen;
+
+import android.app.Activity;
+import android.content.ContentResolver;
+import android.content.Context;
+import android.content.Intent;
+import android.graphics.Bitmap;
+import android.graphics.BitmapFactory;
+import android.net.Uri;
+import android.os.Bundle;
+import android.os.UserHandle;
+import android.provider.MediaStore;
+import android.provider.Settings;
+import android.text.TextUtils;
+import android.view.View;
+import android.widget.Button;
+import android.widget.Toast;
+
+import androidx.preference.ListPreference;
+import androidx.preference.Preference;
+import androidx.preference.PreferenceCategory;
+import androidx.preference.PreferenceScreen;
+import androidx.preference.Preference.OnPreferenceChangeListener;
+import androidx.preference.SwitchPreferenceCompat;
+
+import com.android.internal.logging.nano.MetricsProto;
+import com.android.settings.R;
+import com.android.settings.SettingsPreferenceFragment;
+import com.android.settings.search.BaseSearchIndexProvider;
+import com.android.settingslib.search.SearchIndexable;
+import com.android.settingslib.widget.LayoutPreference;
+
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.stream.Collectors;
+
+@SearchIndexable
+public class LockScreenWidgets extends SettingsPreferenceFragment implements Preference.OnPreferenceChangeListener {
+
+ public static final String TAG = "LockScreenWidgets";
+
+ private static final String MAIN_WIDGET_1_KEY = "main_custom_widgets1";
+ private static final String MAIN_WIDGET_2_KEY = "main_custom_widgets2";
+ private static final String EXTRA_WIDGET_1_KEY = "custom_widgets1";
+ private static final String EXTRA_WIDGET_2_KEY = "custom_widgets2";
+ private static final String EXTRA_WIDGET_3_KEY = "custom_widgets3";
+ private static final String EXTRA_WIDGET_4_KEY = "custom_widgets4";
+ private static final String KEY_APPLY_CHANGE_BUTTON = "apply_change_button";
+
+ private static final String LOCKSCREEN_WIDGETS_KEY = "lockscreen_widgets";
+ private static final String LOCKSCREEN_WIDGETS_EXTRAS_KEY = "lockscreen_widgets_extras";
+
+ private Preference mMainWidget1;
+ private Preference mMainWidget2;
+ private Preference mExtraWidget1;
+ private Preference mExtraWidget2;
+ private Preference mExtraWidget3;
+ private Preference mExtraWidget4;
+ private Button mApplyChange;
+
+ private SwitchPreferenceCompat mLockScreenWidgetsEnabledPref;
+ private List mWidgetPreferences;
+
+ private Map widgetKeysMap = new HashMap<>();
+ private Map initialWidgetKeysMap = new HashMap<>();
+
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+
+ addPreferencesFromResource(R.xml.evolution_settings_lock_screen_widgets);
+
+ initializePreferences();
+ setupListeners();
+
+ boolean isLsWidgetsEnabled = Settings.System.getIntForUser(
+ getActivity().getContentResolver(),
+ "lockscreen_widgets_enabled",
+ 0,
+ UserHandle.USER_CURRENT) != 0;
+
+ mLockScreenWidgetsEnabledPref.setChecked(isLsWidgetsEnabled);
+ showWidgetPreferences(isLsWidgetsEnabled);
+
+ loadInitialPreferences();
+ saveInitialPreferences();
+ mApplyChange.setEnabled(false);
+ }
+
+ private void initializePreferences() {
+ mMainWidget1 = findPreference(MAIN_WIDGET_1_KEY);
+ mMainWidget2 = findPreference(MAIN_WIDGET_2_KEY);
+ mExtraWidget1 = findPreference(EXTRA_WIDGET_1_KEY);
+ mExtraWidget2 = findPreference(EXTRA_WIDGET_2_KEY);
+ mExtraWidget3 = findPreference(EXTRA_WIDGET_3_KEY);
+ mExtraWidget4 = findPreference(EXTRA_WIDGET_4_KEY);
+
+ mWidgetPreferences = Arrays.asList(
+ mMainWidget1,
+ mMainWidget2,
+ mExtraWidget1,
+ mExtraWidget2,
+ mExtraWidget3,
+ mExtraWidget4);
+
+ mLockScreenWidgetsEnabledPref = findPreference("lockscreen_widgets_enabled");
+
+ LayoutPreference layoutPreference = findPreference(KEY_APPLY_CHANGE_BUTTON);
+ mApplyChange = layoutPreference.findViewById(R.id.apply_change);
+ }
+
+ private void setupListeners() {
+ for (Preference widgetPref : mWidgetPreferences) {
+ widgetPref.setOnPreferenceChangeListener(this);
+ widgetKeysMap.put(widgetPref, "");
+ }
+ mLockScreenWidgetsEnabledPref.setOnPreferenceChangeListener(this);
+
+ mApplyChange.setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ updateWidgetPreferences();
+ saveInitialPreferences();
+ mApplyChange.setEnabled(false);
+ }
+ });
+ }
+
+ private void showWidgetPreferences(boolean isEnabled) {
+ for (Preference widgetPref : mWidgetPreferences) {
+ widgetPref.setVisible(isEnabled);
+ }
+ }
+
+ private void loadInitialPreferences() {
+ ContentResolver resolver = getActivity().getContentResolver();
+ String mainWidgets = Settings.System.getString(resolver, LOCKSCREEN_WIDGETS_KEY);
+ setWidgetAndPreferenceValues(mainWidgets, mMainWidget1, mMainWidget2);
+ String extraWidgets = Settings.System.getString(resolver, LOCKSCREEN_WIDGETS_EXTRAS_KEY);
+ setWidgetAndPreferenceValues(extraWidgets, mExtraWidget1, mExtraWidget2, mExtraWidget3, mExtraWidget4);
+ }
+
+ private void setWidgetAndPreferenceValues(String widgets, Preference... preferences) {
+ if (widgets == null) {
+ return;
+ }
+ List widgetList = Arrays.asList(widgets.split(","));
+ for (int i = 0; i < preferences.length && i < widgetList.size(); i++) {
+ String value = widgetList.get(i).trim();
+ Preference pref = preferences[i];
+ widgetKeysMap.put(pref, value);
+ if (pref instanceof ListPreference) {
+ ((ListPreference) pref).setValue(value);
+ }
+ }
+ }
+
+ @Override
+ public boolean onPreferenceChange(Preference preference, Object newValue) {
+ if (widgetKeysMap.containsKey(preference)) {
+ widgetKeysMap.put(preference, String.valueOf(newValue));
+ mApplyChange.setEnabled(hasChanges());
+ return true;
+ } else if (preference == mLockScreenWidgetsEnabledPref) {
+ boolean isEnabled = (boolean) newValue;
+ showWidgetPreferences(isEnabled);
+ mLockScreenWidgetsEnabledPref.setChecked(isEnabled);
+ return true;
+ }
+ return false;
+ }
+
+ private void updateWidgetPreferences() {
+ List mainWidgetsList = Arrays.asList(widgetKeysMap.get(mMainWidget1), widgetKeysMap.get(mMainWidget2));
+ List extraWidgetsList = Arrays.asList(widgetKeysMap.get(mExtraWidget1), widgetKeysMap.get(mExtraWidget2), widgetKeysMap.get(mExtraWidget3), widgetKeysMap.get(mExtraWidget4));
+
+ mainWidgetsList = replaceEmptyWithNone(mainWidgetsList);
+ extraWidgetsList = replaceEmptyWithNone(extraWidgetsList);
+
+ String mainWidgets = TextUtils.join(",", mainWidgetsList);
+ String extraWidgets = TextUtils.join(",", extraWidgetsList);
+
+ ContentResolver resolver = getActivity().getContentResolver();
+ Settings.System.putString(resolver, LOCKSCREEN_WIDGETS_KEY, mainWidgets);
+ Settings.System.putString(resolver, LOCKSCREEN_WIDGETS_EXTRAS_KEY, extraWidgets);
+ }
+
+ private List replaceEmptyWithNone(List inputList) {
+ return inputList.stream()
+ .map(s -> TextUtils.isEmpty(s) ? "none" : s)
+ .collect(Collectors.toList());
+ }
+
+ private void saveInitialPreferences() {
+ initialWidgetKeysMap.clear();
+ for (Preference widgetPref : mWidgetPreferences) {
+ String value = widgetKeysMap.get(widgetPref);
+ initialWidgetKeysMap.put(widgetPref, value);
+ }
+ }
+
+ private boolean hasChanges() {
+ for (Map.Entry entry : initialWidgetKeysMap.entrySet()) {
+ Preference pref = entry.getKey();
+ String initialValue = entry.getValue();
+ String currentValue = widgetKeysMap.get(pref);
+ if (!TextUtils.equals(initialValue, currentValue)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ @Override
+ public int getMetricsCategory() {
+ return MetricsProto.MetricsEvent.VIEW_UNKNOWN;
+ }
+
+ public static final BaseSearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
+ new BaseSearchIndexProvider(R.xml.evolution_settings_lock_screen_widgets) {
+ @Override
+ public List getNonIndexableKeys(Context context) {
+ return super.getNonIndexableKeys(context);
+ }
+ };
+}