first commit
diff --git a/Android.mk b/Android.mk
new file mode 100644
index 0000000..73514cb
--- /dev/null
+++ b/Android.mk
@@ -0,0 +1,28 @@
+LOCAL_PATH := $(call my-dir)
+include $(CLEAR_VARS)
+
+LOCAL_USE_AAPT2 := true
+
+LOCAL_MODULE := OmniLib
+
+LOCAL_SHARED_ANDROID_LIBRARIES := \
+ android-support-annotations \
+ android-support-v4 \
+ android-support-v7-recyclerview \
+ android-support-v7-preference \
+ android-support-v7-appcompat \
+ android-support-v14-preference
+
+LOCAL_STATIC_JAVA_LIBRARY := legacy-android-test
+
+LOCAL_RESOURCE_DIR := $(LOCAL_PATH)/res
+
+LOCAL_JAR_EXCLUDE_FILES := none
+
+LOCAL_SRC_FILES := $(call all-java-files-under, src)
+
+include $(BUILD_STATIC_JAVA_LIBRARY)
+
+# For the test package.
+include $(call all-makefiles-under, $(LOCAL_PATH))
+
diff --git a/AndroidManifest.xml b/AndroidManifest.xml
new file mode 100644
index 0000000..9249b88
--- /dev/null
+++ b/AndroidManifest.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="utf-8"?>
+
+<!-- Copyright (C) 2016 The OmniROM Project
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+ -->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="org.omnirom.omnilib">
+
+ <uses-sdk
+ android:minSdkVersion="27" />
+
+</manifest>
diff --git a/common.mk b/common.mk
new file mode 100644
index 0000000..98fcf5c
--- /dev/null
+++ b/common.mk
@@ -0,0 +1,61 @@
+#
+# Include this make file to build your application against this module.
+#
+# Make sure to include it after you've set all your desired LOCAL variables.
+# Note that you must explicitly set your LOCAL_RESOURCE_DIR before including
+# this file.
+#
+# For example:
+#
+# LOCAL_RESOURCE_DIR := \
+# $(LOCAL_PATH)/res
+#
+# include packages/apps/OmniLib/common.mk
+#
+
+ifeq ($(LOCAL_USE_AAPT2),true)
+LOCAL_STATIC_ANDROID_LIBRARIES += \
+ android-support-annotations \
+ android-support-v4 \
+ OmniLib
+else
+LOCAL_RESOURCE_DIR += $(call my-dir)/res
+
+
+## Include transitive dependencies below
+
+# Include support-v7-appcompat, if not already included
+ifeq (,$(findstring android-support-v7-appcompat,$(LOCAL_STATIC_JAVA_LIBRARIES)))
+LOCAL_RESOURCE_DIR += frameworks/support/v7/appcompat/res
+LOCAL_AAPT_FLAGS += --extra-packages android.support.v7.appcompat
+LOCAL_STATIC_JAVA_LIBRARIES += android-support-v7-appcompat
+endif
+
+# Include support-v7-recyclerview, if not already included
+ifeq (,$(findstring android-support-v7-recyclerview,$(LOCAL_STATIC_JAVA_LIBRARIES)))
+LOCAL_RESOURCE_DIR += frameworks/support/v7/recyclerview/res
+LOCAL_AAPT_FLAGS += --extra-packages android.support.v7.recyclerview
+LOCAL_STATIC_JAVA_LIBRARIES += android-support-v7-recyclerview
+endif
+
+# Include android-support-v7-preference, if not already included
+ifeq (,$(findstring android-support-v7-preference,$(LOCAL_STATIC_JAVA_LIBRARIES)))
+LOCAL_RESOURCE_DIR += frameworks/support/v7/preference/res
+LOCAL_AAPT_FLAGS += --extra-packages android.support.v7.preference
+LOCAL_STATIC_JAVA_LIBRARIES += android-support-v7-preference
+endif
+
+# Include android-support-v14-preference, if not already included
+ifeq (,$(findstring android-support-v14-preference,$(LOCAL_STATIC_JAVA_LIBRARIES)))
+LOCAL_RESOURCE_DIR += frameworks/support/v14/preference/res
+LOCAL_AAPT_FLAGS += --extra-packages android.support.v14.preference
+LOCAL_STATIC_JAVA_LIBRARIES += android-support-v14-preference
+endif
+
+LOCAL_AAPT_FLAGS += --auto-add-overlay --extra-packages com.android.settingslib
+
+LOCAL_STATIC_JAVA_LIBRARIES += \
+ android-support-annotations \
+ android-support-v4 \
+ OmniLib
+endif
diff --git a/res/layout/app_grid_item.xml b/res/layout/app_grid_item.xml
new file mode 100644
index 0000000..0b1644c
--- /dev/null
+++ b/res/layout/app_grid_item.xml
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2016 The OmniROM Project
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+ -->
+<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent">
+
+ <ImageView
+ android:id="@+id/appIcon"
+ android:layout_width="@android:dimen/app_icon_size"
+ android:layout_height="@android:dimen/app_icon_size"
+ android:layout_alignParentLeft="true"
+ android:layout_alignParentStart="true"
+ android:layout_alignParentTop="true"
+ android:background="?android:attr/selectableItemBackground"
+ android:scaleType="centerInside" />
+</RelativeLayout>
diff --git a/res/layout/app_select_item.xml b/res/layout/app_select_item.xml
new file mode 100644
index 0000000..92a9b9a
--- /dev/null
+++ b/res/layout/app_select_item.xml
@@ -0,0 +1,57 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2016 The OmniROM Project
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+ -->
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:minHeight="64dp"
+ android:paddingStart="6dp"
+ android:gravity="center_vertical"
+ android:paddingEnd="?android:attr/listPreferredItemPaddingEnd"
+ android:orientation="horizontal" >
+
+ <ImageView
+ android:id="@+id/app_icon"
+ android:layout_width="@android:dimen/app_icon_size"
+ android:layout_height="@android:dimen/app_icon_size"
+ android:layout_marginEnd="8dip"
+ android:layout_gravity="center_vertical"
+ android:scaleType="centerInside"
+ android:contentDescription="@null" />
+
+ <TextView
+ android:id="@+id/app_name"
+ android:layout_width="0dip"
+ android:layout_height="wrap_content"
+ android:layout_weight="1"
+ android:layout_gravity="center_vertical"
+ android:singleLine="true"
+ android:ellipsize="end"
+ android:focusable="false"
+ android:textAppearance="?android:attr/textAppearanceListItem"
+ android:textAlignment="viewStart" />
+
+ <CheckBox android:id="@android:id/checkbox"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_marginStart="8dip"
+ android:layout_gravity="center_vertical"
+ android:clickable="false"
+ android:focusable="false" />
+
+</LinearLayout>
+
diff --git a/res/layout/applist_preference_icon.xml b/res/layout/applist_preference_icon.xml
new file mode 100644
index 0000000..12644d0
--- /dev/null
+++ b/res/layout/applist_preference_icon.xml
@@ -0,0 +1,49 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2006 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.
+-->
+
+<!-- Layout for a Preference in a PreferenceActivity. The
+ Preference is able to place a specific widget for its particular
+ type in the "widget_frame" layout. -->
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:id="@android:id/widget_frame"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:minHeight="64dp"
+ android:gravity="center_vertical"
+ android:paddingStart="6dp"
+ android:paddingEnd="?android:attr/listPreferredItemPaddingEnd"
+ android:background="?android:attr/selectableItemBackground">
+
+ <ImageView
+ android:id="@+id/icon"
+ android:layout_width="@android:dimen/app_icon_size"
+ android:layout_height="@android:dimen/app_icon_size"
+ android:layout_gravity="center_vertical"
+ android:layout_marginEnd="8dip"
+ android:scaleType="centerInside" />
+
+ <TextView
+ android:id="@+id/title"
+ android:layout_width="0dip"
+ android:layout_height="wrap_content"
+ android:layout_weight="1"
+ android:layout_gravity="center_vertical"
+ android:ellipsize="end"
+ android:focusable="false"
+ android:singleLine="true"
+ android:textAlignment="viewStart"
+ android:textAppearance="?android:attr/textAppearanceListItem" />
+
+</LinearLayout>
diff --git a/res/layout/preference_app_list.xml b/res/layout/preference_app_list.xml
new file mode 100644
index 0000000..97177b9
--- /dev/null
+++ b/res/layout/preference_app_list.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2016 The OmniROM Project
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+ -->
+
+<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:orientation="vertical"
+ android:paddingStart="@dimen/alert_dialog_padding_material"
+ android:paddingEnd="@dimen/alert_dialog_padding_material">
+
+ <ListView
+ android:id="@+id/app_list"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:divider="@null" />
+</LinearLayout>
+
diff --git a/res/layout/preference_app_select.xml b/res/layout/preference_app_select.xml
new file mode 100644
index 0000000..39ebee3
--- /dev/null
+++ b/res/layout/preference_app_select.xml
@@ -0,0 +1,80 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2016 The OmniROM Project
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+-->
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:minHeight="?android:attr/listPreferredItemHeight"
+ android:gravity="center_vertical"
+ android:paddingStart="?android:attr/listPreferredItemPaddingStart"
+ android:paddingEnd="?android:attr/listPreferredItemPaddingEnd"
+ android:background="?android:attr/selectableItemBackground"
+ android:clipToPadding="false"
+ android:orientation="horizontal" >
+
+ <LinearLayout
+ android:id="@+id/icon_frame"
+ style="@style/preference_icon_frame"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:gravity="start|center_vertical"
+ android:orientation="horizontal"
+ android:clipToPadding="false"
+ android:paddingEnd="12dp"
+ android:paddingTop="4dp"
+ android:paddingBottom="4dp">
+ <com.android.internal.widget.PreferenceImageView
+ android:id="@android:id/icon"
+ android:layout_width="48dp"
+ android:layout_height="48dp"
+ android:gravity="center"
+ android:scaleType="centerInside" />
+ </LinearLayout>
+
+ <LinearLayout
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:orientation="vertical"
+ android:gravity="center_vertical"
+ android:layout_weight="1" >
+
+ <RelativeLayout
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_marginEnd="6dip"
+ android:layout_marginTop="10dip"
+ android:layout_marginBottom="6dip" >
+
+ <TextView android:id="@android:id/title"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:singleLine="true"
+ android:textAppearance="?android:attr/textAppearanceListItem"
+ android:ellipsize="marquee" />
+
+ <TextView android:id="@android:id/summary"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_below="@android:id/title"
+ android:layout_alignStart="@android:id/title"
+ android:textAppearance="?android:attr/textAppearanceListItemSecondary"
+ android:textColor="?android:attr/textColorSecondary"
+ android:maxLines="10"
+ android:ellipsize="end" />
+
+ </RelativeLayout>
+ </LinearLayout>
+</LinearLayout>
diff --git a/res/layout/preference_color_select.xml b/res/layout/preference_color_select.xml
new file mode 100644
index 0000000..dc53867
--- /dev/null
+++ b/res/layout/preference_color_select.xml
@@ -0,0 +1,82 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2014 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:minHeight="?android:attr/listPreferredItemHeight"
+ android:gravity="center_vertical"
+ android:paddingStart="?android:attr/listPreferredItemPaddingStart"
+ android:paddingEnd="?android:attr/listPreferredItemPaddingEnd"
+ android:background="?android:attr/selectableItemBackground"
+ android:clipToPadding="false" >
+
+ <LinearLayout
+ android:id="@+id/icon_frame"
+ style="@style/preference_icon_frame"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:gravity="start|center_vertical"
+ android:orientation="horizontal"
+ android:clipToPadding="false"
+ android:paddingEnd="12dp"
+ android:paddingTop="4dp"
+ android:paddingBottom="4dp">
+ <com.android.internal.widget.PreferenceImageView
+ android:id="@android:id/icon"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:maxWidth="48dp"
+ android:maxHeight="48dp" />
+ </LinearLayout>
+
+ <RelativeLayout
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_weight="1"
+ android:paddingTop="12dp"
+ android:paddingBottom="12dp">
+
+ <TextView android:id="@android:id/title"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:singleLine="true"
+ android:textAppearance="?android:attr/textAppearanceListItem"
+ android:ellipsize="marquee"
+ android:fadingEdge="horizontal" />
+
+ <TextView android:id="@android:id/summary"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_below="@android:id/title"
+ android:layout_alignStart="@android:id/title"
+ android:textAppearance="?android:attr/textAppearanceListItemSecondary"
+ android:textColor="?android:attr/textColorSecondary"
+ android:maxLines="1" />
+ </RelativeLayout>
+
+ <LinearLayout
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_marginEnd="8dp">
+
+ <ImageView
+ android:id="@+id/light_color"
+ android:layout_width="@dimen/color_preference_width"
+ android:layout_height="@dimen/color_preference_height"
+ android:layout_gravity="center" />
+ </LinearLayout>
+</LinearLayout>
diff --git a/res/layout/preference_font_picker.xml b/res/layout/preference_font_picker.xml
new file mode 100644
index 0000000..fd34b75
--- /dev/null
+++ b/res/layout/preference_font_picker.xml
@@ -0,0 +1,85 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2016 The OmniROM Project
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+ -->
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:minHeight="?android:attr/listPreferredItemHeight"
+ android:gravity="center_vertical"
+ android:paddingStart="?android:attr/listPreferredItemPaddingStart"
+ android:paddingEnd="?android:attr/listPreferredItemPaddingEnd"
+ android:background="?android:attr/selectableItemBackground"
+ android:clipToPadding="false" >
+
+ <LinearLayout
+ android:id="@+id/icon_frame"
+ style="@style/preference_icon_frame"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:gravity="start|center_vertical"
+ android:orientation="horizontal"
+ android:clipToPadding="false"
+ android:paddingEnd="12dp"
+ android:paddingTop="4dp"
+ android:paddingBottom="4dp">
+ <com.android.internal.widget.PreferenceImageView
+ android:id="@android:id/icon"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:maxWidth="48dp"
+ android:maxHeight="48dp" />
+ </LinearLayout>
+
+ <RelativeLayout
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_weight="1"
+ android:paddingTop="16dp"
+ android:paddingBottom="16dp">
+
+ <TextView android:id="@android:id/title"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:singleLine="true"
+ android:textAppearance="?android:attr/textAppearanceListItem"
+ android:ellipsize="marquee"
+ android:fadingEdge="horizontal" />
+
+ <TextView android:id="@android:id/summary"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_below="@android:id/title"
+ android:layout_alignStart="@android:id/title"
+ android:textAppearance="?android:attr/textAppearanceListItemSecondary"
+ android:textColor="?android:attr/textColorSecondary"
+ android:maxLines="1" />
+ </RelativeLayout>
+
+ <LinearLayout
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_marginEnd="8dp">
+
+ <TextView android:id="@+id/font_sample"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:singleLine="true"
+ android:textAppearance="?android:attr/textAppearanceMedium"
+ android:layout_gravity="center"
+ android:text="@string/font_sample_text" />
+ </LinearLayout>
+</LinearLayout>
diff --git a/res/layout/preference_seek_bar.xml b/res/layout/preference_seek_bar.xml
new file mode 100644
index 0000000..d988419
--- /dev/null
+++ b/res/layout/preference_seek_bar.xml
@@ -0,0 +1,115 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2016 The OmniROM Project
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+-->
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:minHeight="?android:attr/listPreferredItemHeight"
+ android:gravity="center_vertical"
+ android:paddingStart="?android:attr/listPreferredItemPaddingStart"
+ android:paddingEnd="?android:attr/listPreferredItemPaddingEnd"
+ android:background="?android:attr/selectableItemBackground"
+ android:clipToPadding="false"
+ android:orientation="horizontal" >
+
+ <LinearLayout
+ android:id="@+id/icon_frame"
+ style="@style/preference_icon_frame"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:gravity="start|center_vertical"
+ android:orientation="horizontal"
+ android:clipToPadding="false"
+ android:paddingEnd="12dp"
+ android:paddingTop="4dp"
+ android:paddingBottom="4dp">
+ <com.android.internal.widget.PreferenceImageView
+ android:id="@android:id/icon"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:maxWidth="48dp"
+ android:maxHeight="48dp" />
+ </LinearLayout>
+
+ <LinearLayout
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:orientation="vertical"
+ android:gravity="center_vertical"
+ android:layout_weight="1" >
+
+ <RelativeLayout
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_marginEnd="6dip"
+ android:layout_marginTop="10dip"
+ android:layout_marginBottom="6dip" >
+
+ <TextView android:id="@android:id/title"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:singleLine="true"
+ android:textAppearance="?android:attr/textAppearanceListItem"
+ android:ellipsize="marquee" />
+
+ <TextView android:id="@android:id/summary"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_below="@android:id/title"
+ android:layout_alignStart="@android:id/title"
+ android:textAppearance="?android:attr/textAppearanceListItemSecondary"
+ android:textColor="?android:attr/textColorSecondary"
+ android:maxLines="10"
+ android:ellipsize="end" />
+
+ </RelativeLayout>
+
+ <LinearLayout
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:gravity="center_vertical"
+ android:orientation="horizontal"
+ android:layout_marginStart="10dip"
+ android:layout_marginEnd="6dip"
+ android:layout_marginTop="5dip"
+ android:layout_marginBottom="10dip">
+
+ <TextView android:id="@+id/seekBarPrefUnitsLeft"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:textAppearance="?android:attr/textAppearanceSmall" />
+
+ <SeekBar android:id="@+id/seekbar"
+ android:layout_width="0dp"
+ android:layout_height="wrap_content"
+ android:layout_weight="1"
+ android:paddingLeft="5dp"
+ android:paddingRight="5dp" />
+
+ <TextView android:id="@+id/seekBarPrefValue"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:paddingRight="5dp"
+ android:textAppearance="?android:attr/textAppearanceSmall" />
+
+ <TextView android:id="@+id/seekBarPrefUnitsRight"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:textAppearance="?android:attr/textAppearanceSmall" />
+
+ </LinearLayout>
+ </LinearLayout>
+</LinearLayout>
diff --git a/res/layout/preference_selected_apps_view.xml b/res/layout/preference_selected_apps_view.xml
new file mode 100644
index 0000000..05480dd
--- /dev/null
+++ b/res/layout/preference_selected_apps_view.xml
@@ -0,0 +1,60 @@
+<?xml version="1.0" encoding="utf-8"?><!-- Copyright (C) 2016 The OmniROM Project
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+ -->
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:background="@android:drawable/list_selector_background"
+ android:gravity="center_vertical"
+ android:minHeight="?android:attr/listPreferredItemHeight"
+ android:paddingEnd="?android:attr/scrollbarSize">
+
+ <RelativeLayout
+ android:layout_width="0dp"
+ android:layout_height="wrap_content"
+ android:layout_marginBottom="6dip"
+ android:layout_marginEnd="6dip"
+ android:layout_marginStart="8dip"
+ android:layout_marginTop="6dip"
+ android:layout_weight="1">
+
+ <HorizontalScrollView
+ android:id="@+id/appsScrollView"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_gravity="center"
+ android:layout_marginBottom="8dip"
+ android:layout_marginTop="8dip"
+ android:scrollbars="none" >
+
+ <LinearLayout
+ android:id="@+id/selected_apps"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:orientation="horizontal" />
+ </HorizontalScrollView>
+
+ </RelativeLayout>
+
+ <!-- Preference should place its actual preference widget here. -->
+ <LinearLayout
+ android:id="@android:id/widget_frame"
+ android:layout_width="wrap_content"
+ android:layout_height="match_parent"
+ android:gravity="center_vertical"
+ android:orientation="vertical" />
+
+</LinearLayout>
diff --git a/res/values/custom_attrs.xml b/res/values/custom_attrs.xml
new file mode 100644
index 0000000..ce2d08f
--- /dev/null
+++ b/res/values/custom_attrs.xml
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+** Copyright 2013, The ChameleonOS 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.
+*/
+-->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+
+ <declare-styleable name="SeekBarPreference">
+ <attr name="min" format="integer" />
+ <attr name="interval" format="integer" />
+ <attr name="unitsLeft" format="string|reference" />
+ <attr name="unitsRight" format="string|reference" />
+ </declare-styleable>
+
+ <declare-styleable name="ColorSelectPreference">
+ <attr name="ledPreview" format="boolean" />
+ </declare-styleable>
+</resources>
diff --git a/res/values/dimensions.xml b/res/values/dimensions.xml
new file mode 100644
index 0000000..b329078
--- /dev/null
+++ b/res/values/dimensions.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2016 The OmniROM Project
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+ -->
+
+<resources>
+ <dimen name="alert_dialog_padding_material">20dp</dimen>
+ <dimen name="color_preference_width">18dip</dimen>
+ <dimen name="color_preference_height">18dip</dimen>
+</resources>
\ No newline at end of file
diff --git a/src/org/omnirom/omnilib/preference/AppMultiSelectListPreference.java b/src/org/omnirom/omnilib/preference/AppMultiSelectListPreference.java
new file mode 100644
index 0000000..be6caa4
--- /dev/null
+++ b/src/org/omnirom/omnilib/preference/AppMultiSelectListPreference.java
@@ -0,0 +1,245 @@
+/*
+ * Copyright (C) 2016 The OmniROM Project
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+package org.omnirom.omnilib.preference;
+
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.content.pm.PackageManager;
+import android.content.pm.ResolveInfo;
+import android.graphics.drawable.Drawable;
+import android.util.AttributeSet;
+import android.util.Log;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.AdapterView;
+import android.widget.ArrayAdapter;
+import android.widget.CheckBox;
+import android.widget.ImageView;
+import android.widget.ListView;
+import android.widget.TextView;
+
+import org.omnirom.omnilib.R;
+import com.android.settingslib.CustomDialogPreference;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
+
+public class AppMultiSelectListPreference extends CustomDialogPreference {
+ private static final String TAG = "AppMultiSelectList";
+ private static final boolean DEBUG = false;
+
+ private final List<PackageItem> mPackageInfoList = new ArrayList<PackageItem>();
+ private AppListAdapter mAdapter;
+ private List<String> mValues = new ArrayList<String>();
+ private PackageManager mPm;
+
+ public AppMultiSelectListPreference(Context context) {
+ this(context, null);
+ }
+
+ public AppMultiSelectListPreference(Context context, AttributeSet attrs) {
+ super(context, attrs);
+ setDialogLayoutResource(R.layout.preference_app_list);
+
+ mPm = context.getPackageManager();
+
+ final Intent mainIntent = new Intent(Intent.ACTION_MAIN, null);
+ mainIntent.addCategory(Intent.CATEGORY_LAUNCHER);
+ List<ResolveInfo> installedAppsInfo = getContext().getPackageManager().queryIntentActivities(
+ mainIntent, 0);
+
+ for (ResolveInfo info : installedAppsInfo) {
+ ComponentName componentName = new ComponentName(
+ info.activityInfo.applicationInfo.packageName,
+ info.activityInfo.name);
+
+ try {
+ final PackageItem item = new PackageItem(
+ info.activityInfo.loadLabel(mPm), 0, componentName);
+ mPackageInfoList.add(item);
+ } catch (Exception e) {
+ if (DEBUG) Log.e(TAG, "Load installed apps", e);
+ }
+ }
+ Collections.sort(mPackageInfoList);
+
+ setPositiveButtonText(R.string.action_save);
+ setNegativeButtonText(android.R.string.cancel);
+ }
+
+ public void setValues(Collection<String> values) {
+ mValues.clear();
+ mValues.addAll(values);
+ }
+
+ public Collection<String> getValues() {
+ return mValues;
+ }
+
+ @Override
+ protected void onBindDialogView(View view) {
+ super.onBindDialogView(view);
+
+ mAdapter = new AppListAdapter(getContext());
+ final ListView listView = (ListView) view.findViewById(R.id.app_list);
+ listView.setAdapter(mAdapter);
+ listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
+ @Override
+ public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
+ final AppViewHolder holder = (AppViewHolder) view.getTag();
+ final boolean isChecked = !holder.checkBox.isChecked();
+
+ holder.checkBox.setChecked(isChecked);
+ PackageItem info = mAdapter.getItem(position);
+
+ if (isChecked) {
+ mValues.add(info.mValue);
+ } else {
+ mValues.remove(info.mValue);
+ }
+ }
+ });
+ }
+
+ @Override
+ protected void onDialogClosed(boolean positiveResult) {
+ super.onDialogClosed(positiveResult);
+ if (positiveResult) {
+ callChangeListener(mValues.size() > 0 ? mValues : null);
+ }
+ }
+
+ public class PackageItem implements Comparable<PackageItem> {
+ public final CharSequence mTitle;
+ public final int mAppIconResourceId;
+ public final ComponentName mComponentName;
+ public final String mValue;
+
+ PackageItem(CharSequence title, int iconResourceId, ComponentName componentName) {
+ mTitle = title;
+ mAppIconResourceId = iconResourceId;
+ mComponentName = componentName;
+ mValue = componentName.flattenToString();
+ }
+
+ PackageItem(CharSequence title, int iconResourceId, String value) {
+ mTitle = title;
+ mAppIconResourceId = iconResourceId;
+ mComponentName = null;
+ mValue = value;
+ }
+
+ @Override
+ public int compareTo(PackageItem another) {
+ return mTitle.toString().toUpperCase().compareTo(another.mTitle.toString().toUpperCase());
+ }
+
+ @Override
+ public int hashCode() {
+ return mValue.hashCode();
+ }
+
+ @Override
+ public boolean equals(Object another) {
+ if (another == null || !(another instanceof PackageItem)) {
+ return false;
+ }
+ return mValue.equals(((PackageItem) another).mValue);
+ }
+ }
+
+ public class AppListAdapter extends ArrayAdapter<PackageItem> {
+ private final LayoutInflater mInflater;
+
+ public AppListAdapter(Context context) {
+ super(context, 0);
+ mInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
+ addAll(mPackageInfoList);
+ }
+
+ @Override
+ public View getView(int position, View convertView, ViewGroup parent) {
+ AppViewHolder holder = AppViewHolder.createOrRecycle(mInflater, convertView);
+ convertView = holder.rootView;
+ PackageItem info = getItem(position);
+ holder.appName.setText(info.mTitle);
+ if (info.mAppIconResourceId != 0) {
+ holder.appIcon.setImageResource(info.mAppIconResourceId);
+ } else {
+ Drawable d = resolveAppIcon(info);
+ holder.appIcon.setImageDrawable(d);
+ }
+ holder.checkBox.setChecked(mValues.contains(info.mValue));
+ return convertView;
+ }
+
+ @Override
+ public PackageItem getItem(int position) {
+ return mPackageInfoList.get(position);
+ }
+ }
+
+ public static class AppViewHolder {
+ public View rootView;
+ public TextView appName;
+ public ImageView appIcon;
+ public CheckBox checkBox;
+
+ public static AppViewHolder createOrRecycle(LayoutInflater inflater, View convertView) {
+ if (convertView == null) {
+ convertView = inflater.inflate(R.layout.app_select_item, null);
+
+ // Creates a ViewHolder and store references to the two children views
+ // we want to bind data to.
+ AppViewHolder holder = new AppViewHolder();
+ holder.rootView = convertView;
+ holder.appName = (TextView) convertView.findViewById(R.id.app_name);
+ holder.appIcon = (ImageView) convertView.findViewById(R.id.app_icon);
+ holder.checkBox = (CheckBox) convertView.findViewById(android.R.id.checkbox);
+ convertView.setTag(holder);
+ return holder;
+ } else {
+ // Get the ViewHolder back to get fast access to the TextView
+ // and the ImageView.
+ return (AppViewHolder) convertView.getTag();
+ }
+ }
+ }
+
+ private Drawable getDefaultActivityIcon() {
+ return getContext().getResources().getDrawable(android.R.drawable.sym_def_app_icon);
+ }
+
+ private Drawable resolveAppIcon(PackageItem item) {
+ Drawable appIcon = null;
+ try {
+ appIcon = mPm.getActivityIcon(item.mComponentName);
+ } catch (PackageManager.NameNotFoundException e) {
+ if (DEBUG) Log.e(TAG, "resolveAppIcon", e);
+ }
+ if (appIcon == null) {
+ appIcon = getDefaultActivityIcon();
+ }
+ return appIcon;
+ }
+}
+
diff --git a/src/org/omnirom/omnilib/preference/AppSelectListPreference.java b/src/org/omnirom/omnilib/preference/AppSelectListPreference.java
new file mode 100644
index 0000000..9b3d009
--- /dev/null
+++ b/src/org/omnirom/omnilib/preference/AppSelectListPreference.java
@@ -0,0 +1,339 @@
+/*
+* Copyright (C) 2017 The OmniROM Project
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 2 of the License, or
+* (at your option) any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program. If not, see <http://www.gnu.org/licenses/>.
+*
+*/
+package org.omnirom.omnilib.preference;
+
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.DialogInterface;
+import android.content.Intent;
+import android.content.pm.ActivityInfo;
+import android.content.pm.ApplicationInfo;
+import android.content.pm.PackageManager;
+import android.content.pm.ResolveInfo;
+import android.graphics.drawable.Drawable;
+import android.os.Handler;
+import android.os.Message;
+import android.support.v7.preference.PreferenceViewHolder;
+import android.support.v14.preference.PreferenceDialogFragment;
+import android.util.AttributeSet;
+import android.util.Log;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.AdapterView;
+import android.widget.AdapterView.OnItemClickListener;
+import android.widget.BaseAdapter;
+import android.widget.ImageView;
+import android.widget.ListView;
+import android.widget.TextView;
+
+import java.util.Collections;
+import java.util.LinkedList;
+import java.util.List;
+
+import com.android.settingslib.CustomDialogPreference;
+import org.omnirom.omnilib.R;
+
+public class AppSelectListPreference extends CustomDialogPreference {
+
+ private static String TAG = "AppSelectListPreference";
+ public static final String DISABLED_ENTRY = "disabled";
+
+ private AppSelectListAdapter mAdapter;
+ private Drawable mAppIconDrawable;
+ private int mAppIconResourceId;
+ private CharSequence mTitle;
+ private String mValue;
+ private PackageManager mPm;
+
+ public class PackageItem implements Comparable<PackageItem> {
+ public final CharSequence mTitle;
+ public final int mAppIconResourceId;
+ public final ComponentName mComponentName;
+ public final String mValue;
+
+ PackageItem(CharSequence title, int iconResourceId, ComponentName componentName) {
+ mTitle = title;
+ mAppIconResourceId = iconResourceId;
+ mComponentName = componentName;
+ mValue = componentName.flattenToString();
+ }
+
+ PackageItem(CharSequence title, int iconResourceId, String value) {
+ mTitle = title;
+ mAppIconResourceId = iconResourceId;
+ mComponentName = null;
+ mValue = value;
+ }
+
+ @Override
+ public int compareTo(PackageItem another) {
+ return mTitle.toString().toUpperCase().compareTo(another.mTitle.toString().toUpperCase());
+ }
+
+ @Override
+ public int hashCode() {
+ return mValue.hashCode();
+ }
+
+ @Override
+ public boolean equals(Object another) {
+ if (another == null || !(another instanceof PackageItem)) {
+ return false;
+ }
+ return mValue.equals(((PackageItem) another).mValue);
+ }
+ }
+
+ public class AppSelectListAdapter extends BaseAdapter implements Runnable {
+ private LayoutInflater mInflater;
+ private List<PackageItem> mInstalledPackages = new LinkedList<PackageItem>();
+
+ private final Handler mHandler = new Handler() {
+ @Override
+ public void handleMessage(Message msg) {
+ PackageItem disabledItem = new PackageItem(getContext().getResources().getString(R.string.disabled_entry),
+ R.drawable.ic_disabled, DISABLED_ENTRY);
+ mInstalledPackages.add(0, disabledItem);
+
+ notifyDataSetChanged();
+ updatePreferenceViews();
+ }
+ };
+
+ public AppSelectListAdapter(Context context) {
+ mInflater = LayoutInflater.from(context);
+ reloadList();
+ }
+
+ @Override
+ public int getCount() {
+ return mInstalledPackages.size();
+ }
+
+ @Override
+ public PackageItem getItem(int position) {
+ return mInstalledPackages.get(position);
+ }
+
+ @Override
+ public long getItemId(int position) {
+ return mInstalledPackages.get(position).hashCode();
+ }
+
+ @Override
+ public View getView(int position, View convertView, ViewGroup parent) {
+ ViewHolder holder;
+ if (convertView != null) {
+ holder = (ViewHolder) convertView.getTag();
+ } else {
+ convertView = mInflater.inflate(R.layout.applist_preference_icon, null, false);
+ holder = new ViewHolder();
+ convertView.setTag(holder);
+ holder.title = (TextView) convertView.findViewById(R.id.title);
+ holder.icon = (ImageView) convertView.findViewById(R.id.icon);
+ }
+
+ PackageItem applicationInfo = getItem(position);
+ holder.title.setText(applicationInfo.mTitle);
+ if (applicationInfo.mAppIconResourceId != 0) {
+ holder.icon.setImageResource(applicationInfo.mAppIconResourceId);
+ } else {
+ Drawable d = resolveAppIcon(applicationInfo);
+ holder.icon.setImageDrawable(d);
+ }
+ return convertView;
+ }
+
+ private void reloadList() {
+ mInstalledPackages.clear();
+ new Thread(this).start();
+ }
+
+ @Override
+ public void run() {
+ final Intent mainIntent = new Intent(Intent.ACTION_MAIN, null);
+ mainIntent.addCategory(Intent.CATEGORY_LAUNCHER);
+ List<ResolveInfo> installedAppsInfo = mPm.queryIntentActivities(mainIntent, 0);
+
+ for (ResolveInfo info : installedAppsInfo) {
+ ActivityInfo activity = info.activityInfo;
+ ApplicationInfo appInfo = activity.applicationInfo;
+ ComponentName componentName = new ComponentName(appInfo.packageName, activity.name);
+ CharSequence label = null;
+ try {
+ label = activity.loadLabel(mPm);
+ } catch (Exception e) {
+ }
+ if (label != null) {
+ final PackageItem item = new PackageItem(activity.loadLabel(mPm), 0, componentName);
+ mInstalledPackages.add(item);
+ }
+ }
+ Collections.sort(mInstalledPackages);
+ mHandler.obtainMessage(0).sendToTarget();
+ }
+
+ private PackageItem resolveApplication(ComponentName componentName) {
+ for (PackageItem item : mInstalledPackages) {
+ if (item.mComponentName != null && item.mComponentName.equals(componentName)) {
+ return item;
+ }
+ }
+ return null;
+ }
+
+ private class ViewHolder {
+ TextView title;
+ TextView summary;
+ ImageView icon;
+ }
+ }
+
+ public AppSelectListPreference(Context context, AttributeSet attrs) {
+ super(context, attrs);
+ init();
+ }
+
+ public AppSelectListPreference(Context context, int color) {
+ super(context, null);
+ init();
+ }
+
+ private void init() {
+ mPm = getContext().getPackageManager();
+ setDialogLayoutResource(R.layout.preference_app_list);
+ setLayoutResource(R.layout.preference_app_select);
+ setNegativeButtonText(android.R.string.cancel);
+ setPositiveButtonText(null);
+ setDialogTitle(R.string.choose_app);
+ setDialogIcon(null);
+ mAdapter = new AppSelectListAdapter(getContext());
+ }
+
+ @Override
+ protected void onSetInitialValue(boolean restorePersistedValue, Object defaultValue) {
+ super.onSetInitialValue(restorePersistedValue, defaultValue);
+ if (mTitle != null) {
+ setSummary(mTitle);
+ } else {
+ setSummary(getContext().getResources().getString(R.string.not_ready_summary));
+ }
+ mAppIconResourceId = R.drawable.ic_disabled;
+ setIcon(mAppIconResourceId);
+ }
+
+ @Override
+ protected void onBindDialogView(View view) {
+ super.onBindDialogView(view);
+
+ final ListView list = (ListView) view.findViewById(R.id.app_list);
+ list.setAdapter(mAdapter);
+ list.setOnItemClickListener(new OnItemClickListener() {
+ @Override
+ public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
+ PackageItem info = (PackageItem) parent.getItemAtPosition(position);
+ mValue = info.mValue;
+ if (shouldPersist()) {
+ persistString(mValue);
+ }
+ mTitle = info.mTitle;
+ mAppIconDrawable = null;
+ mAppIconResourceId = 0;
+ if (info.mComponentName != null) {
+ mAppIconDrawable = resolveAppIcon(info);
+ } else {
+ mAppIconResourceId = info.mAppIconResourceId;
+ }
+
+ updatePreferenceViews();
+ callChangeListener(mValue);
+ getDialog().dismiss();
+ }
+ });
+ }
+
+ private void updatePreferenceViews() {
+ String name = null;
+ if (shouldPersist()) {
+ name = getPersistedString(null);
+ } else {
+ name = mValue;
+ }
+ mAppIconResourceId = R.drawable.ic_disabled;
+
+ if (name != null) {
+ if (name.equals(DISABLED_ENTRY)) {
+ mTitle = getContext().getResources().getString(R.string.disabled_entry);
+ mAppIconResourceId = R.drawable.ic_disabled;
+ } else {
+ mAppIconDrawable = null;
+ ComponentName componentName = ComponentName.unflattenFromString(name);
+ PackageItem item = mAdapter.resolveApplication(componentName);
+ if (item != null) {
+ mTitle = item.mTitle;
+ mAppIconDrawable = resolveAppIcon(item);
+ } else {
+ mTitle = getContext().getResources().getString(R.string.resolve_failed_summary);
+ }
+ }
+ } else {
+ mTitle = getContext().getResources().getString(R.string.disabled_entry);
+ mAppIconResourceId = R.drawable.ic_disabled;
+ }
+
+ setSummary(mTitle);
+ if (mAppIconDrawable != null) {
+ setIcon(mAppIconDrawable);
+ } else {
+ setIcon(mAppIconResourceId);
+ }
+ }
+
+ private Drawable getDefaultActivityIcon() {
+ return getContext().getResources().getDrawable(android.R.drawable.sym_def_app_icon);
+ }
+
+ public String getValue() {
+ return mValue;
+ }
+
+ public void setValue(String value) {
+ mValue = value;
+ }
+
+ private Drawable resolveAppIcon(PackageItem item) {
+ Drawable appIcon = null;
+ try {
+ appIcon = mPm.getActivityIcon(item.mComponentName);
+ } catch (PackageManager.NameNotFoundException e) {
+ }
+ if (appIcon == null) {
+ appIcon = getDefaultActivityIcon();
+ }
+ return appIcon;
+ }
+
+ public static class AppSelectListPreferenceDialogFragment
+ extends CustomDialogPreference.CustomPreferenceDialogFragment {
+ public static CustomDialogPreference.CustomPreferenceDialogFragment
+ newInstance(String key) {
+ return CustomDialogPreference.CustomPreferenceDialogFragment.newInstance(key);
+ }
+ }
+}
diff --git a/src/org/omnirom/omnilib/preference/ColorSelectDialog.java b/src/org/omnirom/omnilib/preference/ColorSelectDialog.java
new file mode 100644
index 0000000..dee9df0
--- /dev/null
+++ b/src/org/omnirom/omnilib/preference/ColorSelectDialog.java
@@ -0,0 +1,327 @@
+/*
+ * Copyright (C) 2010 Daniel Nilsson
+ * Copyright (C) 2012 The CyanogenMod 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.omnirom.omnilib.preference;
+
+import android.app.Activity;
+import android.app.AlertDialog;
+import android.app.NotificationManager;
+import android.content.Context;
+import android.graphics.Color;
+import android.graphics.PixelFormat;
+import android.os.Bundle;
+import android.text.Editable;
+import android.text.TextWatcher;
+import android.text.InputFilter;
+import android.text.InputFilter.LengthFilter;
+import android.util.Pair;
+import android.util.Log;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.View.OnFocusChangeListener;
+import android.view.ViewGroup;
+import android.view.inputmethod.InputMethodManager;
+import android.widget.AdapterView;
+import android.widget.BaseAdapter;
+import android.widget.EditText;
+import android.widget.LinearLayout;
+import android.widget.Spinner;
+import android.widget.SpinnerAdapter;
+import android.widget.TextView;
+
+import org.omnirom.omnilib.R;
+import org.omnirom.omnigears.ui.ColorPanelView;
+import org.omnirom.omnigears.ui.ColorPickerView;
+import org.omnirom.omnigears.ui.ColorPickerView.OnColorChangedListener;
+
+import java.util.ArrayList;
+import java.util.IllegalFormatException;
+import java.util.Locale;
+
+public class ColorSelectDialog extends AlertDialog implements
+ ColorPickerView.OnColorChangedListener, TextWatcher, OnFocusChangeListener {
+
+ private static final String TAG = "ColorSelectDialog";
+ private final static String STATE_KEY_COLOR = "BatteryLightDialog:color";
+
+ private ColorPickerView mColorPicker;
+
+ private EditText mHexColorInput;
+ private ColorPanelView mNewColor;
+ private LayoutInflater mInflater;
+ private boolean mMultiColor = true;
+ private Spinner mColorList;
+ private LinearLayout mColorListView;
+ private LinearLayout mColorPanelView;
+ private ColorPanelView mNewListColor;
+ private LedColorAdapter mLedColorAdapter;
+ private boolean mWithAlpha;
+
+ private boolean mShowLedPreview;
+ private NotificationManager mNoMan;
+ private Context mContext;
+
+ protected ColorSelectDialog(Context context, int initialColor, boolean showLedPreview) {
+ super(context);
+ mContext = context;
+ mShowLedPreview = showLedPreview;
+ mWithAlpha = false;
+ mMultiColor = getContext().getResources().getBoolean(R.bool.config_has_multi_color_led);
+ init(initialColor);
+ }
+
+ private void init(int color) {
+ // To fight color banding.
+ getWindow().setFormat(PixelFormat.RGBA_8888);
+ setUp(color);
+ }
+
+ /**
+ * This function sets up the dialog with the proper values. If the speedOff parameters
+ * has a -1 value disable both spinners
+ *
+ * @param color - the color to set
+ * @param speedOn - the flash time in ms
+ * @param speedOff - the flash length in ms
+ */
+ private void setUp(int color) {
+ mInflater = (LayoutInflater) getContext()
+ .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
+ View layout = mInflater.inflate(R.layout.dialog_battery_settings, null);
+
+ mNoMan = (NotificationManager)
+ mContext.getSystemService(Context.NOTIFICATION_SERVICE);
+
+ mColorPicker = (ColorPickerView) layout.findViewById(R.id.color_picker_view);
+ mHexColorInput = (EditText) layout.findViewById(R.id.hex_color_input);
+ mNewColor = (ColorPanelView) layout.findViewById(R.id.color_panel);
+ mColorPanelView = (LinearLayout) layout.findViewById(R.id.color_panel_view);
+
+ mColorListView = (LinearLayout) layout.findViewById(R.id.color_list_view);
+ mColorList = (Spinner) layout.findViewById(R.id.color_list_spinner);
+ mNewListColor = (ColorPanelView) layout.findViewById(R.id.color_list_panel);
+
+ mColorPicker.setOnColorChangedListener(this);
+ mHexColorInput.setOnFocusChangeListener(this);
+ setAlphaSliderVisible(mWithAlpha);
+ mColorPicker.setColor(color, true);
+ showLed(color);
+
+ mColorList = (Spinner) layout.findViewById(R.id.color_list_spinner);
+ mLedColorAdapter = new LedColorAdapter(
+ R.array.entries_led_colors,
+ R.array.values_led_colors);
+ mColorList.setAdapter(mLedColorAdapter);
+ mColorList.setSelection(mLedColorAdapter.getColorPosition(color));
+ mColorList.setOnItemSelectedListener(mColorListListener);
+
+ setView(layout);
+
+ // show and hide the correct UI depending if we have multi-color led or not
+ if (mMultiColor){
+ mColorListView.setVisibility(View.GONE);
+ mColorPicker.setVisibility(View.VISIBLE);
+ mColorPanelView.setVisibility(View.VISIBLE);
+ } else {
+ mColorListView.setVisibility(View.VISIBLE);
+ mColorPicker.setVisibility(View.GONE);
+ mColorPanelView.setVisibility(View.GONE);
+ }
+ }
+
+ private AdapterView.OnItemSelectedListener mColorListListener = new AdapterView.OnItemSelectedListener() {
+
+ @Override
+ public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
+ int color = mLedColorAdapter.getColor(position);
+ mNewListColor.setColor(color);
+ }
+
+ @Override
+ public void onNothingSelected(AdapterView<?> parent) {
+ }
+ };
+
+ @Override
+ public Bundle onSaveInstanceState() {
+ Bundle state = super.onSaveInstanceState();
+ state.putInt(STATE_KEY_COLOR, getColor());
+ switchOffLed();
+ return state;
+ }
+
+ @Override
+ public void onRestoreInstanceState(Bundle state) {
+ super.onRestoreInstanceState(state);
+ mColorPicker.setColor(state.getInt(STATE_KEY_COLOR), true);
+ }
+
+ @Override
+ public void onColorChanged(int color) {
+ final boolean hasAlpha = mWithAlpha;
+ final String format = hasAlpha ? "%08x" : "%06x";
+ final int mask = hasAlpha ? 0xFFFFFFFF : 0x00FFFFFF;
+
+ mNewColor.setColor(color);
+ mHexColorInput.setText(String.format(Locale.US, format, color & mask));
+
+ showLed(color);
+ }
+
+ private void showLed(int color) {
+ if (mShowLedPreview) {
+ if (color == 0xFFFFFFFF) {
+ // argb white doesn't work
+ color = 0xffffff;
+ }
+ mNoMan.forceShowLedLight(color);
+ }
+ }
+
+ public void switchOffLed() {
+ if (mShowLedPreview) {
+ mNoMan.forceShowLedLight(-1);
+ }
+ }
+
+ @Override
+ public void onStop() {
+ super.onStop();
+ switchOffLed();
+ }
+
+ public void setAlphaSliderVisible(boolean visible) {
+ mHexColorInput.setFilters(new InputFilter[] { new InputFilter.LengthFilter(visible ? 8 : 6) } );
+ mColorPicker.setAlphaSliderVisible(visible);
+ }
+
+ public int getColor() {
+ if (mMultiColor){
+ return mColorPicker.getColor();
+ } else {
+ return mNewListColor.getColor();
+ }
+ }
+
+ class LedColorAdapter extends BaseAdapter implements SpinnerAdapter {
+ private ArrayList<Pair<String, Integer>> mColors;
+
+ public LedColorAdapter(int ledColorResource, int ledValueResource) {
+ mColors = new ArrayList<Pair<String, Integer>>();
+
+ String[] color_names = getContext().getResources().getStringArray(ledColorResource);
+ String[] color_values = getContext().getResources().getStringArray(ledValueResource);
+
+ for(int i = 0; i < color_values.length; ++i) {
+ try {
+ int color = Color.parseColor(color_values[i]);
+ mColors.add(new Pair<String, Integer>(color_names[i], color));
+ } catch (IllegalArgumentException ex) {
+ // Number format is incorrect, ignore entry
+ }
+ }
+ }
+
+ /**
+ * Will return the position of the spinner entry with the specified
+ * color. Returns 0 if there is no such entry.
+ */
+ public int getColorPosition(int color) {
+ for (int position = 0; position < getCount(); ++position) {
+ if (getItem(position).second.equals(color)) {
+ return position;
+ }
+ }
+
+ return 0;
+ }
+
+ public int getColor(int position) {
+ Pair<String, Integer> item = getItem(position);
+ if (item != null){
+ return item.second;
+ }
+
+ // -1 is white
+ return -1;
+ }
+
+ @Override
+ public int getCount() {
+ return mColors.size();
+ }
+
+ @Override
+ public Pair<String, Integer> getItem(int position) {
+ return mColors.get(position);
+ }
+
+ @Override
+ public long getItemId(int position) {
+ return position;
+ }
+
+ @Override
+ public View getView(int position, View view, ViewGroup parent) {
+ if (view == null) {
+ view = mInflater.inflate(R.layout.led_color_item, null);
+ }
+
+ Pair<String, Integer> entry = getItem(position);
+ ((TextView) view.findViewById(R.id.textViewName)).setText(entry.first);
+
+ return view;
+ }
+ }
+
+ @Override
+ public void beforeTextChanged(CharSequence s, int start, int count, int after) {
+ }
+
+ @Override
+ public void onTextChanged(CharSequence s, int start, int before, int count) {
+ }
+
+ @Override
+ public void afterTextChanged(Editable s) {
+ String hexColor = mHexColorInput.getText().toString();
+ if (!hexColor.isEmpty()) {
+ try {
+ int color = Color.parseColor('#' + hexColor);
+ if (!mWithAlpha) {
+ color |= 0xFF000000; // set opaque
+ }
+ mColorPicker.setColor(color);
+ mNewColor.setColor(color);
+ } catch (IllegalArgumentException ex) {
+ // Number format is incorrect, ignore
+ }
+ }
+ }
+
+ @Override
+ public void onFocusChange(View v, boolean hasFocus) {
+ if (!hasFocus) {
+ mHexColorInput.removeTextChangedListener(this);
+ InputMethodManager inputMethodManager = (InputMethodManager) getContext()
+ .getSystemService(Activity.INPUT_METHOD_SERVICE);
+ inputMethodManager.hideSoftInputFromWindow(v.getWindowToken(), 0);
+ } else {
+ mHexColorInput.addTextChangedListener(this);
+ }
+ }
+}
diff --git a/src/org/omnirom/omnilib/preference/ColorSelectPreference.java b/src/org/omnirom/omnilib/preference/ColorSelectPreference.java
new file mode 100644
index 0000000..4592873
--- /dev/null
+++ b/src/org/omnirom/omnilib/preference/ColorSelectPreference.java
@@ -0,0 +1,150 @@
+/*
+ * Copyright (C) 2012 The CyanogenMod 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.omnirom.omnilib.preference;
+
+import android.app.AlertDialog;
+import android.app.Dialog;
+import android.content.Context;
+import android.content.DialogInterface;
+import android.content.res.Resources;
+import android.graphics.drawable.ShapeDrawable;
+import android.graphics.drawable.shapes.RectShape;
+import android.support.v7.preference.Preference;
+import android.support.v7.preference.PreferenceViewHolder;
+import android.util.AttributeSet;
+import android.widget.ImageView;
+
+import org.omnirom.omnilib.R;
+
+public class ColorSelectPreference extends Preference implements DialogInterface.OnDismissListener {
+
+ private static String TAG = "ColorSelectPreference";
+ public static final int DEFAULT_COLOR = 0xFFFFFF; //White
+
+ private ImageView mLightColorView;
+ private Resources mResources;
+ private int mColorValue;
+ private Dialog mDialog;
+
+ private boolean mShowLedPreview;
+
+ /**
+ * @param context
+ * @param attrs
+ */
+ public ColorSelectPreference(Context context, AttributeSet attrs) {
+ super(context, attrs);
+ mColorValue = DEFAULT_COLOR;
+ init(context, attrs);
+ }
+
+ public ColorSelectPreference(Context context, int color) {
+ super(context, null);
+ mColorValue = color;
+ init(context, null);
+ }
+
+ public ColorSelectPreference(Context context, AttributeSet attrs, int defStyle) {
+ super(context, attrs, defStyle);
+ mColorValue = DEFAULT_COLOR;
+ init(context, attrs);
+ }
+
+ private void init(Context context, AttributeSet attrs) {
+ setLayoutResource(R.layout.preference_color_select);
+ mResources = getContext().getResources();
+ mShowLedPreview = attrs.getAttributeBooleanValue(null, "ledPreview", false);
+ }
+
+ public void setColor(int color) {
+ mColorValue = color;
+ updatePreferenceViews();
+ }
+
+ public int getColor() {
+ return mColorValue;
+ }
+
+ @Override
+ public void onBindViewHolder(PreferenceViewHolder holder) {
+ super.onBindViewHolder(holder);
+
+ mLightColorView = (ImageView) holder.findViewById(R.id.light_color);
+
+ updatePreferenceViews();
+ }
+
+ private void updatePreferenceViews() {
+ final int width = (int) mResources.getDimension(R.dimen.color_preference_width);
+ final int height = (int) mResources.getDimension(R.dimen.color_preference_height);
+
+ if (mLightColorView != null) {
+ mLightColorView.setEnabled(true);
+ mLightColorView.setImageDrawable(createRectShape(width, height, 0xFF000000 | mColorValue));
+ }
+ }
+
+ @Override
+ protected void onClick() {
+ if (mDialog != null && mDialog.isShowing()) return;
+ mDialog = getDialog();
+ mDialog.setOnDismissListener(this);
+ mDialog.show();
+ }
+
+ public Dialog getDialog() {
+ final ColorSelectDialog d = new ColorSelectDialog(getContext(),
+ 0xFF000000 | mColorValue, mShowLedPreview);
+
+ d.setButton(AlertDialog.BUTTON_POSITIVE, mResources.getString(R.string.ok),
+ new DialogInterface.OnClickListener() {
+ @Override
+ public void onClick(DialogInterface dialog, int which) {
+ if (mShowLedPreview) {
+ mColorValue = d.getColor() & 0x00FFFFFF; // strip alpha, led does not support it
+ d.switchOffLed();
+ } else {
+ mColorValue = d.getColor();
+ }
+ updatePreferenceViews();
+ callChangeListener(new Integer(mColorValue));
+ }
+ });
+ d.setButton(AlertDialog.BUTTON_NEGATIVE, mResources.getString(R.string.cancel),
+ new DialogInterface.OnClickListener() {
+ @Override
+ public void onClick(DialogInterface dialog, int which) {
+ d.switchOffLed();
+ }
+ });
+
+ return d;
+ }
+
+ private static ShapeDrawable createRectShape(int width, int height, int color) {
+ ShapeDrawable shape = new ShapeDrawable(new RectShape());
+ shape.setIntrinsicHeight(height);
+ shape.setIntrinsicWidth(width);
+ shape.getPaint().setColor(color);
+ return shape;
+ }
+
+ @Override
+ public void onDismiss(DialogInterface dialog) {
+ mDialog = null;
+ }
+}
diff --git a/src/org/omnirom/omnilib/preference/GlobalCheckBoxPreference.java b/src/org/omnirom/omnilib/preference/GlobalCheckBoxPreference.java
new file mode 100644
index 0000000..c50a25d
--- /dev/null
+++ b/src/org/omnirom/omnilib/preference/GlobalCheckBoxPreference.java
@@ -0,0 +1,66 @@
+/*
+ * Copyright (C) 2013 The CyanogenMod 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.omnirom.omnilib.preference;
+
+import android.content.Context;
+import android.support.v7.preference.CheckBoxPreference;
+import android.provider.Settings;
+import android.util.AttributeSet;
+
+public class GlobalCheckBoxPreference extends CheckBoxPreference {
+ public GlobalCheckBoxPreference(Context context, AttributeSet attrs, int defStyle) {
+ super(context, attrs, defStyle);
+ }
+
+ public GlobalCheckBoxPreference(Context context, AttributeSet attrs) {
+ super(context, attrs);
+ }
+
+ public GlobalCheckBoxPreference(Context context) {
+ super(context, null);
+ }
+
+ @Override
+ protected boolean persistBoolean(boolean value) {
+ if (shouldPersist()) {
+ if (value == getPersistedBoolean(!value)) {
+ // It's already there, so the same as persisting
+ return true;
+ }
+
+ Settings.Global.putInt(getContext().getContentResolver(), getKey(), value ? 1 : 0);
+ return true;
+ }
+ return false;
+ }
+
+ @Override
+ protected boolean getPersistedBoolean(boolean defaultReturnValue) {
+ if (!shouldPersist()) {
+ return defaultReturnValue;
+ }
+
+ return Settings.Global.getInt(getContext().getContentResolver(),
+ getKey(), defaultReturnValue ? 1 : 0) != 0;
+ }
+
+ @Override
+ protected void onSetInitialValue(boolean restoreValue, Object defaultValue) {
+ setChecked(Settings.Global.getString(getContext().getContentResolver(), getKey()) != null ? getPersistedBoolean(isChecked())
+ : (Boolean) defaultValue);
+ }
+}
diff --git a/src/org/omnirom/omnilib/preference/GlobalSettingSwitchPreference.java b/src/org/omnirom/omnilib/preference/GlobalSettingSwitchPreference.java
new file mode 100644
index 0000000..03e1cb3
--- /dev/null
+++ b/src/org/omnirom/omnilib/preference/GlobalSettingSwitchPreference.java
@@ -0,0 +1,64 @@
+/*
+ * Copyright (C) 2014 The CyanogenMod 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.omnirom.omnilib.preference;
+
+import android.content.Context;
+import android.support.v14.preference.SwitchPreference;
+import android.provider.Settings;
+import android.util.AttributeSet;
+
+public class GlobalSettingSwitchPreference extends SwitchPreference {
+ public GlobalSettingSwitchPreference(Context context, AttributeSet attrs, int defStyle) {
+ super(context, attrs, defStyle);
+ }
+
+ public GlobalSettingSwitchPreference(Context context, AttributeSet attrs) {
+ super(context, attrs);
+ }
+
+ public GlobalSettingSwitchPreference(Context context) {
+ super(context, null);
+ }
+
+ @Override
+ protected boolean persistBoolean(boolean value) {
+ if (shouldPersist()) {
+ if (value == getPersistedBoolean(!value)) {
+ // It's already there, so the same as persisting
+ return true;
+ }
+ Settings.Global.putInt(getContext().getContentResolver(), getKey(), value ? 1 : 0);
+ return true;
+ }
+ return false;
+ }
+
+ @Override
+ protected boolean getPersistedBoolean(boolean defaultReturnValue) {
+ if (!shouldPersist()) {
+ return defaultReturnValue;
+ }
+ return Settings.Global.getInt(getContext().getContentResolver(),
+ getKey(), defaultReturnValue ? 1 : 0) != 0;
+ }
+
+ @Override
+ protected void onSetInitialValue(boolean restoreValue, Object defaultValue) {
+ setChecked(Settings.Global.getString(getContext().getContentResolver(), getKey()) != null ? getPersistedBoolean(isChecked())
+ : (Boolean) defaultValue);
+ }
+}
diff --git a/src/org/omnirom/omnilib/preference/ScrollAppsViewPreference.java b/src/org/omnirom/omnilib/preference/ScrollAppsViewPreference.java
new file mode 100644
index 0000000..cb1f847
--- /dev/null
+++ b/src/org/omnirom/omnilib/preference/ScrollAppsViewPreference.java
@@ -0,0 +1,93 @@
+/*
+ * Copyright (C) 2017 The OmniROM Project
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+package org.omnirom.omnilib.preference;
+
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.pm.PackageManager;
+import android.graphics.drawable.Drawable;
+import android.support.v7.preference.Preference;
+import android.support.v7.preference.PreferenceViewHolder;
+import android.util.AttributeSet;
+import android.util.Log;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.widget.ImageView;
+import android.widget.LinearLayout;
+
+import org.omnirom.omnilib.R;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+
+public class ScrollAppsViewPreference extends Preference {
+ private static final String TAG = "ScrollAppsPreference";
+
+ private Context mContext;
+ private List<String> mValues = new ArrayList<String>();
+ private PackageManager mPm;
+ private LayoutInflater mInflater;
+
+ public ScrollAppsViewPreference(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
+ super(context, attrs, defStyleAttr, defStyleRes);
+ initPreference(context);
+ }
+
+ public ScrollAppsViewPreference(Context context, AttributeSet attrs, int defStyleAttr) {
+ super(context, attrs, defStyleAttr);
+ initPreference(context);
+ }
+
+ public ScrollAppsViewPreference(Context context, AttributeSet attrs) {
+ super(context, attrs);
+ initPreference(context);
+ }
+
+ public void setValues(Collection<String> values) {
+ mValues.clear();
+ mValues.addAll(values);
+ }
+
+ @Override
+ public void onBindViewHolder(PreferenceViewHolder holder) {
+ super.onBindViewHolder(holder);
+ LinearLayout linearLayout = (LinearLayout) holder.findViewById(R.id.selected_apps);
+ if (linearLayout.getChildCount() > 0) linearLayout.removeAllViews();
+
+ for (String value : mValues) {
+ try {
+ View v = mInflater.inflate(R.layout.app_grid_item, null);
+ ComponentName componentName = ComponentName.unflattenFromString(value);
+ Drawable icon = mPm.getActivityIcon(componentName);
+ ((ImageView) v.findViewById(R.id.appIcon)).setImageDrawable(icon);
+ v.setPadding(10, 5, 10, 5);
+ linearLayout.addView(v);
+ } catch (PackageManager.NameNotFoundException e) {
+ Log.e(TAG, "Set app icon", e);
+ }
+ }
+ }
+
+ private void initPreference(Context context) {
+ mContext = context;
+ setLayoutResource(R.layout.preference_selected_apps_view);
+ mPm = context.getPackageManager();
+ mInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
+ }
+}
diff --git a/src/org/omnirom/omnilib/preference/SecureCheckBoxPreference.java b/src/org/omnirom/omnilib/preference/SecureCheckBoxPreference.java
new file mode 100644
index 0000000..eb0dd72
--- /dev/null
+++ b/src/org/omnirom/omnilib/preference/SecureCheckBoxPreference.java
@@ -0,0 +1,66 @@
+/*
+ * Copyright (C) 2013 The CyanogenMod 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.omnirom.omnilib.preference;
+
+import android.content.Context;
+import android.support.v7.preference.CheckBoxPreference;
+import android.provider.Settings;
+import android.util.AttributeSet;
+
+public class SecureCheckBoxPreference extends CheckBoxPreference {
+ public SecureCheckBoxPreference(Context context, AttributeSet attrs, int defStyle) {
+ super(context, attrs, defStyle);
+ }
+
+ public SecureCheckBoxPreference(Context context, AttributeSet attrs) {
+ super(context, attrs);
+ }
+
+ public SecureCheckBoxPreference(Context context) {
+ super(context, null);
+ }
+
+ @Override
+ protected boolean persistBoolean(boolean value) {
+ if (shouldPersist()) {
+ if (value == getPersistedBoolean(!value)) {
+ // It's already there, so the same as persisting
+ return true;
+ }
+
+ Settings.Secure.putInt(getContext().getContentResolver(), getKey(), value ? 1 : 0);
+ return true;
+ }
+ return false;
+ }
+
+ @Override
+ protected boolean getPersistedBoolean(boolean defaultReturnValue) {
+ if (!shouldPersist()) {
+ return defaultReturnValue;
+ }
+
+ return Settings.Secure.getInt(getContext().getContentResolver(),
+ getKey(), defaultReturnValue ? 1 : 0) != 0;
+ }
+
+ @Override
+ protected void onSetInitialValue(boolean restoreValue, Object defaultValue) {
+ setChecked(Settings.Secure.getString(getContext().getContentResolver(), getKey()) != null ? getPersistedBoolean(isChecked())
+ : (Boolean) defaultValue);
+ }
+}
diff --git a/src/org/omnirom/omnilib/preference/SecureSettingSwitchPreference.java b/src/org/omnirom/omnilib/preference/SecureSettingSwitchPreference.java
new file mode 100644
index 0000000..02cc031
--- /dev/null
+++ b/src/org/omnirom/omnilib/preference/SecureSettingSwitchPreference.java
@@ -0,0 +1,65 @@
+/*
+ * Copyright (C) 2015 The CyanogenMod 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.omnirom.omnilib.preference;
+
+import android.content.Context;
+import android.support.v14.preference.SwitchPreference;
+import android.util.AttributeSet;
+
+import android.provider.Settings;
+
+public class SecureSettingSwitchPreference extends SwitchPreference {
+ public SecureSettingSwitchPreference(Context context, AttributeSet attrs, int defStyle) {
+ super(context, attrs, defStyle);
+ }
+
+ public SecureSettingSwitchPreference(Context context, AttributeSet attrs) {
+ super(context, attrs);
+ }
+
+ public SecureSettingSwitchPreference(Context context) {
+ super(context, null);
+ }
+
+ @Override
+ protected boolean persistBoolean(boolean value) {
+ if (shouldPersist()) {
+ if (value == getPersistedBoolean(!value)) {
+ // It's already there, so the same as persisting
+ return true;
+ }
+ Settings.Secure.putInt(getContext().getContentResolver(), getKey(), value ? 1 : 0);
+ return true;
+ }
+ return false;
+ }
+
+ @Override
+ protected boolean getPersistedBoolean(boolean defaultReturnValue) {
+ if (!shouldPersist()) {
+ return defaultReturnValue;
+ }
+ return Settings.Secure.getInt(getContext().getContentResolver(),
+ getKey(), defaultReturnValue ? 1 : 0) != 0;
+ }
+
+ @Override
+ protected void onSetInitialValue(boolean restoreValue, Object defaultValue) {
+ setChecked(Settings.Secure.getString(getContext().getContentResolver(), getKey()) != null ? getPersistedBoolean(isChecked())
+ : (Boolean) defaultValue);
+ }
+}
diff --git a/src/org/omnirom/omnilib/preference/SeekBarPreference.java b/src/org/omnirom/omnilib/preference/SeekBarPreference.java
new file mode 100644
index 0000000..c4b356d
--- /dev/null
+++ b/src/org/omnirom/omnilib/preference/SeekBarPreference.java
@@ -0,0 +1,211 @@
+/*
+** Copyright 2013, The ChameleonOS Open Source Project
+** Copyright 2016, The OmniROM 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.omnirom.omnilib.preference;
+
+import android.content.Context;
+import android.content.res.TypedArray;
+import android.support.v7.preference.Preference;
+import android.support.v7.preference.PreferenceViewHolder;
+import android.util.AttributeSet;
+import android.util.Log;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.view.ViewParent;
+import android.widget.SeekBar;
+import android.widget.SeekBar.OnSeekBarChangeListener;
+import android.widget.TextView;
+import org.omnirom.omnilib.R;
+
+public class SeekBarPreference extends Preference implements OnSeekBarChangeListener {
+
+ private final String TAG = getClass().getName();
+
+ private static final String ANDROIDNS = "http://schemas.android.com/apk/res/android";
+ private static final String SETTINGS = "http://schemas.android.com/apk/res/com.android.settings";
+ private static final int DEFAULT_VALUE = 50;
+
+ private int mMaxValue = 100;
+ private int mMinValue = 0;
+ private int mInterval = 1;
+ private int mCurrentValue;
+ private String mUnitsLeft = "";
+ private String mUnitsRight = "";
+ private SeekBar mSeekBar;
+ private TextView mStatusText;
+
+ public SeekBarPreference(Context context, AttributeSet attrs) {
+ super(context, attrs);
+ initPreference(context, attrs);
+ }
+
+ public SeekBarPreference(Context context, AttributeSet attrs, int defStyle) {
+ super(context, attrs, defStyle);
+ initPreference(context, attrs);
+ }
+
+ private void initPreference(Context context, AttributeSet attrs) {
+ setValuesFromXml(attrs);
+ setLayoutResource(R.layout.preference_seek_bar);
+ }
+
+ private void setValuesFromXml(AttributeSet attrs) {
+ final TypedArray typedArray = getContext().obtainStyledAttributes(
+ attrs, R.styleable.SeekBarPreference);
+
+ mMaxValue = attrs.getAttributeIntValue(ANDROIDNS, "max", 100);
+ mMinValue = attrs.getAttributeIntValue(SETTINGS, "min", 0);
+ mUnitsLeft = getAttributeStringValue(attrs, SETTINGS, "unitsLeft", "");
+ String units = getAttributeStringValue(attrs, SETTINGS, "units", "");
+ mUnitsRight = getAttributeStringValue(attrs, SETTINGS, "unitsRight", units);
+
+ Integer id = typedArray.getResourceId(R.styleable.SeekBarPreference_unitsRight, 0);
+ if (id > 0) {
+ mUnitsRight = getContext().getResources().getString(id);
+ }
+ id = typedArray.getResourceId(R.styleable.SeekBarPreference_unitsLeft, 0);
+ if (id > 0) {
+ mUnitsLeft = getContext().getResources().getString(id);
+ }
+
+ try {
+ String newInterval = attrs.getAttributeValue(SETTINGS, "interval");
+ if(newInterval != null)
+ mInterval = Integer.parseInt(newInterval);
+ } catch(Exception e) {
+ Log.e(TAG, "Invalid interval value", e);
+ }
+ typedArray.recycle();
+ }
+
+ private String getAttributeStringValue(AttributeSet attrs, String namespace, String name, String defaultValue) {
+ String value = attrs.getAttributeValue(namespace, name);
+ if(value == null) {
+ value = defaultValue;
+ }
+ return value;
+ }
+
+ @Override
+ public void onDependencyChanged(Preference dependency, boolean disableDependent) {
+ super.onDependencyChanged(dependency, disableDependent);
+ this.setShouldDisableView(true);
+ if (mSeekBar != null) {
+ mSeekBar.setEnabled(!disableDependent);
+ }
+ }
+
+ @Override
+ public void onBindViewHolder(PreferenceViewHolder holder) {
+ super.onBindViewHolder(holder);
+
+ mSeekBar = (SeekBar) holder.findViewById(R.id.seekbar);
+ mSeekBar.setMax(mMaxValue - mMinValue);
+ mSeekBar.setProgress(mCurrentValue - mMinValue);
+ mSeekBar.setOnSeekBarChangeListener(this);
+ mSeekBar.setEnabled(isEnabled());
+
+ mStatusText = (TextView)holder.findViewById(R.id.seekBarPrefValue);
+ mStatusText.setText(String.valueOf(mCurrentValue));
+ mStatusText.setMinimumWidth(30);
+
+ TextView unitsRight = (TextView)holder.findViewById(R.id.seekBarPrefUnitsRight);
+ unitsRight.setText(mUnitsRight);
+ TextView unitsLeft = (TextView)holder.findViewById(R.id.seekBarPrefUnitsLeft);
+ unitsLeft.setText(mUnitsLeft);
+ }
+
+ @Override
+ public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
+ int newValue = progress + mMinValue;
+
+ if(newValue > mMaxValue) {
+ newValue = mMaxValue;
+ } else if(newValue < mMinValue) {
+ newValue = mMinValue;
+ } else if(mInterval != 1 && newValue % mInterval != 0) {
+ newValue = Math.round(((float)newValue)/mInterval)*mInterval;
+ }
+
+ // change rejected, revert to the previous value
+ if (!callChangeListener(newValue)) {
+ seekBar.setProgress(mCurrentValue - mMinValue);
+ return;
+ }
+
+ // change accepted, store it
+ mCurrentValue = newValue;
+ mStatusText.setText(String.valueOf(newValue));
+ persistInt(newValue);
+ }
+
+ @Override
+ public void onStartTrackingTouch(SeekBar seekBar) {}
+
+ @Override
+ public void onStopTrackingTouch(SeekBar seekBar) {
+ notifyChanged();
+ }
+
+ @Override
+ protected Object onGetDefaultValue(TypedArray ta, int index){
+ int defaultValue = ta.getInt(index, DEFAULT_VALUE);
+ return defaultValue;
+ }
+
+ @Override
+ protected void onSetInitialValue(boolean restoreValue, Object defaultValue) {
+ if (restoreValue) {
+ mCurrentValue = getPersistedInt(mCurrentValue);
+ } else {
+ int temp = 0;
+ try {
+ temp = (Integer)defaultValue;
+ } catch(Exception ex) {
+ Log.e(TAG, "Invalid default value: " + defaultValue.toString());
+ }
+ persistInt(temp);
+ mCurrentValue = temp;
+ }
+ }
+
+ public void setValue(int value) {
+ mCurrentValue = value;
+ }
+
+ public void setMaxValue(int value) {
+ mMaxValue = value;
+ if (mSeekBar != null) {
+ mSeekBar.setMax(mMaxValue - mMinValue);
+ }
+ }
+
+ public void setMinValue(int value) {
+ mMinValue = value;
+ if (mSeekBar != null) {
+ mSeekBar.setMax(mMaxValue - mMinValue);
+ }
+ }
+
+ @Override
+ public void setEnabled (boolean enabled) {
+ if (mSeekBar != null) {
+ mSeekBar.setEnabled(enabled);
+ }
+ super.setEnabled(enabled);
+ }
+}
diff --git a/src/org/omnirom/omnilib/preference/SystemCheckBoxPreference.java b/src/org/omnirom/omnilib/preference/SystemCheckBoxPreference.java
new file mode 100644
index 0000000..2a6ed7e
--- /dev/null
+++ b/src/org/omnirom/omnilib/preference/SystemCheckBoxPreference.java
@@ -0,0 +1,66 @@
+/*
+ * Copyright (C) 2013 The CyanogenMod 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.omnirom.omnilib.preference;
+
+import android.content.Context;
+import android.support.v7.preference.CheckBoxPreference;
+import android.provider.Settings;
+import android.util.AttributeSet;
+
+public class SystemCheckBoxPreference extends CheckBoxPreference {
+ public SystemCheckBoxPreference(Context context, AttributeSet attrs, int defStyle) {
+ super(context, attrs, defStyle);
+ }
+
+ public SystemCheckBoxPreference(Context context, AttributeSet attrs) {
+ super(context, attrs);
+ }
+
+ public SystemCheckBoxPreference(Context context) {
+ super(context, null);
+ }
+
+ @Override
+ protected boolean persistBoolean(boolean value) {
+ if (shouldPersist()) {
+ if (value == getPersistedBoolean(!value)) {
+ // It's already there, so the same as persisting
+ return true;
+ }
+
+ Settings.System.putInt(getContext().getContentResolver(), getKey(), value ? 1 : 0);
+ return true;
+ }
+ return false;
+ }
+
+ @Override
+ protected boolean getPersistedBoolean(boolean defaultReturnValue) {
+ if (!shouldPersist()) {
+ return defaultReturnValue;
+ }
+
+ return Settings.System.getInt(getContext().getContentResolver(),
+ getKey(), defaultReturnValue ? 1 : 0) != 0;
+ }
+
+ @Override
+ protected void onSetInitialValue(boolean restoreValue, Object defaultValue) {
+ setChecked(Settings.System.getString(getContext().getContentResolver(), getKey()) != null ? getPersistedBoolean(isChecked())
+ : (Boolean) defaultValue);
+ }
+}
diff --git a/src/org/omnirom/omnilib/preference/SystemSettingSwitchPreference.java b/src/org/omnirom/omnilib/preference/SystemSettingSwitchPreference.java
new file mode 100644
index 0000000..684037d
--- /dev/null
+++ b/src/org/omnirom/omnilib/preference/SystemSettingSwitchPreference.java
@@ -0,0 +1,64 @@
+/*
+ * Copyright (C) 2013 The CyanogenMod 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.omnirom.omnilib.preference;
+
+import android.content.Context;
+import android.provider.Settings;
+import android.support.v14.preference.SwitchPreference;
+import android.util.AttributeSet;
+
+public class SystemSettingSwitchPreference extends SwitchPreference {
+ public SystemSettingSwitchPreference(Context context, AttributeSet attrs, int defStyle) {
+ super(context, attrs, defStyle);
+ }
+
+ public SystemSettingSwitchPreference(Context context, AttributeSet attrs) {
+ super(context, attrs);
+ }
+
+ public SystemSettingSwitchPreference(Context context) {
+ super(context, null);
+ }
+
+ @Override
+ protected boolean persistBoolean(boolean value) {
+ if (shouldPersist()) {
+ if (value == getPersistedBoolean(!value)) {
+ // It's already there, so the same as persisting
+ return true;
+ }
+ Settings.System.putInt(getContext().getContentResolver(), getKey(), value ? 1 : 0);
+ return true;
+ }
+ return false;
+ }
+
+ @Override
+ protected boolean getPersistedBoolean(boolean defaultReturnValue) {
+ if (!shouldPersist()) {
+ return defaultReturnValue;
+ }
+ return Settings.System.getInt(getContext().getContentResolver(),
+ getKey(), defaultReturnValue ? 1 : 0) != 0;
+ }
+
+ @Override
+ protected void onSetInitialValue(boolean restoreValue, Object defaultValue) {
+ setChecked(Settings.System.getString(getContext().getContentResolver(), getKey()) != null ? getPersistedBoolean(isChecked())
+ : (Boolean) defaultValue);
+ }
+}