rog2: Add Refresh rate support
diff --git a/DeviceParts/AndroidManifest.xml b/DeviceParts/AndroidManifest.xml
index 8717dfc..ef43823 100644
--- a/DeviceParts/AndroidManifest.xml
+++ b/DeviceParts/AndroidManifest.xml
@@ -76,5 +76,15 @@
                     android:name="android.service.quicksettings.action.QS_TILE"/>
             </intent-filter>
         </service>
+        <service
+            android:name="org.omnirom.device.FrameRateTileService"
+            android:icon="@drawable/ic_refresh_rate"
+            android:label="@string/refresh_rate_title"
+            android:permission="android.permission.BIND_QUICK_SETTINGS_TILE">
+            <intent-filter>
+                <action
+                    android:name="android.service.quicksettings.action.QS_TILE"/>
+            </intent-filter>
+        </service>
     </application>
 </manifest>
diff --git a/DeviceParts/res/drawable/ic_refresh_rate.xml b/DeviceParts/res/drawable/ic_refresh_rate.xml
new file mode 100644
index 0000000..e6fc714
--- /dev/null
+++ b/DeviceParts/res/drawable/ic_refresh_rate.xml
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="utf-8"?>
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+    android:height="24dp"
+    android:width="24dp"
+    android:viewportWidth="24"
+    android:viewportHeight="24">
+    <path android:fillColor="#ff000000" android:pathData="M16.9846,18.2382 L18.2258,18.2382 C18.2131,18.2499,18.2014,18.2606,18.1897,18.2724 L16.3938,20.0038 L16.218,20.661 L19.0364,20.661 L19.2815,19.746 L17.9094,19.746 C17.923,19.7323,17.9367,19.7196,17.9494,19.706 L19.6974,18.0185 L19.7179,17.999 L19.9142,17.3174 L17.2316,17.3174 Z" />
+    <path android:fillColor="#ff000000" android:pathData="M16.824,16.202 L15.796,16.202 L15.353,17.856 L13.951,17.856 L14.395,16.202 L13.372,16.202 L12.212,20.528 L12.177,20.661 L13.199,20.661 L13.696,18.808 L15.098,18.808 L14.601,20.661 L15.629,20.661 L16.789,16.335 L16.824,16.202 Z" />
+    <path android:fillColor="#ff000000" android:pathData="M20.5676,5.55489 L3.43243,5.55489 A1.99674,1.99674,0,0,0,1.43732,7.549 L1.43732,16.3264 A1.99763,1.99763,0,0,0,3.43244,18.3215 L12.1487,18.3215 L12.5239,16.9229 L3.43243,16.9229 A0.5974,0.5974,0,0,1,2.83593,16.3264 L2.83593,15.5738 L4.38348,14.813 L4.38348,9.052 L2.83594,8.29946 L2.83594,7.549 A0.59756,0.59756,0,0,1,3.43244,6.95153 L20.5676,6.95153 A0.59778,0.59778,0,0,1,21.1651,7.549 L21.1651,8.29845 L19.6165,9.05205 L19.6165,14.812 L21.1651,15.5738 L21.1651,16.3264 A0.59982,0.59982,0,0,1,20.6978,16.9074 L20.5759,16.9353 L20.1779,18.3215 L20.5676,18.3215 A1.99763,1.99763,0,0,0,22.5627,16.3264 L22.5627,7.549 A1.99674,1.99674,0,0,0,20.5676,5.55489 Z" />
+    <path android:fillColor="#ff000000" android:pathData="M9.44588,10.2675 A2.81936,2.81936,0,0,1,10.7652,9.72158 A3.20479,3.20479,0,0,1,11.3922,9.69326 L11.5924,9.71474 L11.902,8.56044 L11.61,8.54482 C11.5641,8.54282,11.5133,8.54189,11.4537,8.54189 A4.48486,4.48486,0,0,0,10.7984,8.59267 A4.271,4.271,0,0,0,8.68317,9.45888 A5.452,5.452,0,0,0,6.77792,12.453 A2.59467,2.59467,0,0,0,6.98492,14.7323 A1.62291,1.62291,0,0,0,8.33746,15.327 A3.14951,3.14951,0,0,0,11.2349,12.9793 A1.80218,1.80218,0,0,0,11.0142,11.3836 A1.5749,1.5749,0,0,0,9.70268,10.8113 A2.47,2.47,0,0,0,8.71049,11.0164 A3.28815,3.28815,0,0,1,9.44588,10.2675 Z M9.94488,12.914 A1.61176,1.61176,0,0,1,8.57188,14.2246 A0.5861,0.5861,0,0,1,8.07774,14.0244 A1.68719,1.68719,0,0,1,8.04356,12.6787 A0.49369,0.49369,0,0,1,8.15001,12.4707 A1.60065,1.60065,0,0,1,9.3453,11.913 A0.63655,0.63655,0,0,1,9.87655,12.1269 A0.90955,0.90955,0,0,1,9.94491,12.914 Z" />
+    <path android:fillColor="#ff000000" android:pathData="M16.7756,11.9335 A3.33176,3.33176,0,0,0,16.6262,9.10536 A1.511,1.511,0,0,0,15.3537,8.54188 C13.9318,8.54188,12.7033,9.82704,12.1477,11.8974 A3.39927,3.39927,0,0,0,12.3303,14.7773 A1.4874,1.4874,0,0,0,13.5569,15.3339 C15.0441,15.3339,16.1877,14.1269,16.7756,11.9335 Z M13.4299,12.0272 C13.8098,10.6082,14.4953,9.6542,15.135,9.6542 A0.4566,0.4566,0,0,1,15.5305,9.82315 A2.76878,2.76878,0,0,1,15.4807,11.8485 C15.0705,13.3788,14.4651,14.2215,13.7756,14.2215 A0.425,0.425,0,0,1,13.4094,14.0535 A2.6914,2.6914,0,0,1,13.4299,12.0272 Z" />
+</vector>
\ No newline at end of file
diff --git a/DeviceParts/res/drawable/ic_refresh_rate_120.xml b/DeviceParts/res/drawable/ic_refresh_rate_120.xml
new file mode 100644
index 0000000..eba0d6b
--- /dev/null
+++ b/DeviceParts/res/drawable/ic_refresh_rate_120.xml
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="utf-8"?>
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+    android:height="24dp"
+    android:width="24dp"
+    android:viewportWidth="24"
+    android:viewportHeight="24">
+    <path android:fillColor="#ff000000" android:pathData="M17,18.24 L18.25,18.24 L18.25,18.24 L16.39,20 L16.22,20.66 L19,20.66 L19.24,19.75 L17.91,19.75 L17.91,19.75 L19.7,18 L19.7,18 L19.89,17.32 L17.23,17.32 Z" />
+    <path android:fillColor="#ff000000" android:pathData="M16.82,16.2 L15.8,16.2 L15.35,17.86 L13.95,17.86 L14.39,16.2 L13.37,16.2 L12.21,20.53 L12.18,20.66 L13.2,20.66 L13.7,18.81 L15.1,18.81 L14.6,20.66 L15.63,20.66 L16.79,16.34 L16.82,16.2 Z" />
+    <path android:fillColor="#ff000000" android:pathData="M20.57,5.55 L3.43,5.55 A2,2,0,0,0,1.43,7.55 L1.43,16.33 A2,2,0,0,0,3.43,18.33 L12.15,18.33 L12.52,16.93 L3.43,16.93 A0.58,0.58,0,0,1,2.84,16.34 L2.84,15.58 L4.38,14.82 L4.38,9.05 L2.84,8.3 L2.84,7.55 A0.59,0.59,0,0,1,3.43,7 L20.57,7 A0.6,0.6,0,0,1,21.17,7.6 L21.17,8.3 L19.62,9.05 L19.62,14.81 L21.17,15.57 L21.17,16.33 A0.61,0.61,0,0,1,20.7,16.91 L20.58,16.91 L20.18,18.29 L20.57,18.29 A2,2,0,0,0,22.57,16.29 L22.57,7.55 A2,2,0,0,0,20.57,5.55 Z" />
+    <path android:fillColor="#ff000000" android:pathData="M18.11,11.93 A3.32,3.32,0,0,0,18,9.11 A1.51,1.51,0,0,0,16.73,8.54 C15.31,8.54,14.08,9.83,13.52,11.9 A3.44,3.44,0,0,0,13.7,14.78 A1.51,1.51,0,0,0,14.93,15.33 C16.38,15.33,17.52,14.13,18.11,11.93 Z M14.76,12.03 C15.14,10.61,15.83,9.65,16.47,9.65 A0.45,0.45,0,0,1,16.86,9.82 C17.1,10.13,17.08,10.82,16.81,11.82 C16.4,13.35,15.81,14.19,15.11,14.19 A0.43,0.43,0,0,1,14.74,14.02 A2.7,2.7,0,0,1,14.76,12 Z" />
+    <path android:fillColor="#ff000000" android:pathData="M6.53,8.64 L5.87,9.82 L7.01,9.82 L5.2,15.19 L6.46,15.19 L8.66,8.64 L6.53,8.64 Z" />
+    <path android:fillColor="#ff000000" android:pathData="M12.94,9.1 A1.67,1.67,0,0,0,11.56,8.54 A2.52,2.52,0,0,0,9.64,9.35 A3.73,3.73,0,0,0,8.93,10.78 L8.93,10.99 L10.13,10.99 L10.13,10.87 A2.62,2.62,0,0,1,10.35,10.32 A1.69,1.69,0,0,1,10.62,9.96 A1,1,0,0,1,10.94,9.76 A1.26,1.26,0,0,1,11.71,9.76 A0.49,0.49,0,0,1,11.93,9.9 A0.64,0.64,0,0,1,12.03,10.14 A0.91,0.91,0,0,1,12.03,10.5 A1.31,1.31,0,0,1,11.76,11.07 C11.68,11.16,11.55,11.3,11.37,11.47 S10.92,11.89,10.6,12.17 L7.41,15.17 L11.79,15.17 L12.19,13.98 L10.19,13.98 L11.64,12.71 C11.94,12.44,12.18,12.22,12.38,12.02 A4.35,4.35,0,0,0,12.83,11.52 A2.23,2.23,0,0,0,13.27,10.52 A1.62,1.62,0,0,0,12.94,9.1 Z" />
+</vector>
diff --git a/DeviceParts/res/drawable/ic_refresh_rate_90.xml b/DeviceParts/res/drawable/ic_refresh_rate_90.xml
new file mode 100644
index 0000000..9d2ef09
--- /dev/null
+++ b/DeviceParts/res/drawable/ic_refresh_rate_90.xml
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="utf-8"?>
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+    android:height="24dp"
+    android:width="24dp"
+    android:viewportWidth="24"
+    android:viewportHeight="24">
+    <path android:fillColor="#ff000000" android:pathData="M16.9846,18.2382 L18.2258,18.2382 C18.2131,18.2499,18.2014,18.2606,18.1897,18.2724 L16.3938,20.0038 L16.218,20.661 L19.0364,20.661 L19.2815,19.746 L17.9094,19.746 C17.923,19.7323,17.9367,19.7196,17.9494,19.706 L19.6974,18.0185 L19.7179,17.999 L19.9142,17.3174 L17.2316,17.3174 Z" />
+    <path android:fillColor="#ff000000" android:pathData="M16.824,16.202 L15.796,16.202 L15.353,17.856 L13.951,17.856 L14.395,16.202 L13.372,16.202 L12.212,20.528 L12.177,20.661 L13.199,20.661 L13.696,18.808 L15.098,18.808 L14.601,20.661 L15.629,20.661 L16.789,16.335 L16.824,16.202 Z" />
+    <path android:fillColor="#ff000000" android:pathData="M20.5676,5.55489 L3.43243,5.55489 A1.99674,1.99674,0,0,0,1.43732,7.549 L1.43732,16.3264 A1.99763,1.99763,0,0,0,3.43244,18.3215 L12.1487,18.3215 L12.5239,16.9229 L3.43243,16.9229 A0.5974,0.5974,0,0,1,2.83593,16.3264 L2.83593,15.5738 L4.38348,14.813 L4.38348,9.052 L2.83594,8.29946 L2.83594,7.549 A0.59756,0.59756,0,0,1,3.43244,6.95153 L20.5676,6.95153 A0.59778,0.59778,0,0,1,21.1651,7.549 L21.1651,8.29845 L19.6165,9.05205 L19.6165,14.812 L21.1651,15.5738 L21.1651,16.3264 A0.59982,0.59982,0,0,1,20.6978,16.9074 L20.5759,16.9353 L20.1779,18.3215 L20.5676,18.3215 A1.99763,1.99763,0,0,0,22.5627,16.3264 L22.5627,7.549 A1.99674,1.99674,0,0,0,20.5676,5.55489 Z" />
+    <path android:fillColor="#ff000000" android:pathData="M9.07928,13.6015 A2.81936,2.81936,0,0,1,7.75994,14.1474 A3.20479,3.20479,0,0,1,7.13294,14.1757 L6.93274,14.1542 L6.62317,15.3085 L6.91517,15.3241 C6.96107,15.3261,7.01185,15.327,7.07142,15.327 A4.48486,4.48486,0,0,0,7.72669,15.2762 A4.271,4.271,0,0,0,9.842,14.4101 A5.452,5.452,0,0,0,11.7473,11.4159 A2.59467,2.59467,0,0,0,11.5403,9.1366 A1.62291,1.62291,0,0,0,10.1878,8.54187 A3.14951,3.14951,0,0,0,7.29034,10.8895 A1.80218,1.80218,0,0,0,7.51104,12.4852 A1.5749,1.5749,0,0,0,8.82256,13.0575 A2.47,2.47,0,0,0,9.81475,12.8524 A3.28815,3.28815,0,0,1,9.07928,13.6015 Z M8.58028,10.955 A1.61176,1.61176,0,0,1,9.95328,9.64445 A0.5861,0.5861,0,0,1,10.4474,9.84465 A1.68719,1.68719,0,0,1,10.4816,11.1903 A0.49369,0.49369,0,0,1,10.3751,11.3983 A1.60065,1.60065,0,0,1,9.17979,11.9559 A0.63655,0.63655,0,0,1,8.64854,11.742 A0.90955,0.90955,0,0,1,8.58026,10.955 Z" />
+    <path android:fillColor="#ff000000" android:pathData="M16.7756,11.9335 A3.33176,3.33176,0,0,0,16.6262,9.10536 A1.511,1.511,0,0,0,15.3537,8.54188 C13.9318,8.54188,12.7033,9.82704,12.1477,11.8974 A3.39927,3.39927,0,0,0,12.3303,14.7773 A1.4874,1.4874,0,0,0,13.5569,15.3339 C15.0441,15.3339,16.1877,14.1269,16.7756,11.9335 Z M13.4299,12.0272 C13.8098,10.6082,14.4953,9.6542,15.135,9.6542 A0.4566,0.4566,0,0,1,15.5305,9.82315 A2.76878,2.76878,0,0,1,15.4807,11.8485 C15.0705,13.3788,14.4651,14.2215,13.7756,14.2215 A0.425,0.425,0,0,1,13.4094,14.0535 A2.6914,2.6914,0,0,1,13.4299,12.0272 Z" />
+</vector>
diff --git a/DeviceParts/res/values/arrays.xml b/DeviceParts/res/values/arrays.xml
new file mode 100644
index 0000000..c00e7d6
--- /dev/null
+++ b/DeviceParts/res/values/arrays.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- 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.
+-->
+<resources>
+    <string-array name="frame_rate_entries" translatable="false">
+        <item>60 Hz</item>
+        <item>90 Hz</item>
+        <item>120 Hz</item>
+    </string-array>
+
+    <string-array name="frame_rate_values" translatable="false">
+        <item>60</item>
+        <item>90</item>
+        <item>120</item>
+    </string-array>
+</resources>
\ No newline at end of file
diff --git a/DeviceParts/res/values/strings.xml b/DeviceParts/res/values/strings.xml
index a08fb1c..8284a21 100644
--- a/DeviceParts/res/values/strings.xml
+++ b/DeviceParts/res/values/strings.xml
@@ -74,4 +74,7 @@
     <string name="wake_entry">Wakeup</string>
     <string name="swipe_up_to_wake_up_title">Swipe up to wake up</string>
     <string name="swipe_up_to_wake_up_summary">Swipe up on the screen to wake up your device from idle mode</string>
+    <string name="category_frame_rate">FPS of the screen</string>
+    <string name="refresh_rate_title">Refresh rate</string>
+    <string name="summary_placeholder"> </string>
 </resources>
diff --git a/DeviceParts/res/xml/framerate_mode.xml b/DeviceParts/res/xml/framerate_mode.xml
new file mode 100644
index 0000000..8df0e8f
--- /dev/null
+++ b/DeviceParts/res/xml/framerate_mode.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 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.
+-->
+<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
+
+    <PreferenceCategory
+        android:key="frame_mode_main"
+        android:title="@string/category_frame_rate">
+        <ListPreference
+            android:key="frame_mode_key"
+            android:title="@string/refresh_rate_title"
+            android:entries="@array/frame_rate_entries"
+            android:entryValues="@array/frame_rate_values"
+            android:persistent="true" />
+    </PreferenceCategory>
+
+</PreferenceScreen>
\ No newline at end of file
diff --git a/DeviceParts/res/xml/main.xml b/DeviceParts/res/xml/main.xml
index 8d41c3f..0b93ce5 100644
--- a/DeviceParts/res/xml/main.xml
+++ b/DeviceParts/res/xml/main.xml
@@ -14,6 +14,10 @@
      limitations under the License.
 -->
 <PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
+
+    <PreferenceCategory
+        android:key="key_gesture_category"
+        android:title="@string/category_gestures_title">
     <Preference
         android:key="gesture_category"
         android:title="@string/category_gestures_title"
@@ -23,7 +27,11 @@
                 android:targetPackage="org.omnirom.device"
                 android:targetClass="org.omnirom.device.GestureSettingsActivity" />
     </Preference>
+    </PreferenceCategory>
 
+    <PreferenceCategory
+        android:key="key_doze_category"
+        android:title="@string/doze_category_title">
     <Preference
         android:key="doze_category"
         android:title="@string/doze_category_title"
@@ -33,6 +41,18 @@
                 android:targetPackage="org.omnirom.device"
                 android:targetClass="org.omnirom.device.DozeSettingsActivity" />
     </Preference>
+    </PreferenceCategory>
+
+    <PreferenceCategory
+        android:key="frame_mode_main"
+        android:title="@string/category_frame_rate">
+        <ListPreference
+            android:key="frame_mode_key"
+            android:title="@string/refresh_rate_title"
+            android:entries="@array/frame_rate_entries"
+            android:entryValues="@array/frame_rate_values"
+            android:persistent="false" />
+    </PreferenceCategory>
 
     <PreferenceCategory
         android:key="screen"
diff --git a/DeviceParts/src/org/omnirom/device/DeviceSettings.java b/DeviceParts/src/org/omnirom/device/DeviceSettings.java
index a9265a0..af5d63d 100644
--- a/DeviceParts/src/org/omnirom/device/DeviceSettings.java
+++ b/DeviceParts/src/org/omnirom/device/DeviceSettings.java
@@ -22,6 +22,7 @@
 import android.content.res.Resources;
 import android.content.Intent;
 import android.os.Bundle;
+import android.os.SystemProperties;
 import androidx.preference.PreferenceFragment;
 import androidx.preference.ListPreference;
 import androidx.preference.Preference;
@@ -48,6 +49,15 @@
     public static final String SETTINGS_GLOVE_KEY = KEY_SETTINGS_PREFIX + KEY_GLOVE_SWITCH;
 
     private static final String KEY_CATEGORY_SCREEN = "screen";
+    private static final String KEY_FRAME_MODE = "frame_mode_key";
+    public static final String VENDOR_FPS = "vendor.asus.dfps";
+    public static final String TEMP_FPS = "temp_fps";
+
+    public static final String DEFAULT_FPS_VALUE = "60";
+    public static final String FPS_VALUE_90 = "90";
+    public static final String FPS_VALUE_120 = "120";
+
+    private static ListPreference mFrameModeRate;
     private static TwoStatePreference mGloveModeSwitch;
 
     @Override
@@ -58,6 +68,13 @@
         mGloveModeSwitch.setChecked(Settings.System.getInt(getContext().getContentResolver(),
         KEY_GLOVE_SWITCH, 0) == 1);
 
+        mFrameModeRate = (ListPreference) findPreference(KEY_FRAME_MODE);
+        mFrameModeRate.setOnPreferenceChangeListener(this);
+        int frameMode = getFrameMode(0);
+        int valueIndex = mFrameModeRate.findIndexOfValue(String.valueOf(frameMode));
+        mFrameModeRate.setValueIndex(valueIndex);
+        mFrameModeRate.setSummary(mFrameModeRate.getEntries()[valueIndex]);
+
     }
 
     @Override
@@ -72,6 +89,13 @@
 
     @Override
     public boolean onPreferenceChange(Preference preference, Object newValue) {
+		if (preference == mFrameModeRate) {
+            String value = (String) newValue;
+            int frameMode = Integer.valueOf(value);
+            setFrameMode(0, frameMode);
+            int valueIndex = mFrameModeRate.findIndexOfValue(value);
+            mFrameModeRate.setSummary(mFrameModeRate.getEntries()[valueIndex]);
+        }
         return true;
     }
 
@@ -93,4 +117,38 @@
     public static boolean isCurrentlyEnabled() {
         return Utils.getLineValueAsBoolean(getFile(), true);
     }
+
+    private int getFrameMode(int position) {
+
+        String value = Settings.System.getString(getContext().getContentResolver(), TEMP_FPS);
+        final String defaultValue = DEFAULT_FPS_VALUE;
+
+        if (value == null) {
+            value = defaultValue;
+        }
+        try {
+            String[] parts = value.split(",");
+            return Integer.valueOf(parts[position]);
+        } catch (Exception e) {
+        }
+        return 0;
+    }
+
+    private void setFrameMode(int position, int fps) {
+
+        String value = Settings.System.getString(getContext().getContentResolver(), TEMP_FPS);
+        final String defaultValue = DEFAULT_FPS_VALUE;
+
+        if (value == null) {
+            value = defaultValue;
+        }
+        try {
+            String[] parts = value.split(",");
+            parts[position] = String.valueOf(fps);
+            String newValue = TextUtils.join(",", parts);
+            Settings.System.putString(getContext().getContentResolver(), TEMP_FPS, newValue);
+            SystemProperties.set(VENDOR_FPS, newValue);
+        } catch (Exception e) {
+        }
+    }
 }
diff --git a/DeviceParts/src/org/omnirom/device/FrameRateTileService.java b/DeviceParts/src/org/omnirom/device/FrameRateTileService.java
new file mode 100644
index 0000000..687439c
--- /dev/null
+++ b/DeviceParts/src/org/omnirom/device/FrameRateTileService.java
@@ -0,0 +1,96 @@
+/*
+ * 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 org.omnirom.device;
+
+import android.graphics.drawable.Icon;
+import android.os.SystemProperties;
+import android.provider.Settings;
+import android.service.quicksettings.Tile;
+import android.service.quicksettings.TileService;
+
+public class FrameRateTileService extends TileService {
+    private static String VENDOR_FPS = "vendor.asus.dfps";
+
+    private static final String DEFAULT_FPS_VALUE = "60";
+    private static final String FPS_VALUE_90 = "90";
+    private static final String FPS_VALUE_120 = "120";
+
+    @Override
+    public void onDestroy() {
+        super.onDestroy();
+    }
+
+    @Override
+    public void onTileAdded() {
+        super.onTileAdded();
+    }
+
+    @Override
+    public void onTileRemoved() {
+        super.onTileRemoved();
+    }
+
+    @Override
+    public void onStartListening() {
+        super.onStartListening();
+
+        String value = Settings.System.getString(this.getContentResolver(), DeviceSettings.TEMP_FPS);
+        switch (value) {
+			case DEFAULT_FPS_VALUE:
+                getQsTile().setIcon(Icon.createWithResource(this, R.drawable.ic_refresh_rate));
+                break;
+            case FPS_VALUE_90:
+                getQsTile().setIcon(Icon.createWithResource(this, R.drawable.ic_refresh_rate_90));
+                break;
+            case FPS_VALUE_120:
+                getQsTile().setIcon(Icon.createWithResource(this, R.drawable.ic_refresh_rate_120));
+                break;
+        }
+        getQsTile().setState(Tile.STATE_ACTIVE);
+        getQsTile().updateTile();
+    }
+
+    @Override
+    public void onStopListening() {
+        super.onStopListening();
+    }
+
+    @Override
+    public void onClick() {
+        super.onClick();
+
+        String value = Settings.System.getString(this.getContentResolver(), DeviceSettings.TEMP_FPS);
+
+        switch (value) {
+			case DEFAULT_FPS_VALUE:
+                Settings.System.putString(this.getContentResolver(), DeviceSettings.TEMP_FPS, FPS_VALUE_90);
+                SystemProperties.set(VENDOR_FPS, FPS_VALUE_90);
+                getQsTile().setIcon(Icon.createWithResource(this, R.drawable.ic_refresh_rate_90));
+                break;
+            case FPS_VALUE_90:
+                Settings.System.putString(this.getContentResolver(), DeviceSettings.TEMP_FPS, FPS_VALUE_120);
+                SystemProperties.set(VENDOR_FPS, FPS_VALUE_120);
+                getQsTile().setIcon(Icon.createWithResource(this, R.drawable.ic_refresh_rate_120));
+                break;
+            case FPS_VALUE_120:
+                Settings.System.putString(this.getContentResolver(), DeviceSettings.TEMP_FPS, DEFAULT_FPS_VALUE);
+                SystemProperties.set(VENDOR_FPS, DEFAULT_FPS_VALUE);
+                getQsTile().setIcon(Icon.createWithResource(this, R.drawable.ic_refresh_rate));
+                break;
+        }
+        getQsTile().updateTile();
+    }
+}
\ No newline at end of file
diff --git a/DeviceParts/src/org/omnirom/device/Startup.java b/DeviceParts/src/org/omnirom/device/Startup.java
index 5479b63..45c295d 100644
--- a/DeviceParts/src/org/omnirom/device/Startup.java
+++ b/DeviceParts/src/org/omnirom/device/Startup.java
@@ -21,6 +21,7 @@
 import android.content.Context;
 import android.content.Intent;
 import android.content.SharedPreferences;
+import android.os.SystemProperties;
 import androidx.preference.PreferenceManager;
 import android.provider.Settings;
 import android.text.TextUtils;
@@ -91,6 +92,16 @@
         enabled = !TextUtils.isEmpty(value) && !value.equals(AppSelectListPreference.DISABLED_ENTRY);
         restore(getGestureFile(GestureSettings.KEY_GOOGLE_APP), enabled);
 
+        value = Settings.System.getString(context.getContentResolver(), DeviceSettings.TEMP_FPS);
+        if (TextUtils.isEmpty(value)) {
+            value = DeviceSettings.DEFAULT_FPS_VALUE;
+            Settings.System.putString(context.getContentResolver(), DeviceSettings.TEMP_FPS, value);
+            SystemProperties.set(DeviceSettings.VENDOR_FPS, value);
+        } else {
+	    Settings.System.putString(context.getContentResolver(), DeviceSettings.TEMP_FPS, value);
+        SystemProperties.set(DeviceSettings.VENDOR_FPS, value);
+        }
+
         value = Settings.System.getString(context.getContentResolver(), Settings.System.OMNI_BUTTON_EXTRA_KEY_MAPPING);
         if (TextUtils.isEmpty(value)) {
             return;