diff --git a/omnipreference/java/omnirom/preference/AppMultiSelectListPreference.java b/omnipreference/java/omnirom/preference/AppMultiSelectListPreference.java
new file mode 100644
index 0000000..008b77d
--- /dev/null
+++ b/omnipreference/java/omnirom/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 omnirom.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 omnirom.preference.R;
+import com.android.settingslib.CustomDialogPreferenceCompat;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
+
+public class AppMultiSelectListPreference extends CustomDialogPreferenceCompat {
+    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/omnipreference/java/omnirom/preference/AppSelectListPreference.java b/omnipreference/java/omnirom/preference/AppSelectListPreference.java
new file mode 100644
index 0000000..86c3152
--- /dev/null
+++ b/omnipreference/java/omnirom/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 omnirom.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 androidx.preference.PreferenceViewHolder;
+import androidx.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.CustomDialogPreferenceCompat;
+import omnirom.preference.R;
+
+public class AppSelectListPreference extends CustomDialogPreferenceCompat {
+
+    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 CustomDialogPreferenceCompat.CustomPreferenceDialogFragment {
+        public static CustomDialogPreferenceCompat.CustomPreferenceDialogFragment
+                newInstance(String key) {
+            return CustomDialogPreferenceCompat.CustomPreferenceDialogFragment.newInstance(key);
+        }
+    }
+}
diff --git a/omnipreference/java/omnirom/preference/ColorSelectDialog.java b/omnipreference/java/omnirom/preference/ColorSelectDialog.java
new file mode 100644
index 0000000..ccd93f9
--- /dev/null
+++ b/omnipreference/java/omnirom/preference/ColorSelectDialog.java
@@ -0,0 +1,331 @@
+/*
+ * 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 omnirom.preference;
+
+import android.app.Activity;
+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 androidx.appcompat.app.AlertDialog;
+
+import omnirom.preference.R;
+import omnirom.ui.ColorPanelView;
+import omnirom.ui.ColorPickerView;
+import omnirom.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 boolean mShowMultiColor;
+    private NotificationManager mNoMan;
+    private Context mContext;
+
+    protected ColorSelectDialog(Context context, int initialColor, boolean showMultiColor, boolean showLedPreview, boolean withAlpha) {
+        super(context);
+        mContext = context;
+        mShowLedPreview = showLedPreview;
+        mWithAlpha = withAlpha;
+        mShowMultiColor = showMultiColor;
+        mMultiColor =
+                (getContext().getResources().getBoolean(R.bool.config_has_multi_color_led) || mShowMultiColor);
+        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/omnipreference/java/omnirom/preference/ColorSelectPreference.java b/omnipreference/java/omnirom/preference/ColorSelectPreference.java
new file mode 100644
index 0000000..97a39d5
--- /dev/null
+++ b/omnipreference/java/omnirom/preference/ColorSelectPreference.java
@@ -0,0 +1,188 @@
+/*
+ * 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 omnirom.preference;
+
+import android.content.Context;
+import android.content.DialogInterface;
+import android.content.res.Resources;
+import android.content.res.TypedArray;
+import android.graphics.drawable.ShapeDrawable;
+import android.graphics.drawable.shapes.RectShape;
+import androidx.preference.Preference;
+import androidx.preference.PreferenceViewHolder;
+import android.util.AttributeSet;
+import android.util.TypedValue;
+import android.widget.ImageView;
+
+import androidx.appcompat.app.AlertDialog;
+
+import omnirom.preference.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;
+    protected int mColorValue;
+    private AlertDialog mDialog;
+
+    private boolean mShowLedPreview;
+    private boolean mShowMultiColor;
+    private boolean mWithAlpha;
+
+    /**
+     * @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);
+    }
+
+    protected void init(Context context, AttributeSet attrs) {
+        setLayoutResource(R.layout.preference_color_select);
+        mResources = getContext().getResources();
+        if (attrs != null) {
+            final TypedArray attributes = context.obtainStyledAttributes(attrs,
+                    R.styleable.ColorSelectPreference);
+            final TypedValue useWithAlpha = attributes.peekValue(
+                    R.styleable.ColorSelectPreference_withAlpha);
+            if (useWithAlpha != null) {
+                mWithAlpha = (useWithAlpha.type == TypedValue.TYPE_INT_BOOLEAN
+                                && useWithAlpha.data != 0);
+            }
+            final TypedValue useLedPreview = attributes.peekValue(
+                    R.styleable.ColorSelectPreference_ledPreview);
+            if (useLedPreview != null) {
+                mShowLedPreview = (useLedPreview.type == TypedValue.TYPE_INT_BOOLEAN
+                                && useLedPreview.data != 0);
+            }
+            final TypedValue useMultiColor = attributes.peekValue(
+                    R.styleable.ColorSelectPreference_multiColor);
+            if (useMultiColor != null) {
+                mShowMultiColor = (useMultiColor.type == TypedValue.TYPE_INT_BOOLEAN
+                                && useMultiColor.data != 0);
+            }
+        }
+    }
+
+    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 AlertDialog getDialog() {
+        final ColorSelectDialog d = new ColorSelectDialog(getContext(),
+                0xFF000000 | mColorValue, mShowMultiColor, mShowLedPreview, mWithAlpha);
+
+        d.setButton(AlertDialog.BUTTON_POSITIVE, mResources.getString(android.R.string.ok),
+                new DialogInterface.OnClickListener() {
+            @Override
+            public void onClick(DialogInterface dialog, int which) {
+                int color = 0;
+                if (mShowLedPreview) {
+                    color =  d.getColor() & 0x00FFFFFF; // strip alpha, led does not support it
+                    d.switchOffLed();
+                } else {
+                    color =  d.getColor();
+                }
+                setColor(color);
+                callChangeListener(new Integer(color));
+            }
+        });
+        d.setButton(AlertDialog.BUTTON_NEGATIVE, mResources.getString(android.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;
+    }
+
+    public void setWithAlpha(boolean value) {
+        mWithAlpha = value;
+    }
+
+    public void setWithLedPreview(boolean value) {
+        mShowLedPreview = value;
+    }
+
+    public void setWithMultiColor(boolean value) {
+        mShowMultiColor = value;
+    }
+}
diff --git a/omnipreference/java/omnirom/preference/GlobalCheckBoxPreference.java b/omnipreference/java/omnirom/preference/GlobalCheckBoxPreference.java
new file mode 100644
index 0000000..01a9e69
--- /dev/null
+++ b/omnipreference/java/omnirom/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 omnirom.preference;
+
+import android.content.Context;
+import androidx.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/omnipreference/java/omnirom/preference/GlobalSettingSwitchPreference.java b/omnipreference/java/omnirom/preference/GlobalSettingSwitchPreference.java
new file mode 100644
index 0000000..1996a4b
--- /dev/null
+++ b/omnipreference/java/omnirom/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 omnirom.preference;
+
+import android.content.Context;
+import androidx.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/omnipreference/java/omnirom/preference/ScrollAppsViewPreference.java b/omnipreference/java/omnirom/preference/ScrollAppsViewPreference.java
new file mode 100644
index 0000000..bf84431
--- /dev/null
+++ b/omnipreference/java/omnirom/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 omnirom.preference;
+
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.pm.PackageManager;
+import android.graphics.drawable.Drawable;
+import androidx.preference.Preference;
+import androidx.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 omnirom.preference.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/omnipreference/java/omnirom/preference/SecureCheckBoxPreference.java b/omnipreference/java/omnirom/preference/SecureCheckBoxPreference.java
new file mode 100644
index 0000000..5f281fb
--- /dev/null
+++ b/omnipreference/java/omnirom/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 omnirom.preference;
+
+import android.content.Context;
+import androidx.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/omnipreference/java/omnirom/preference/SecureSettingSwitchPreference.java b/omnipreference/java/omnirom/preference/SecureSettingSwitchPreference.java
new file mode 100644
index 0000000..0a33f2b
--- /dev/null
+++ b/omnipreference/java/omnirom/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 omnirom.preference;
+
+import android.content.Context;
+import androidx.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/omnipreference/java/omnirom/preference/SeekBarPreference.java b/omnipreference/java/omnirom/preference/SeekBarPreference.java
new file mode 100644
index 0000000..b86a15c
--- /dev/null
+++ b/omnipreference/java/omnirom/preference/SeekBarPreference.java
@@ -0,0 +1,221 @@
+/*
+ ** 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 omnirom.preference;
+
+import android.content.Context;
+import android.content.res.TypedArray;
+import android.util.TypedValue;
+import androidx.preference.Preference;
+import androidx.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 omnirom.preference.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 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(context, attrs);
+        setLayoutResource(R.layout.preference_seek_bar);
+    }
+
+    private void setValuesFromXml(Context context, AttributeSet attrs) {
+        mMaxValue = attrs.getAttributeIntValue(ANDROIDNS, "max", 100);
+
+        final TypedArray attributes = context.obtainStyledAttributes(attrs,
+                R.styleable.SeekBarPreference);
+
+        TypedValue minAttr =
+                attributes.peekValue(R.styleable.SeekBarPreference_min);
+        if (minAttr != null && minAttr.type == TypedValue.TYPE_INT_DEC) {
+            mMinValue = minAttr.data;
+        }
+
+        TypedValue unitsLeftAttr =
+                attributes.peekValue(R.styleable.SeekBarPreference_unitsLeft);
+        CharSequence data = null;
+        if (unitsLeftAttr != null && unitsLeftAttr.type == TypedValue.TYPE_STRING) {
+            if (unitsLeftAttr.resourceId != 0) {
+                data = context.getText(unitsLeftAttr.resourceId);
+            } else {
+                data = unitsLeftAttr.string;
+            }
+        }
+        mUnitsLeft = (data == null) ? "" : data.toString();
+
+        TypedValue unitsRightAttr =
+                attributes.peekValue(R.styleable.SeekBarPreference_unitsRight);
+        data = null;
+        if (unitsRightAttr != null && unitsRightAttr.type == TypedValue.TYPE_STRING) {
+            if (unitsRightAttr.resourceId != 0) {
+                data = context.getText(unitsRightAttr.resourceId);
+            } else {
+                data = unitsRightAttr.string;
+            }
+        }
+        mUnitsRight = (data == null) ? "" : data.toString();
+
+        TypedValue intervalAttr =
+                attributes.peekValue(R.styleable.SeekBarPreference_interval);
+        if (intervalAttr != null && intervalAttr.type == TypedValue.TYPE_INT_DEC) {
+            mInterval = intervalAttr.data;
+        }
+
+        attributes.recycle();
+    }
+
+    @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/omnipreference/java/omnirom/preference/SystemCheckBoxPreference.java b/omnipreference/java/omnirom/preference/SystemCheckBoxPreference.java
new file mode 100644
index 0000000..f6340e8
--- /dev/null
+++ b/omnipreference/java/omnirom/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 omnirom.preference;
+
+import android.content.Context;
+import androidx.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/omnipreference/java/omnirom/preference/SystemSettingSwitchPreference.java b/omnipreference/java/omnirom/preference/SystemSettingSwitchPreference.java
new file mode 100644
index 0000000..647ce90
--- /dev/null
+++ b/omnipreference/java/omnirom/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 omnirom.preference;
+
+import android.content.Context;
+import android.provider.Settings;
+import androidx.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);
+    }
+}
diff --git a/omnipreference/java/omnirom/preference/SystemSettingsColorSelectPreference.java b/omnipreference/java/omnirom/preference/SystemSettingsColorSelectPreference.java
new file mode 100644
index 0000000..2bffc66
--- /dev/null
+++ b/omnipreference/java/omnirom/preference/SystemSettingsColorSelectPreference.java
@@ -0,0 +1,83 @@
+/*
+ * Copyright (C) 2021 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 omnirom.preference;
+
+import android.content.Context;
+import android.provider.Settings;
+import android.util.AttributeSet;
+
+public class SystemSettingsColorSelectPreference extends ColorSelectPreference {
+    private int mDefaultColor = ColorSelectPreference.DEFAULT_COLOR;
+
+    public SystemSettingsColorSelectPreference(Context context, AttributeSet attrs, int defStyle) {
+        super(context, attrs, defStyle);
+    }
+
+    public SystemSettingsColorSelectPreference(Context context, AttributeSet attrs) {
+        super(context, attrs);
+    }
+
+    public SystemSettingsColorSelectPreference(Context context) {
+        super(context, null);
+    }
+
+    @Override
+    protected boolean persistInt(int value) {
+        if (!shouldPersist()) {
+            return false;
+        }
+
+        if (value == getPersistedInt(~value)) {
+            // It's already there, so the same as persisting
+            return true;
+        }
+
+        Settings.System.putInt(getContext().getContentResolver(), getKey(), value);
+        return true;
+    }
+
+    @Override
+    protected int getPersistedInt(int defaultReturnValue) {
+        if (!shouldPersist()) {
+            return defaultReturnValue;
+        }
+
+        return Settings.System.getInt(getContext().getContentResolver(),
+                getKey(), defaultReturnValue);
+    }
+
+    public void updateColor() {
+        super.setColor(getPersistedInt(mColorValue));
+    }
+
+    @Override
+    public void setColor(int color) {
+        super.setColor(color);
+        persistInt(color);
+    }
+
+    @Override
+    public void setDefaultValue(Object defaultValue) {
+        mDefaultColor = (Integer) defaultValue;
+        super.setDefaultValue(defaultValue);
+        super.setColor(getPersistedInt((Integer) defaultValue));
+    }
+
+    public void resetToDefaultValue() {
+        setColor(mDefaultColor);
+    }
+}
diff --git a/omnipreference/java/omnirom/preference/WifiSelectListPreference.java b/omnipreference/java/omnirom/preference/WifiSelectListPreference.java
new file mode 100644
index 0000000..8feba20
--- /dev/null
+++ b/omnipreference/java/omnirom/preference/WifiSelectListPreference.java
@@ -0,0 +1,172 @@
+/*
+ *  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 omnirom.preference;
+
+import android.content.Context;
+import android.util.AttributeSet;
+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.ListView;
+import android.widget.TextView;
+import android.net.wifi.WifiManager;
+import android.icu.text.Collator;
+
+import com.android.settingslib.wifi.AccessPoint;
+import com.android.settingslib.wifi.WifiSavedConfigUtils;
+
+import omnirom.preference.R;
+import com.android.settingslib.CustomDialogPreferenceCompat;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+import java.util.Comparator;
+import java.util.Collections;
+
+public class WifiSelectListPreference extends CustomDialogPreferenceCompat {
+    private List<AccessPoint> mAPInfoList;
+    private ActionListAdapter mAdapter;
+    private List<String> mValues = new ArrayList<String>();
+    private WifiManager mWifiManager;
+    private static final Comparator<AccessPoint> SAVED_NETWORK_COMPARATOR =
+            new Comparator<AccessPoint>() {
+                final Collator mCollator = Collator.getInstance();
+
+                @Override
+                public int compare(AccessPoint ap1, AccessPoint ap2) {
+                    return mCollator.compare(
+                            nullToEmpty(ap1.getSsidStr()), nullToEmpty(ap2.getSsidStr()));
+                }
+
+                private String nullToEmpty(String string) {
+                    return (string == null) ? "" : string;
+                }
+            };
+
+    public WifiSelectListPreference(Context context) {
+        this(context, null);
+    }
+
+    public WifiSelectListPreference(Context context, AttributeSet attrs) {
+        super(context, attrs);
+        setDialogLayoutResource(R.layout.preference_wifi_ap_list);
+        mWifiManager = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);
+        mAPInfoList = WifiSavedConfigUtils.getAllConfigs(context, mWifiManager);
+        Collections.sort(mAPInfoList, SAVED_NETWORK_COMPARATOR);
+
+        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 ActionListAdapter(getContext());
+        final ListView listView = (ListView) view.findViewById(R.id.wifi_ap_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);
+                AccessPoint info = mAdapter.getItem(position);
+
+                if (isChecked) {
+                    mValues.add(info.getSsidStr());
+                } else {
+                    mValues.remove(info.getSsidStr());
+                }
+            }
+        });
+    }
+
+    @Override
+    protected void onDialogClosed(boolean positiveResult) {
+        super.onDialogClosed(positiveResult);
+        if (positiveResult) {
+            callChangeListener(mValues.size() > 0 ? mValues : null);
+        }
+    }
+
+    public class ActionListAdapter extends ArrayAdapter<AccessPoint> {
+        private final LayoutInflater mInflater;
+
+        public ActionListAdapter(Context context) {
+            super(context, 0);
+            mInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
+            addAll(mAPInfoList);
+        }
+
+        @Override
+        public View getView(int position, View convertView, ViewGroup parent) {
+            AppViewHolder holder = AppViewHolder.createOrRecycle(mInflater, convertView);
+            convertView = holder.rootView;
+            AccessPoint info = getItem(position);
+            holder.title.setText(info.getSsidStr());
+            holder.checkBox.setChecked(mValues.contains(info.getSsidStr()));
+            return convertView;
+        }
+
+        @Override
+        public AccessPoint getItem(int position) {
+            return mAPInfoList.get(position);
+        }
+    }
+
+    public static class AppViewHolder {
+        public View rootView;
+        public TextView title;
+        public CheckBox checkBox;
+
+        public static AppViewHolder createOrRecycle(LayoutInflater inflater, View convertView) {
+            if (convertView == null) {
+                convertView = inflater.inflate(R.layout.wifi_ap_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.title = (TextView) convertView.findViewById(R.id.ap_name);
+                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();
+            }
+        }
+    }
+}
+
diff --git a/omnipreference/java/omnirom/ui/AlphaPatternDrawable.java b/omnipreference/java/omnirom/ui/AlphaPatternDrawable.java
new file mode 100644
index 0000000..d91998d
--- /dev/null
+++ b/omnipreference/java/omnirom/ui/AlphaPatternDrawable.java
@@ -0,0 +1,125 @@
+/*
+ * 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 omnirom.ui;
+
+import android.graphics.Bitmap;
+import android.graphics.Canvas;
+import android.graphics.ColorFilter;
+import android.graphics.Paint;
+import android.graphics.Rect;
+import android.graphics.Bitmap.Config;
+import android.graphics.drawable.Drawable;
+
+/**
+ * This drawable that draws a simple white and gray chess board pattern. It's
+ * pattern you will often see as a background behind a partly transparent image
+ * in many applications.
+ *
+ * @author Daniel Nilsson
+ */
+public class AlphaPatternDrawable extends Drawable {
+
+    private int mRectangleSize = 10;
+
+    private Paint mPaint = new Paint();
+    private Paint mPaintWhite = new Paint();
+    private Paint mPaintGray = new Paint();
+
+    private int numRectanglesHorizontal;
+    private int numRectanglesVertical;
+
+    /**
+     * Bitmap in which the pattern will be cached.
+     */
+    private Bitmap mBitmap;
+
+    public AlphaPatternDrawable(int rectangleSize) {
+        mRectangleSize = rectangleSize;
+        mPaintWhite.setColor(0xffffffff);
+        mPaintGray.setColor(0xffcbcbcb);
+    }
+
+    @Override
+    public void draw(Canvas canvas) {
+        if (mBitmap != null) {
+            canvas.drawBitmap(mBitmap, null, getBounds(), mPaint);
+        }
+    }
+
+    @Override
+    public int getOpacity() {
+        return 0;
+    }
+
+    @Override
+    public void setAlpha(int alpha) {
+        throw new UnsupportedOperationException("Alpha is not supported by this drawwable.");
+    }
+
+    @Override
+    public void setColorFilter(ColorFilter cf) {
+        throw new UnsupportedOperationException("ColorFilter is not supported by this drawwable.");
+    }
+
+    @Override
+    protected void onBoundsChange(Rect bounds) {
+        super.onBoundsChange(bounds);
+
+        int height = bounds.height();
+        int width = bounds.width();
+
+        numRectanglesHorizontal = (int) Math.ceil((width / mRectangleSize));
+        numRectanglesVertical = (int) Math.ceil(height / mRectangleSize);
+
+        generatePatternBitmap();
+    }
+
+    /**
+     * This will generate a bitmap with the pattern as big as the rectangle we
+     * were allow to draw on. We do this to cache the bitmap so we don't need
+     * to recreate it each time draw() is called since it takes a few
+     * milliseconds.
+     */
+    private void generatePatternBitmap() {
+
+        if (getBounds().width() <= 0 || getBounds().height() <= 0) {
+            return;
+        }
+
+        mBitmap = Bitmap.createBitmap(getBounds().width(), getBounds().height(), Config.ARGB_8888);
+        Canvas canvas = new Canvas(mBitmap);
+
+        Rect r = new Rect();
+        boolean verticalStartWhite = true;
+        for (int i = 0; i <= numRectanglesVertical; i++) {
+            boolean isWhite = verticalStartWhite;
+            for (int j = 0; j <= numRectanglesHorizontal; j++) {
+                r.top = i * mRectangleSize;
+                r.left = j * mRectangleSize;
+                r.bottom = r.top + mRectangleSize;
+                r.right = r.left + mRectangleSize;
+
+                canvas.drawRect(r, isWhite ? mPaintWhite : mPaintGray);
+
+                isWhite = !isWhite;
+            }
+
+            verticalStartWhite = !verticalStartWhite;
+        }
+    }
+}
diff --git a/omnipreference/java/omnirom/ui/ColorPanelView.java b/omnipreference/java/omnirom/ui/ColorPanelView.java
new file mode 100644
index 0000000..e50ce86
--- /dev/null
+++ b/omnipreference/java/omnirom/ui/ColorPanelView.java
@@ -0,0 +1,171 @@
+/*
+ * 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 omnirom.ui;
+
+import android.content.Context;
+import android.graphics.Canvas;
+import android.graphics.Paint;
+import android.graphics.RectF;
+import android.util.AttributeSet;
+import android.view.View;
+
+/**
+ * This class draws a panel which which will be filled with a color which can be
+ * set. It can be used to show the currently selected color which you will get
+ * from the {@link ColorPickerView}.
+ *
+ * @author Daniel Nilsson
+ */
+public class ColorPanelView extends View {
+
+    /**
+     * The width in pixels of the border surrounding the color panel.
+     */
+    private final static float BORDER_WIDTH_PX = 1;
+
+    private static float mDensity = 1f;
+
+    private int mBorderColor = 0xff6E6E6E;
+    private int mColor = 0xff000000;
+
+    private Paint mBorderPaint;
+    private Paint mColorPaint;
+
+    private RectF mDrawingRect;
+    private RectF mColorRect;
+
+    private AlphaPatternDrawable mAlphaPattern;
+
+    public ColorPanelView(Context context) {
+        this(context, null);
+    }
+
+    public ColorPanelView(Context context, AttributeSet attrs) {
+        this(context, attrs, 0);
+    }
+
+    public ColorPanelView(Context context, AttributeSet attrs, int defStyle) {
+        super(context, attrs, defStyle);
+
+        init();
+    }
+
+    private void init() {
+        mBorderPaint = new Paint();
+        mColorPaint = new Paint();
+        mDensity = getContext().getResources().getDisplayMetrics().density;
+    }
+
+    @Override
+    protected void onDraw(Canvas canvas) {
+
+        final RectF rect = mColorRect;
+
+        if (BORDER_WIDTH_PX > 0) {
+            mBorderPaint.setColor(mBorderColor);
+            canvas.drawRect(mDrawingRect, mBorderPaint);
+        }
+
+        if (mAlphaPattern != null) {
+            mAlphaPattern.draw(canvas);
+        }
+
+        mColorPaint.setColor(mColor);
+
+        canvas.drawRect(rect, mColorPaint);
+    }
+
+    @Override
+    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
+
+        int width = MeasureSpec.getSize(widthMeasureSpec);
+        int height = MeasureSpec.getSize(heightMeasureSpec);
+
+        setMeasuredDimension(width, height);
+    }
+
+    @Override
+    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
+        super.onSizeChanged(w, h, oldw, oldh);
+
+        mDrawingRect = new RectF();
+        mDrawingRect.left = getPaddingLeft();
+        mDrawingRect.right = w - getPaddingRight();
+        mDrawingRect.top = getPaddingTop();
+        mDrawingRect.bottom = h - getPaddingBottom();
+
+        setUpColorRect();
+
+    }
+
+    private void setUpColorRect() {
+        final RectF dRect = mDrawingRect;
+
+        float left = dRect.left + BORDER_WIDTH_PX;
+        float top = dRect.top + BORDER_WIDTH_PX;
+        float bottom = dRect.bottom - BORDER_WIDTH_PX;
+        float right = dRect.right - BORDER_WIDTH_PX;
+
+        mColorRect = new RectF(left, top, right, bottom);
+
+        mAlphaPattern = new AlphaPatternDrawable((int) (5 * mDensity));
+
+        mAlphaPattern.setBounds(Math.round(mColorRect.left),
+                Math.round(mColorRect.top),
+                Math.round(mColorRect.right),
+                Math.round(mColorRect.bottom));
+
+    }
+
+    /**
+     * Set the color that should be shown by this view.
+     *
+     * @param color
+     */
+    public void setColor(int color) {
+        mColor = color;
+        invalidate();
+    }
+
+    /**
+     * Get the color currently show by this view.
+     *
+     * @return
+     */
+    public int getColor() {
+        return mColor;
+    }
+
+    /**
+     * Set the color of the border surrounding the panel.
+     *
+     * @param color
+     */
+    public void setBorderColor(int color) {
+        mBorderColor = color;
+        invalidate();
+    }
+
+    /**
+     * Get the color of the border surrounding the panel.
+     */
+    public int getBorderColor() {
+        return mBorderColor;
+    }
+
+}
diff --git a/omnipreference/java/omnirom/ui/ColorPickerView.java b/omnipreference/java/omnirom/ui/ColorPickerView.java
new file mode 100644
index 0000000..e703181
--- /dev/null
+++ b/omnipreference/java/omnirom/ui/ColorPickerView.java
@@ -0,0 +1,841 @@
+/*
+ * 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 omnirom.ui;
+
+import android.content.Context;
+import android.graphics.Canvas;
+import android.graphics.Color;
+import android.graphics.ComposeShader;
+import android.graphics.LinearGradient;
+import android.graphics.Paint;
+import android.graphics.Point;
+import android.graphics.PorterDuff.Mode;
+import android.graphics.RectF;
+import android.graphics.Shader;
+import android.graphics.Paint.Align;
+import android.graphics.Paint.Style;
+import android.graphics.Shader.TileMode;
+import android.os.Build;
+import android.util.AttributeSet;
+import android.view.MotionEvent;
+import android.view.View;
+
+/**
+ * Displays a color picker to the user and allow them to select a color. A
+ * slider for the alpha channel is also available. Enable it by setting
+ * setAlphaSliderVisible(boolean) to true.
+ *
+ * @author Daniel Nilsson
+ */
+public class ColorPickerView extends View {
+
+    public interface OnColorChangedListener {
+        public void onColorChanged(int color);
+    }
+
+    private final static int PANEL_SAT_VAL = 0;
+    private final static int PANEL_HUE = 1;
+    private final static int PANEL_ALPHA = 2;
+
+    /**
+     * The width in pixels of the border surrounding all color panels.
+     */
+    private final static float BORDER_WIDTH_PX = 1;
+
+    /**
+     * The width in dp of the hue panel.
+     */
+    private float HUE_PANEL_WIDTH = 30f;
+    /**
+     * The height in dp of the alpha panel
+     */
+    private float ALPHA_PANEL_HEIGHT = 20f;
+    /**
+     * The distance in dp between the different color panels.
+     */
+    private float PANEL_SPACING = 10f;
+    /**
+     * The radius in dp of the color palette tracker circle.
+     */
+    private float PALETTE_CIRCLE_TRACKER_RADIUS = 5f;
+    /**
+     * The dp which the tracker of the hue or alpha panel will extend outside of
+     * its bounds.
+     */
+    private float RECTANGLE_TRACKER_OFFSET = 2f;
+
+    private static float mDensity = 1f;
+
+    private OnColorChangedListener mListener;
+
+    private Paint mSatValPaint;
+    private Paint mSatValTrackerPaint;
+
+    private Paint mHuePaint;
+    private Paint mHueTrackerPaint;
+
+    private Paint mAlphaPaint;
+    private Paint mAlphaTextPaint;
+
+    private Paint mBorderPaint;
+
+    private Shader mValShader;
+    private Shader mSatShader;
+    private Shader mHueShader;
+    private Shader mAlphaShader;
+
+    private int mAlpha = 0xff;
+    private float mHue = 360f;
+    private float mSat = 0f;
+    private float mVal = 0f;
+
+    private String mAlphaSliderText = "Alpha";
+    private int mSliderTrackerColor = 0xff1c1c1c;
+    private int mBorderColor = 0xff6E6E6E;
+    private boolean mShowAlphaPanel = false;
+
+    /*
+     * To remember which panel that has the "focus" when processing hardware
+     * button data.
+     */
+    private int mLastTouchedPanel = PANEL_SAT_VAL;
+
+    /**
+     * Offset from the edge we must have or else the finger tracker will get
+     * clipped when it is drawn outside of the view.
+     */
+    private float mDrawingOffset;
+
+    /*
+     * Distance form the edges of the view of where we are allowed to draw.
+     */
+    private RectF mDrawingRect;
+
+    private RectF mSatValRect;
+    private RectF mHueRect;
+    private RectF mAlphaRect;
+
+    private AlphaPatternDrawable mAlphaPattern;
+
+    private Point mStartTouchPoint = null;
+
+    public ColorPickerView(Context context) {
+        this(context, null);
+    }
+
+    public ColorPickerView(Context context, AttributeSet attrs) {
+        this(context, attrs, 0);
+    }
+
+    public ColorPickerView(Context context, AttributeSet attrs, int defStyle) {
+        super(context, attrs, defStyle);
+        init();
+    }
+
+    private void init() {
+        mDensity = getContext().getResources().getDisplayMetrics().density;
+        PALETTE_CIRCLE_TRACKER_RADIUS *= mDensity;
+        RECTANGLE_TRACKER_OFFSET *= mDensity;
+        HUE_PANEL_WIDTH *= mDensity;
+        ALPHA_PANEL_HEIGHT *= mDensity;
+        PANEL_SPACING = PANEL_SPACING * mDensity;
+
+        mDrawingOffset = calculateRequiredOffset();
+        initPaintTools();
+
+        // Needed for receiving track ball motion events.
+        setFocusableInTouchMode(true);
+        setFocusable(true);
+        setClickable(true);
+    }
+
+    private void initPaintTools() {
+        mSatValPaint = new Paint();
+        mSatValTrackerPaint = new Paint();
+        mHuePaint = new Paint();
+        mHueTrackerPaint = new Paint();
+        mAlphaPaint = new Paint();
+        mAlphaTextPaint = new Paint();
+        mBorderPaint = new Paint();
+
+        mSatValTrackerPaint.setStyle(Style.STROKE);
+        mSatValTrackerPaint.setStrokeWidth(2f * mDensity);
+        mSatValTrackerPaint.setAntiAlias(true);
+
+        mHueTrackerPaint.setColor(mSliderTrackerColor);
+        mHueTrackerPaint.setStyle(Style.STROKE);
+        mHueTrackerPaint.setStrokeWidth(2f * mDensity);
+        mHueTrackerPaint.setAntiAlias(true);
+
+        mAlphaTextPaint.setColor(0xff1c1c1c);
+        mAlphaTextPaint.setTextSize(14f * mDensity);
+        mAlphaTextPaint.setAntiAlias(true);
+        mAlphaTextPaint.setTextAlign(Align.CENTER);
+        mAlphaTextPaint.setFakeBoldText(true);
+    }
+
+    private float calculateRequiredOffset() {
+        float offset = Math.max(PALETTE_CIRCLE_TRACKER_RADIUS, RECTANGLE_TRACKER_OFFSET);
+        offset = Math.max(offset, BORDER_WIDTH_PX * mDensity);
+
+        return offset * 1.5f;
+    }
+
+    private int[] buildHueColorArray() {
+        int[] hue = new int[361];
+
+        int count = 0;
+        for (int i = hue.length - 1; i >= 0; i--, count++) {
+            hue[count] = Color.HSVToColor(new float[] {
+                    i, 1f, 1f
+            });
+        }
+        return hue;
+    }
+
+    @Override
+    protected void onDraw(Canvas canvas) {
+        if (mDrawingRect.width() <= 0 || mDrawingRect.height() <= 0) {
+            return;
+        }
+        drawSatValPanel(canvas);
+        drawHuePanel(canvas);
+        drawAlphaPanel(canvas);
+    }
+
+    private void drawSatValPanel(Canvas canvas) {
+        final RectF rect = mSatValRect;
+        int rgb = Color.HSVToColor(new float[] {
+                mHue, 1f, 1f
+        });
+
+        if (BORDER_WIDTH_PX > 0) {
+            mBorderPaint.setColor(mBorderColor);
+            canvas.drawRect(mDrawingRect.left, mDrawingRect.top, rect.right + BORDER_WIDTH_PX,
+                    rect.bottom + BORDER_WIDTH_PX, mBorderPaint);
+        }
+
+        // On Honeycomb+ we need to use software rendering to create the shader properly
+        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
+            setLayerType(View.LAYER_TYPE_SOFTWARE, null);
+        }
+
+        // Get the overlaying gradients ready and create the ComposeShader
+        if (mValShader == null) {
+            mValShader = new LinearGradient(rect.left, rect.top, rect.left, rect.bottom,
+                    0xffffffff, 0xff000000, TileMode.CLAMP);
+        }
+        mSatShader = new LinearGradient(rect.left, rect.top, rect.right, rect.top,
+                0xffffffff, rgb, TileMode.CLAMP);
+        ComposeShader mShader = new ComposeShader(mValShader, mSatShader, Mode.MULTIPLY);
+        mSatValPaint.setShader(mShader);
+        canvas.drawRect(rect, mSatValPaint);
+
+        Point p = satValToPoint(mSat, mVal);
+        mSatValTrackerPaint.setColor(0xff000000);
+        canvas.drawCircle(p.x, p.y, PALETTE_CIRCLE_TRACKER_RADIUS - 1f * mDensity,
+                mSatValTrackerPaint);
+
+        mSatValTrackerPaint.setColor(0xffdddddd);
+        canvas.drawCircle(p.x, p.y, PALETTE_CIRCLE_TRACKER_RADIUS, mSatValTrackerPaint);
+    }
+
+    private void drawHuePanel(Canvas canvas) {
+        final RectF rect = mHueRect;
+
+        if (BORDER_WIDTH_PX > 0) {
+            mBorderPaint.setColor(mBorderColor);
+            canvas.drawRect(rect.left - BORDER_WIDTH_PX,
+                    rect.top - BORDER_WIDTH_PX,
+                    rect.right + BORDER_WIDTH_PX,
+                    rect.bottom + BORDER_WIDTH_PX,
+                    mBorderPaint);
+        }
+
+        if (mHueShader == null) {
+            mHueShader = new LinearGradient(rect.left, rect.top, rect.left, rect.bottom,
+                    buildHueColorArray(), null, TileMode.CLAMP);
+            mHuePaint.setShader(mHueShader);
+        }
+
+        canvas.drawRect(rect, mHuePaint);
+
+        float rectHeight = 4 * mDensity / 2;
+
+        Point p = hueToPoint(mHue);
+
+        RectF r = new RectF();
+        r.left = rect.left - RECTANGLE_TRACKER_OFFSET;
+        r.right = rect.right + RECTANGLE_TRACKER_OFFSET;
+        r.top = p.y - rectHeight;
+        r.bottom = p.y + rectHeight;
+
+        canvas.drawRoundRect(r, 2, 2, mHueTrackerPaint);
+
+    }
+
+    private void drawAlphaPanel(Canvas canvas) {
+        if (!mShowAlphaPanel || mAlphaRect == null || mAlphaPattern == null) {
+            return;
+        }
+
+        final RectF rect = mAlphaRect;
+
+        if (BORDER_WIDTH_PX > 0) {
+            mBorderPaint.setColor(mBorderColor);
+            canvas.drawRect(rect.left - BORDER_WIDTH_PX,
+                    rect.top - BORDER_WIDTH_PX,
+                    rect.right + BORDER_WIDTH_PX,
+                    rect.bottom + BORDER_WIDTH_PX,
+                    mBorderPaint);
+        }
+
+        mAlphaPattern.draw(canvas);
+
+        float[] hsv = new float[] {
+                mHue, mSat, mVal
+        };
+        int color = Color.HSVToColor(hsv);
+        int acolor = Color.HSVToColor(0, hsv);
+
+        mAlphaShader = new LinearGradient(rect.left, rect.top, rect.right, rect.top,
+                color, acolor, TileMode.CLAMP);
+
+        mAlphaPaint.setShader(mAlphaShader);
+
+        canvas.drawRect(rect, mAlphaPaint);
+
+        if (mAlphaSliderText != null && mAlphaSliderText != "") {
+            canvas.drawText(mAlphaSliderText, rect.centerX(), rect.centerY() + 4 * mDensity,
+                    mAlphaTextPaint);
+        }
+
+        float rectWidth = 4 * mDensity / 2;
+        Point p = alphaToPoint(mAlpha);
+
+        RectF r = new RectF();
+        r.left = p.x - rectWidth;
+        r.right = p.x + rectWidth;
+        r.top = rect.top - RECTANGLE_TRACKER_OFFSET;
+        r.bottom = rect.bottom + RECTANGLE_TRACKER_OFFSET;
+
+        canvas.drawRoundRect(r, 2, 2, mHueTrackerPaint);
+    }
+
+    private Point hueToPoint(float hue) {
+        final RectF rect = mHueRect;
+        final float height = rect.height();
+
+        Point p = new Point();
+        p.y = (int) (height - (hue * height / 360f) + rect.top);
+        p.x = (int) rect.left;
+        return p;
+    }
+
+    private Point satValToPoint(float sat, float val) {
+
+        final RectF rect = mSatValRect;
+        final float height = rect.height();
+        final float width = rect.width();
+
+        Point p = new Point();
+
+        p.x = (int) (sat * width + rect.left);
+        p.y = (int) ((1f - val) * height + rect.top);
+
+        return p;
+    }
+
+    private Point alphaToPoint(int alpha) {
+        final RectF rect = mAlphaRect;
+        final float width = rect.width();
+
+        Point p = new Point();
+        p.x = (int) (width - (alpha * width / 0xff) + rect.left);
+        p.y = (int) rect.top;
+        return p;
+    }
+
+    private float[] pointToSatVal(float x, float y) {
+        final RectF rect = mSatValRect;
+        float[] result = new float[2];
+        float width = rect.width();
+        float height = rect.height();
+
+        if (x < rect.left) {
+            x = 0f;
+        } else if (x > rect.right) {
+            x = width;
+        } else {
+            x = x - rect.left;
+        }
+
+        if (y < rect.top) {
+            y = 0f;
+        } else if (y > rect.bottom) {
+            y = height;
+        } else {
+            y = y - rect.top;
+        }
+
+        result[0] = 1.f / width * x;
+        result[1] = 1.f - (1.f / height * y);
+        return result;
+    }
+
+    private float pointToHue(float y) {
+        final RectF rect = mHueRect;
+        float height = rect.height();
+
+        if (y < rect.top) {
+            y = 0f;
+        } else if (y > rect.bottom) {
+            y = height;
+        } else {
+            y = y - rect.top;
+        }
+        return 360f - (y * 360f / height);
+    }
+
+    private int pointToAlpha(int x) {
+        final RectF rect = mAlphaRect;
+        final int width = (int) rect.width();
+
+        if (x < rect.left) {
+            x = 0;
+        } else if (x > rect.right) {
+            x = width;
+        } else {
+            x = x - (int) rect.left;
+        }
+        return 0xff - (x * 0xff / width);
+    }
+
+    @Override
+    public boolean onTrackballEvent(MotionEvent event) {
+        float x = event.getX();
+        float y = event.getY();
+        boolean update = false;
+
+        if (event.getAction() == MotionEvent.ACTION_MOVE) {
+            switch (mLastTouchedPanel) {
+                case PANEL_SAT_VAL:
+                    float sat,
+                    val;
+                    sat = mSat + x / 50f;
+                    val = mVal - y / 50f;
+                    if (sat < 0f) {
+                        sat = 0f;
+                    } else if (sat > 1f) {
+                        sat = 1f;
+                    }
+
+                    if (val < 0f) {
+                        val = 0f;
+                    } else if (val > 1f) {
+                        val = 1f;
+                    }
+                    mSat = sat;
+                    mVal = val;
+                    update = true;
+                    break;
+                case PANEL_HUE:
+                    float hue = mHue - y * 10f;
+                    if (hue < 0f) {
+                        hue = 0f;
+                    } else if (hue > 360f) {
+                        hue = 360f;
+                    }
+                    mHue = hue;
+                    update = true;
+                    break;
+                case PANEL_ALPHA:
+                    if (!mShowAlphaPanel || mAlphaRect == null) {
+                        update = false;
+                    } else {
+                        int alpha = (int) (mAlpha - x * 10);
+                        if (alpha < 0) {
+                            alpha = 0;
+                        } else if (alpha > 0xff) {
+                            alpha = 0xff;
+                        }
+                        mAlpha = alpha;
+                        update = true;
+                    }
+                    break;
+            }
+        }
+
+        if (update) {
+            if (mListener != null) {
+                mListener.onColorChanged(Color.HSVToColor(mAlpha, new float[] {
+                        mHue, mSat, mVal
+                }));
+            }
+            invalidate();
+            return true;
+        }
+        return super.onTrackballEvent(event);
+    }
+
+    @Override
+    public boolean onTouchEvent(MotionEvent event) {
+        boolean update = false;
+
+        switch (event.getAction()) {
+            case MotionEvent.ACTION_DOWN:
+                mStartTouchPoint = new Point((int) event.getX(), (int) event.getY());
+                update = moveTrackersIfNeeded(event);
+                break;
+            case MotionEvent.ACTION_MOVE:
+                update = moveTrackersIfNeeded(event);
+                break;
+            case MotionEvent.ACTION_UP:
+                mStartTouchPoint = null;
+                update = moveTrackersIfNeeded(event);
+                break;
+        }
+
+        if (update) {
+            requestFocus();
+            if (mListener != null) {
+                mListener.onColorChanged(Color.HSVToColor(mAlpha, new float[] {
+                        mHue, mSat, mVal
+                }));
+            }
+            invalidate();
+            return true;
+        }
+
+        return super.onTouchEvent(event);
+    }
+
+    private boolean moveTrackersIfNeeded(MotionEvent event) {
+
+        if (mStartTouchPoint == null)
+            return false;
+
+        boolean update = false;
+        int startX = mStartTouchPoint.x;
+        int startY = mStartTouchPoint.y;
+
+        if (mHueRect.contains(startX, startY)) {
+            mLastTouchedPanel = PANEL_HUE;
+            mHue = pointToHue(event.getY());
+            update = true;
+        } else if (mSatValRect.contains(startX, startY)) {
+            mLastTouchedPanel = PANEL_SAT_VAL;
+            float[] result = pointToSatVal(event.getX(), event.getY());
+            mSat = result[0];
+            mVal = result[1];
+            update = true;
+        } else if (mAlphaRect != null && mAlphaRect.contains(startX, startY)) {
+            mLastTouchedPanel = PANEL_ALPHA;
+            mAlpha = pointToAlpha((int) event.getX());
+            update = true;
+        }
+
+        return update;
+    }
+
+    @Override
+    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
+        int width = 0;
+        int height = 0;
+
+        int widthMode = MeasureSpec.getMode(widthMeasureSpec);
+        int heightMode = MeasureSpec.getMode(heightMeasureSpec);
+
+        int widthAllowed = MeasureSpec.getSize(widthMeasureSpec);
+        int heightAllowed = MeasureSpec.getSize(heightMeasureSpec);
+
+        widthAllowed = chooseWidth(widthMode, widthAllowed);
+        heightAllowed = chooseHeight(heightMode, heightAllowed);
+
+        if (!mShowAlphaPanel) {
+            height = (int) (widthAllowed - PANEL_SPACING - HUE_PANEL_WIDTH);
+
+            // If calculated height (based on the width) is more than the
+            // allowed height.
+            if (height > heightAllowed && heightMode != MeasureSpec.UNSPECIFIED) {
+                height = heightAllowed;
+                width = (int) (height + PANEL_SPACING + HUE_PANEL_WIDTH);
+            } else {
+                width = widthAllowed;
+            }
+        } else {
+
+            width = (int) (heightAllowed - ALPHA_PANEL_HEIGHT + HUE_PANEL_WIDTH);
+
+            if (width > widthAllowed && widthMode != MeasureSpec.UNSPECIFIED) {
+                width = widthAllowed;
+                height = (int) (widthAllowed - HUE_PANEL_WIDTH + ALPHA_PANEL_HEIGHT);
+            } else {
+                height = heightAllowed;
+            }
+        }
+        setMeasuredDimension(width, height);
+    }
+
+    private int chooseWidth(int mode, int size) {
+        if (mode == MeasureSpec.AT_MOST || mode == MeasureSpec.EXACTLY) {
+            return size;
+        } else { // (mode == MeasureSpec.UNSPECIFIED)
+            return getPrefferedWidth();
+        }
+    }
+
+    private int chooseHeight(int mode, int size) {
+        if (mode == MeasureSpec.AT_MOST || mode == MeasureSpec.EXACTLY) {
+            return size;
+        } else { // (mode == MeasureSpec.UNSPECIFIED)
+            return getPrefferedHeight();
+        }
+    }
+
+    private int getPrefferedWidth() {
+        int width = getPrefferedHeight();
+        if (mShowAlphaPanel) {
+            width -= (PANEL_SPACING + ALPHA_PANEL_HEIGHT);
+        }
+        return (int) (width + HUE_PANEL_WIDTH + PANEL_SPACING);
+    }
+
+    private int getPrefferedHeight() {
+        int height = (int) (200 * mDensity);
+        if (mShowAlphaPanel) {
+            height += PANEL_SPACING + ALPHA_PANEL_HEIGHT;
+        }
+        return height;
+    }
+
+    @Override
+    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
+        super.onSizeChanged(w, h, oldw, oldh);
+
+        mDrawingRect = new RectF();
+        mDrawingRect.left = mDrawingOffset + getPaddingLeft();
+        mDrawingRect.right = w - mDrawingOffset - getPaddingRight();
+        mDrawingRect.top = mDrawingOffset + getPaddingTop();
+        mDrawingRect.bottom = h - mDrawingOffset - getPaddingBottom();
+
+        setUpSatValRect();
+        setUpHueRect();
+        setUpAlphaRect();
+    }
+
+    private void setUpSatValRect() {
+        final RectF dRect = mDrawingRect;
+        float panelSide = dRect.height() - BORDER_WIDTH_PX * 2;
+
+        if (mShowAlphaPanel) {
+            panelSide -= PANEL_SPACING + ALPHA_PANEL_HEIGHT;
+        }
+
+        float left = dRect.left + BORDER_WIDTH_PX;
+        float top = dRect.top + BORDER_WIDTH_PX;
+        float bottom = top + panelSide;
+        float right = left + panelSide;
+        mSatValRect = new RectF(left, top, right, bottom);
+    }
+
+    private void setUpHueRect() {
+        final RectF dRect = mDrawingRect;
+
+        float left = dRect.right - HUE_PANEL_WIDTH + BORDER_WIDTH_PX;
+        float top = dRect.top + BORDER_WIDTH_PX;
+        float bottom = dRect.bottom - BORDER_WIDTH_PX
+                - (mShowAlphaPanel ? (PANEL_SPACING + ALPHA_PANEL_HEIGHT) : 0);
+        float right = dRect.right - BORDER_WIDTH_PX;
+
+        mHueRect = new RectF(left, top, right, bottom);
+    }
+
+    private void setUpAlphaRect() {
+        if (!mShowAlphaPanel) {
+            return;
+        }
+
+        final RectF dRect = mDrawingRect;
+        float left = dRect.left + BORDER_WIDTH_PX;
+        float top = dRect.bottom - ALPHA_PANEL_HEIGHT + BORDER_WIDTH_PX;
+        float bottom = dRect.bottom - BORDER_WIDTH_PX;
+        float right = dRect.right - BORDER_WIDTH_PX;
+
+        mAlphaRect = new RectF(left, top, right, bottom);
+        mAlphaPattern = new AlphaPatternDrawable((int) (5 * mDensity));
+        mAlphaPattern.setBounds(Math.round(mAlphaRect.left), Math
+                .round(mAlphaRect.top), Math.round(mAlphaRect.right), Math
+                .round(mAlphaRect.bottom));
+    }
+
+    /**
+     * Set a OnColorChangedListener to get notified when the color selected by
+     * the user has changed.
+     *
+     * @param listener
+     */
+    public void setOnColorChangedListener(OnColorChangedListener listener) {
+        mListener = listener;
+    }
+
+    /**
+     * Set the color of the border surrounding all panels.
+     *
+     * @param color
+     */
+    public void setBorderColor(int color) {
+        mBorderColor = color;
+        invalidate();
+    }
+
+    /**
+     * Get the color of the border surrounding all panels.
+     */
+    public int getBorderColor() {
+        return mBorderColor;
+    }
+
+    /**
+     * Get the current color this view is showing.
+     *
+     * @return the current color.
+     */
+    public int getColor() {
+        return Color.HSVToColor(mAlpha, new float[] {
+                mHue, mSat, mVal
+        });
+    }
+
+    /**
+     * Set the color the view should show.
+     *
+     * @param color The color that should be selected.
+     */
+    public void setColor(int color) {
+        setColor(color, false);
+    }
+
+    /**
+     * Set the color this view should show.
+     *
+     * @param color The color that should be selected.
+     * @param callback If you want to get a callback to your
+     *            OnColorChangedListener.
+     */
+    public void setColor(int color, boolean callback) {
+        int alpha = Color.alpha(color);
+        int red = Color.red(color);
+        int blue = Color.blue(color);
+        int green = Color.green(color);
+        float[] hsv = new float[3];
+
+        Color.RGBToHSV(red, green, blue, hsv);
+        mAlpha = alpha;
+        mHue = hsv[0];
+        mSat = hsv[1];
+        mVal = hsv[2];
+
+        if (callback && mListener != null) {
+            mListener.onColorChanged(Color.HSVToColor(mAlpha, new float[] {
+                    mHue, mSat, mVal
+            }));
+        }
+        invalidate();
+    }
+
+    /**
+     * Get the drawing offset of the color picker view. The drawing offset is
+     * the distance from the side of a panel to the side of the view minus the
+     * padding. Useful if you want to have your own panel below showing the
+     * currently selected color and want to align it perfectly.
+     *
+     * @return The offset in pixels.
+     */
+    public float getDrawingOffset() {
+        return mDrawingOffset;
+    }
+
+    /**
+     * Set if the user is allowed to adjust the alpha panel. Default is false.
+     * If it is set to false no alpha will be set.
+     *
+     * @param visible
+     */
+    public void setAlphaSliderVisible(boolean visible) {
+        if (mShowAlphaPanel != visible) {
+            mShowAlphaPanel = visible;
+
+            /*
+             * Reset all shader to force a recreation. Otherwise they will not
+             * look right after the size of the view has changed.
+             */
+            mValShader = null;
+            mSatShader = null;
+            mHueShader = null;
+            mAlphaShader = null;
+            requestLayout();
+        }
+
+    }
+
+    public boolean isAlphaSliderVisible() {
+        return mShowAlphaPanel;
+    }
+
+    public void setSliderTrackerColor(int color) {
+        mSliderTrackerColor = color;
+        mHueTrackerPaint.setColor(mSliderTrackerColor);
+        invalidate();
+    }
+
+    public int getSliderTrackerColor() {
+        return mSliderTrackerColor;
+    }
+
+    /**
+     * Set the text that should be shown in the alpha slider. Set to null to
+     * disable text.
+     *
+     * @param res string resource id.
+     */
+    public void setAlphaSliderText(int res) {
+        String text = getContext().getString(res);
+        setAlphaSliderText(text);
+    }
+
+    /**
+     * Set the text that should be shown in the alpha slider. Set to null to
+     * disable text.
+     *
+     * @param text Text that should be shown.
+     */
+    public void setAlphaSliderText(String text) {
+        mAlphaSliderText = text;
+        invalidate();
+    }
+
+    /**
+     * Get the current value of the text that will be shown in the alpha slider.
+     *
+     * @return
+     */
+    public String getAlphaSliderText() {
+        return mAlphaSliderText;
+    }
+}
diff --git a/omnipreference/java/omnirom/widget/SecureSettingsSwitch.java b/omnipreference/java/omnirom/widget/SecureSettingsSwitch.java
new file mode 100644
index 0000000..02cfda7
--- /dev/null
+++ b/omnipreference/java/omnirom/widget/SecureSettingsSwitch.java
@@ -0,0 +1,78 @@
+/*
+ * Copyright (C) 2020 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 omnirom.widget;
+
+import android.content.Context;
+import android.content.res.TypedArray;
+import android.os.UserHandle;
+import android.provider.Settings;
+import android.util.AttributeSet;
+import android.util.Log;
+import android.widget.Switch;
+
+import omnirom.preference.R;
+
+public class SecureSettingsSwitch extends Switch {
+
+    private boolean mInflated = false;
+    private int mInitialValue = 0;
+
+    public SecureSettingsSwitch(Context context, AttributeSet attrs, int defStyle) {
+        super(context, attrs, defStyle);
+        setInitialValue(context, attrs);
+    }
+
+    public SecureSettingsSwitch(Context context, AttributeSet attrs) {
+        super(context, attrs);
+        setInitialValue(context, attrs);
+    }
+
+    public SecureSettingsSwitch(Context context) {
+        super(context, null);
+    }
+
+    private void setInitialValue(Context context, AttributeSet attrs) {
+        if (attrs == null) return;
+        final TypedArray attributes = context.obtainStyledAttributes(attrs,
+                R.styleable.SecureSettingsSwitch, 0, 0);
+        mInitialValue =
+                attributes.getInteger(R.styleable.SecureSettingsSwitch_initialValue, 0);
+        attributes.recycle();
+    }
+
+    @Override
+    protected void onFinishInflate() {
+        mInflated = true;
+        switch (mInitialValue) {
+            case 0:
+                setChecked(Settings.Secure.getIntForUser(getContext().getContentResolver(),
+                    getResources().getResourceEntryName(getId()), 0, UserHandle.USER_CURRENT) != 0);
+                break;
+            case 1:
+                setChecked(Settings.Secure.getIntForUser(getContext().getContentResolver(),
+                    getResources().getResourceEntryName(getId()), 1, UserHandle.USER_CURRENT) == 1);
+        }
+    }
+
+    @Override
+    public void setChecked(boolean checked) {
+        if (!mInflated) return;
+        Settings.Secure.putIntForUser(getContext().getContentResolver(),
+                getResources().getResourceEntryName(getId()), checked ? 1 : 0, UserHandle.USER_CURRENT);
+        super.setChecked(checked);
+    }
+}
diff --git a/omnipreference/java/omnirom/widget/SystemSettingsSwitch.java b/omnipreference/java/omnirom/widget/SystemSettingsSwitch.java
new file mode 100644
index 0000000..74fa2fa
--- /dev/null
+++ b/omnipreference/java/omnirom/widget/SystemSettingsSwitch.java
@@ -0,0 +1,78 @@
+/*
+ * Copyright (C) 2020 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 omnirom.widget;
+
+import android.content.Context;
+import android.content.res.TypedArray;
+import android.os.UserHandle;
+import android.provider.Settings;
+import android.util.AttributeSet;
+import android.util.Log;
+import android.widget.Switch;
+
+import omnirom.preference.R;
+
+public class SystemSettingsSwitch extends Switch {
+
+    private boolean mInflated = false;
+    private int mInitialValue = 0;
+
+    public SystemSettingsSwitch(Context context, AttributeSet attrs, int defStyle) {
+        super(context, attrs, defStyle);
+        setInitialValue(context, attrs);
+    }
+
+    public SystemSettingsSwitch(Context context, AttributeSet attrs) {
+        super(context, attrs);
+        setInitialValue(context, attrs);
+    }
+
+    public SystemSettingsSwitch(Context context) {
+        super(context, null);
+    }
+
+    private void setInitialValue(Context context, AttributeSet attrs) {
+        if (attrs == null) return;
+        final TypedArray attributes = context.obtainStyledAttributes(attrs,
+                R.styleable.SystemSettingsSwitch, 0, 0);
+        mInitialValue =
+                attributes.getInteger(R.styleable.SystemSettingsSwitch_initialValue, 0);
+        attributes.recycle();
+    }
+
+    @Override
+    protected void onFinishInflate() {
+        mInflated = true;
+        switch (mInitialValue) {
+            case 0:
+                setChecked(Settings.System.getIntForUser(getContext().getContentResolver(),
+                    getResources().getResourceEntryName(getId()), 0, UserHandle.USER_CURRENT) != 0);
+                break;
+            case 1:
+                setChecked(Settings.System.getIntForUser(getContext().getContentResolver(),
+                    getResources().getResourceEntryName(getId()), 1, UserHandle.USER_CURRENT) == 1);
+        }
+    }
+
+    @Override
+    public void setChecked(boolean checked) {
+        if (!mInflated) return;
+        Settings.System.putIntForUser(getContext().getContentResolver(),
+                getResources().getResourceEntryName(getId()), checked ? 1 : 0, UserHandle.USER_CURRENT);
+        super.setChecked(checked);
+    }
+}
