From 3a3ca7e92c7c2507093994f3fdcca4ccfc28f975 Mon Sep 17 00:00:00 2001 From: Dhina17 Date: Wed, 20 Sep 2023 13:59:53 +0530 Subject: [PATCH] Gear: Add pulse ambient edge lightning settings Strings are adapted from AICP resources_devicesettings. Change-Id: I2c25ea044bc23e3e5fdf4e41f98243d297cc3f27 --- ...ent_edge_light_color_selector_inner_bg.xml | 22 ++ ...ent_edge_light_color_selector_outer_bg.xml | 22 ++ res/drawable/ic_color_selected.xml | 27 +++ ...ambient_edge_light_color_selector_item.xml | 40 ++++ ...ambient_edge_light_color_selector_view.xml | 26 +++ res/values-night/colors.xml | 2 + res/values/arrays.xml | 15 ++ res/values/colors.xml | 40 ++-- res/values/config.xml | 3 + res/values/dimens.xml | 15 ++ res/values/integers.xml | 9 + res/values/strings.xml | 17 ++ res/xml/ambient_edge_light_settings.xml | 87 ++++++++ res/xml/bg_doze.xml | 8 + .../AmbientEdgeLightPreferenceController.java | 46 ++++ .../doze/AmbientEdgeLightSettings.java | 202 ++++++++++++++++++ .../fragments/doze/ColorSelectorAdapter.java | 105 +++++++++ 17 files changed, 668 insertions(+), 18 deletions(-) create mode 100644 res/drawable/ambient_edge_light_color_selector_inner_bg.xml create mode 100644 res/drawable/ambient_edge_light_color_selector_outer_bg.xml create mode 100644 res/drawable/ic_color_selected.xml create mode 100644 res/layout/ambient_edge_light_color_selector_item.xml create mode 100644 res/layout/ambient_edge_light_color_selector_view.xml create mode 100644 res/values/dimens.xml create mode 100644 res/values/integers.xml create mode 100644 res/xml/ambient_edge_light_settings.xml create mode 100644 src/com/banana/settings/fragments/doze/AmbientEdgeLightPreferenceController.java create mode 100644 src/com/banana/settings/fragments/doze/AmbientEdgeLightSettings.java create mode 100644 src/com/banana/settings/fragments/doze/ColorSelectorAdapter.java diff --git a/res/drawable/ambient_edge_light_color_selector_inner_bg.xml b/res/drawable/ambient_edge_light_color_selector_inner_bg.xml new file mode 100644 index 000000000..0c7461d0b --- /dev/null +++ b/res/drawable/ambient_edge_light_color_selector_inner_bg.xml @@ -0,0 +1,22 @@ + + + + + + + diff --git a/res/drawable/ambient_edge_light_color_selector_outer_bg.xml b/res/drawable/ambient_edge_light_color_selector_outer_bg.xml new file mode 100644 index 000000000..a6fb0185e --- /dev/null +++ b/res/drawable/ambient_edge_light_color_selector_outer_bg.xml @@ -0,0 +1,22 @@ + + + + + + + diff --git a/res/drawable/ic_color_selected.xml b/res/drawable/ic_color_selected.xml new file mode 100644 index 000000000..b8b2d444e --- /dev/null +++ b/res/drawable/ic_color_selected.xml @@ -0,0 +1,27 @@ + + + + + + diff --git a/res/layout/ambient_edge_light_color_selector_item.xml b/res/layout/ambient_edge_light_color_selector_item.xml new file mode 100644 index 000000000..80fbaba55 --- /dev/null +++ b/res/layout/ambient_edge_light_color_selector_item.xml @@ -0,0 +1,40 @@ + + + + + + + + + diff --git a/res/layout/ambient_edge_light_color_selector_view.xml b/res/layout/ambient_edge_light_color_selector_view.xml new file mode 100644 index 000000000..00feec700 --- /dev/null +++ b/res/layout/ambient_edge_light_color_selector_view.xml @@ -0,0 +1,26 @@ + + + + diff --git a/res/values-night/colors.xml b/res/values-night/colors.xml index b533fbee5..e5724b2b7 100644 --- a/res/values-night/colors.xml +++ b/res/values-night/colors.xml @@ -2,4 +2,6 @@ @*android:color/system_neutral1_800 + + #FF2B2930 diff --git a/res/values/arrays.xml b/res/values/arrays.xml index ec92e00ef..83d4b3b54 100644 --- a/res/values/arrays.xml +++ b/res/values/arrays.xml @@ -762,4 +762,19 @@ 4 5 + + + + + #FF6ACEFF + #FF7BFFDF + #FFB18CFF + #FFB3FF84 + #FF26BEFF + #FFCDCDCD + #FFFFDC62 + #FFFEDADA + #FFFF7676 + #FF615EFF + diff --git a/res/values/colors.xml b/res/values/colors.xml index d1f008926..d12fdc91b 100644 --- a/res/values/colors.xml +++ b/res/values/colors.xml @@ -1,18 +1,22 @@ - - - - - - @*android:color/accent_device_default - - #FFF - - @*android:color/system_neutral1_100 - - #5f6368 - - @*android:color/system_neutral1_0 - + + + + + + @*android:color/accent_device_default + + #FFF + + @*android:color/system_neutral1_100 + + #5f6368 + + @*android:color/system_neutral1_0 + + + @android:color/white + #AA000000 + diff --git a/res/values/config.xml b/res/values/config.xml index 05a0c4914..adcaf7f4f 100644 --- a/res/values/config.xml +++ b/res/values/config.xml @@ -61,4 +61,7 @@ relative to the natural orientation of the display (true for some tablets) --> 1 + + + true diff --git a/res/values/dimens.xml b/res/values/dimens.xml new file mode 100644 index 000000000..167a7fc76 --- /dev/null +++ b/res/values/dimens.xml @@ -0,0 +1,15 @@ + + + + + 40dp + 12.5dp + 48dp + 48dp + 8dp + 4dp + 24dp + diff --git a/res/values/integers.xml b/res/values/integers.xml new file mode 100644 index 000000000..512ec6169 --- /dev/null +++ b/res/values/integers.xml @@ -0,0 +1,9 @@ + + + + + 5 + diff --git a/res/values/strings.xml b/res/values/strings.xml index 7c24461ca..00fb2f78a 100644 --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -822,4 +822,21 @@ Ignore secure window flag Remove screenshot and screenrecord limits for all apps. This can be convenient in some cases but may lead to privacy leaks. + + + Ambient edge lighting + Edge lighting + Enable edge lighting + Light up the side edges of the screen on notification pulse + Color + Auto + App color + Manual + Set edge light color to the system color + Set edge light color to the app color + Pick a color manualy + Advanced + Light duration + Repeat count + Light width diff --git a/res/xml/ambient_edge_light_settings.xml b/res/xml/ambient_edge_light_settings.xml new file mode 100644 index 000000000..a1e94b811 --- /dev/null +++ b/res/xml/ambient_edge_light_settings.xml @@ -0,0 +1,87 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/res/xml/bg_doze.xml b/res/xml/bg_doze.xml index 0ca75b354..bc3e818c3 100644 --- a/res/xml/bg_doze.xml +++ b/res/xml/bg_doze.xml @@ -50,6 +50,14 @@ android:defaultValue="false" android:summary="@string/pulse_on_new_tracks_summary" /> + + diff --git a/src/com/banana/settings/fragments/doze/AmbientEdgeLightPreferenceController.java b/src/com/banana/settings/fragments/doze/AmbientEdgeLightPreferenceController.java new file mode 100644 index 000000000..6dec66a0c --- /dev/null +++ b/src/com/banana/settings/fragments/doze/AmbientEdgeLightPreferenceController.java @@ -0,0 +1,46 @@ +/* + * Copyright (C) 2023 The LibreMobileOS Foundation + * + * 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.banana.settings.fragments.doze; + +import android.content.Context; + +import com.android.settings.R; +import com.android.settings.core.BasePreferenceController; + +public class AmbientEdgeLightPreferenceController extends BasePreferenceController { + + public static final String KEY = "ambient_edge_light"; + + private Context mContext; + + public AmbientEdgeLightPreferenceController(Context context, String key) { + super(context, key); + mContext = context; + } + + public AmbientEdgeLightPreferenceController(Context context) { + this(context, KEY); + mContext = context; + } + + @Override + public int getAvailabilityStatus() { + boolean exists = mContext.getResources().getBoolean(R.bool.config_show_ambient_edge_light); + return (exists ? AVAILABLE : UNSUPPORTED_ON_DEVICE); + } + +} diff --git a/src/com/banana/settings/fragments/doze/AmbientEdgeLightSettings.java b/src/com/banana/settings/fragments/doze/AmbientEdgeLightSettings.java new file mode 100644 index 000000000..0c7422786 --- /dev/null +++ b/src/com/banana/settings/fragments/doze/AmbientEdgeLightSettings.java @@ -0,0 +1,202 @@ +/* + * Copyright (C) 2023 The LibreMobileOS Foundation + * + * 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.banana.settings.fragments.doze; + +import android.content.ContentResolver; +import android.graphics.Color; +import android.os.Bundle; +import android.os.UserHandle; +import android.provider.Settings; +import android.widget.Switch; + +import androidx.preference.Preference; +import androidx.preference.PreferenceScreen; +import androidx.recyclerview.widget.RecyclerView; + +import com.android.internal.logging.nano.MetricsProto.MetricsEvent; + +import com.android.settings.R; +import com.android.settings.SettingsPreferenceFragment; + +import com.android.settingslib.widget.LayoutPreference; +import com.android.settingslib.widget.MainSwitchPreference; +import com.android.settingslib.widget.OnMainSwitchChangeListener; +import com.android.settingslib.widget.SelectorWithWidgetPreference; + +import java.util.Arrays; +import java.util.List; + +public class AmbientEdgeLightSettings extends SettingsPreferenceFragment implements + SelectorWithWidgetPreference.OnClickListener, OnMainSwitchChangeListener, + ColorSelectorAdapter.ColorSelectListener { + + private static final String PULSE_AMBIENT_LIGHT = "pulse_ambient_light"; + private static final String PULSE_AMBIENT_LIGHT_COLOR_MODE = "pulse_ambient_light_color_mode"; + private static final String PULSE_AMBIENT_LIGHT_COLOR_AUTO = "pulse_ambient_light_color_mode_auto"; + private static final String PULSE_AMBIENT_LIGHT_COLOR_APP = "pulse_ambient_light_color_mode_app"; + private static final String PULSE_AMBIENT_LIGHT_COLOR_MANUAL = "pulse_ambient_light_color_mode_manual"; + private static final String PULSE_AMBIENT_LIGHT_COLOR_SELECTOR = "pulse_ambient_light_color_selector"; + private static final List COLOR_MODES = Arrays.asList(PULSE_AMBIENT_LIGHT_COLOR_APP, + PULSE_AMBIENT_LIGHT_COLOR_AUTO, + PULSE_AMBIENT_LIGHT_COLOR_MANUAL); + + private MainSwitchPreference mMainSwitchPref; + private SelectorWithWidgetPreference mLightColorAutoPref; + private SelectorWithWidgetPreference mLightColorAppPref; + private SelectorWithWidgetPreference mLightColorManualPref; + private LayoutPreference mColorSelectorPref; + private RecyclerView mRecyclerView; + + private int mColorMode = 0; + + @Override + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + addPreferencesFromResource(R.xml.ambient_edge_light_settings); + } + + @Override + public void onActivityCreated(final Bundle savedInstanceState) { + super.onActivityCreated(savedInstanceState); + + final PreferenceScreen prefSet = getPreferenceScreen(); + mMainSwitchPref = prefSet.findPreference(PULSE_AMBIENT_LIGHT); + mMainSwitchPref.addOnSwitchChangeListener(this); + mLightColorAutoPref = prefSet.findPreference(PULSE_AMBIENT_LIGHT_COLOR_AUTO); + mLightColorAutoPref.setOnClickListener(this); + mLightColorAppPref = prefSet.findPreference(PULSE_AMBIENT_LIGHT_COLOR_APP); + mLightColorAppPref.setOnClickListener(this); + mLightColorManualPref = prefSet.findPreference(PULSE_AMBIENT_LIGHT_COLOR_MANUAL); + mLightColorManualPref.setOnClickListener(this); + mColorSelectorPref = prefSet.findPreference(PULSE_AMBIENT_LIGHT_COLOR_SELECTOR); + + // Setup manual color selector + mRecyclerView = mColorSelectorPref.findViewById(R.id.color_selector_view); + int selectedColor = getSelectedColor(); + String selectedColorHex = getColorHex(selectedColor); + List colors = Arrays.asList(getResources() + .getStringArray(R.array.ambient_edge_light_manual_colors)); + int index = colors.indexOf(selectedColorHex); + int defaultPosition = index; + if (defaultPosition == -1) { + // Set first color as default color + int defaultColor = Color.parseColor(colors.get(0)); + setSelectedColor(defaultColor); + defaultPosition = 0; + } + mRecyclerView.setAdapter(new ColorSelectorAdapter(colors, defaultPosition, this)); + } + + @Override + public void onResume() { + super.onResume(); + updateUI(); + enableColorSelector(mMainSwitchPref.isChecked()); + } + + @Override + public int getMetricsCategory() { + return MetricsEvent.BANANADROID; + } + + @Override + public void onSwitchChanged(Switch switchView, boolean isChecked) { + enableColorSelector(isChecked); + } + + @Override + public void onRadioButtonClicked(SelectorWithWidgetPreference emiter) { + if (emiter == null) return; + String selectedKey = emiter.getKey(); + updateUI(selectedKey); + int colorMode = getColorModeByKey(selectedKey); + if (mColorMode == colorMode) return; + mColorMode = colorMode; + setColorMode(mColorMode); + } + + @Override + public void onColorSelect(int color) { + setSelectedColor(color); + } + + private void updateUI() { + mColorMode = getColorMode(); + updateUI(mColorMode); + } + + private void updateUI(int colorMode) { + String selectedKey = getKeyByColorMode(colorMode); + updateUI(selectedKey); + } + + private void updateUI(String selectedKey) { + mLightColorAutoPref.setChecked(selectedKey.equals(PULSE_AMBIENT_LIGHT_COLOR_AUTO)); + mLightColorAppPref.setChecked(selectedKey.equals(PULSE_AMBIENT_LIGHT_COLOR_APP)); + mLightColorManualPref.setChecked(selectedKey.equals(PULSE_AMBIENT_LIGHT_COLOR_MANUAL)); + mColorSelectorPref.setVisible(selectedKey.equals(PULSE_AMBIENT_LIGHT_COLOR_MANUAL)); + } + + private void enableColorSelector(boolean enabled) { + // handle enable/disable state only in manual color mode. + if (mColorMode != 2) return; + // Enable/disable the color selector. + float colorAlpha = enabled ? 1f : 0.3f; + mRecyclerView.setAlpha(colorAlpha); + mRecyclerView.suppressLayout(!enabled); + mColorSelectorPref.setSelectable(enabled); + } + + private int getColorModeByKey(String selectedKey) { + int index = COLOR_MODES.indexOf(selectedKey); + return (index == -1) ? 1 : index; + } + + private String getKeyByColorMode(int colorMode) { + if (colorMode < 0 || colorMode >= COLOR_MODES.size()) { + return COLOR_MODES.get(1); + } else { + return COLOR_MODES.get(colorMode); + } + } + + private int getColorMode() { + return Settings.Secure.getIntForUser(getActivity().getContentResolver(), + Settings.Secure.PULSE_AMBIENT_LIGHT_COLOR_MODE, 1, UserHandle.USER_CURRENT); + } + + private void setColorMode(int colorMode) { + Settings.Secure.putIntForUser(getActivity().getContentResolver(), + Settings.Secure.PULSE_AMBIENT_LIGHT_COLOR_MODE, colorMode, UserHandle.USER_CURRENT); + } + + private int getSelectedColor() { + return Settings.Secure.getIntForUser(getActivity().getContentResolver(), + Settings.Secure.PULSE_AMBIENT_LIGHT_COLOR, 1, UserHandle.USER_CURRENT); + } + + private void setSelectedColor(int color) { + Settings.Secure.putIntForUser(getActivity().getContentResolver(), + Settings.Secure.PULSE_AMBIENT_LIGHT_COLOR, color, UserHandle.USER_CURRENT); + } + + private String getColorHex(int color) { + // It will return in '#AARRGGBB' format. + return "#" + Integer.toHexString(color).toUpperCase(); + } + +} diff --git a/src/com/banana/settings/fragments/doze/ColorSelectorAdapter.java b/src/com/banana/settings/fragments/doze/ColorSelectorAdapter.java new file mode 100644 index 000000000..abb4306cb --- /dev/null +++ b/src/com/banana/settings/fragments/doze/ColorSelectorAdapter.java @@ -0,0 +1,105 @@ +/* + * Copyright (C) 2023 The LibreMobileOS Foundation + * + * 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.banana.settings.fragments.doze; + +import android.content.res.ColorStateList; +import android.graphics.Color; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; + +import androidx.annotation.NonNull; +import androidx.appcompat.widget.AppCompatImageView; +import androidx.recyclerview.widget.RecyclerView; + +import com.android.settings.R; + +import java.util.List; + +public class ColorSelectorAdapter extends + RecyclerView.Adapter { + + private final List mColors; + private int selectedPosition = 0; + private final ColorSelectListener mColorSelectListener; + + public ColorSelectorAdapter(List mColors, int defaultPosition, + ColorSelectListener listener) { + this.mColors = mColors; + this.selectedPosition = defaultPosition; + this.mColorSelectListener = listener; + } + + @NonNull + @Override + public ColorSelectorViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { + return ColorSelectorViewHolder.from(parent, this); + } + + @Override + public void onBindViewHolder(@NonNull ColorSelectorViewHolder holder, int position) { + holder.bind(); + } + + @Override + public int getItemCount() { + return mColors.size(); + } + + public static class ColorSelectorViewHolder extends RecyclerView.ViewHolder { + + private final ColorSelectorAdapter mAdapter; + + private ColorSelectorViewHolder(View view, ColorSelectorAdapter adapter) { + super(view); + this.mAdapter = adapter; + } + + public static ColorSelectorViewHolder from(ViewGroup parent, ColorSelectorAdapter adapter) { + LayoutInflater inflater = LayoutInflater.from(parent.getContext()); + View rootView = inflater + .inflate(R.layout.ambient_edge_light_color_selector_item, parent, false); + return new ColorSelectorViewHolder(rootView, adapter); + } + + public void bind() { + int position = getAdapterPosition(); + View colorView = itemView.findViewById(R.id.color_view); + AppCompatImageView selectIcon = itemView.findViewById(R.id.select_icon); + String colorHex = mAdapter.mColors.get(position); + int colorInt = Color.parseColor(colorHex); + colorView.setBackgroundTintList(ColorStateList.valueOf(colorInt)); + int selectIconVisibility = mAdapter.selectedPosition == position + ? View.VISIBLE : View.GONE; + selectIcon.setVisibility(selectIconVisibility); + colorView.setOnClickListener(view -> { + if (mAdapter.selectedPosition != position) { + int prevSelect = mAdapter.selectedPosition; + mAdapter.selectedPosition = position; + mAdapter.notifyItemChanged(prevSelect); + mAdapter.notifyItemChanged(position); + mAdapter.mColorSelectListener.onColorSelect(colorInt); + } + }); + } + } + + interface ColorSelectListener { + void onColorSelect(int color); + } + +}