├── .gitignore ├── .travis.yml ├── EnableAmbientDisplay-Xposed.iml ├── README.md ├── app ├── .gitignore ├── app-release.apk ├── app.iml ├── build.gradle ├── proguard-rules.pro └── src │ └── main │ ├── AndroidManifest.xml │ ├── assets │ └── xposed_init │ ├── java │ └── com │ │ └── dvd │ │ └── android │ │ └── xposed │ │ └── enableambientdisplay │ │ ├── MainActivity.java │ │ ├── XposedMod.java │ │ ├── hook │ │ ├── AndroidHook.java │ │ └── SystemUiHook.java │ │ ├── services │ │ ├── BootReceiver.java │ │ └── SensorService.java │ │ └── utils │ │ ├── RegexValidatorPreference.java │ │ ├── SeekBarDialogPreference.java │ │ └── Utils.java │ └── res │ ├── layout │ ├── activity_settings.xml │ ├── long_title_preference.xml │ └── preference_seek_bar_dialog.xml │ ├── menu │ └── main.xml │ ├── mipmap-hdpi │ └── ic_launcher.png │ ├── mipmap-mdpi │ └── ic_launcher.png │ ├── mipmap-xhdpi │ └── ic_launcher.png │ ├── mipmap-xxhdpi │ └── ic_launcher.png │ ├── mipmap-xxxhdpi │ └── ic_launcher.png │ ├── values-it │ └── strings.xml │ ├── values │ ├── attrs.xml │ └── strings.xml │ └── xml │ └── prefs.xml ├── build.gradle ├── gradle.properties ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat ├── screenshots ├── ambient-display.png ├── main_activity.png └── settings.png └── settings.gradle /.gitignore: -------------------------------------------------------------------------------- 1 | .gradle 2 | /local.properties 3 | .idea/ 4 | .DS_Store 5 | *.iml 6 | 7 | ### Android template 8 | # Built application files 9 | #*.apk 10 | 11 | # Generated files 12 | bin/ 13 | gen/ 14 | 15 | # Gradle files 16 | build/ 17 | 18 | # Proguard folder generated by Eclipse 19 | proguard/ 20 | 21 | # Log Files 22 | *.log 23 | 24 | app/manifest-merger-release-report.txt -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: android 2 | jdk: oraclejdk8 3 | before_install: 4 | - chmod +x gradlew 5 | 6 | android: 7 | components: 8 | - tools 9 | - platform-tools 10 | - build-tools-26.0.1 11 | - android-26 -------------------------------------------------------------------------------- /EnableAmbientDisplay-Xposed.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | Enable Ambient Display - Xposed 2 | =============================== 3 | [![Build Status](https://travis-ci.org/DVDAndroid/Xposed-EnableAmbientDisplay.svg?branch=master)](https://travis-ci.org/DVDAndroid/Xposed-EnableAmbientDisplay) 4 | 5 | 6 | Easy Xposed module for Lollipop which add Ambient Display 7 | 8 | 9 | 10 | 11 | 12 | 13 | Forum 14 | ----- 15 | 16 | [XDA](http://forum.xda-developers.com/xposed/modules/enable-ambient-display-xposed-t3031347) 17 | 18 | Credits 19 | ------- 20 | 21 | [XDA-forum](http://forum.xda-developers.com/google-nexus-5/themes-apps/how-to-add-ambient-display-settings-t2942838) 22 | 23 | LICENSE 24 | ------- 25 | 26 | [MIT License](http://opensource.org/licenses/MIT) 27 | 28 | 29 | Ambient Display WITHOUT Xposed 30 | ------------------------------ 31 | 32 | See [AmbientDisplayTheme](https://github.com/DVDAndroid/AmbientDisplayTheme) 33 | -------------------------------------------------------------------------------- /app/.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | -------------------------------------------------------------------------------- /app/app-release.apk: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DVDAndroid/Xposed-EnableAmbientDisplay/f9e16f17e7a4f7aa002d50a971ec4121ab116363/app/app-release.apk -------------------------------------------------------------------------------- /app/app.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 8 | 9 | 10 | 11 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | -------------------------------------------------------------------------------- /app/build.gradle: -------------------------------------------------------------------------------- 1 | /* 2 | * The MIT License (MIT) 3 | * 4 | * Copyright (c) 2015 DVDAndroid 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in all 14 | * copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | * SOFTWARE. 23 | */ 24 | 25 | apply plugin: 'com.android.application' 26 | 27 | android { 28 | compileSdkVersion 26 29 | buildToolsVersion "26.0.1" 30 | defaultConfig { 31 | applicationId "com.dvd.android.xposed.enableambientdisplay" 32 | minSdkVersion 21 33 | targetSdkVersion 26 34 | versionCode 22 35 | versionName '2.2' 36 | } 37 | buildTypes { 38 | release { 39 | minifyEnabled false 40 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' 41 | } 42 | } 43 | productFlavors { 44 | } 45 | } 46 | 47 | dependencies { 48 | provided 'de.robv.android.xposed:api:82' 49 | } 50 | -------------------------------------------------------------------------------- /app/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # By default, the flags in this file are appended to flags specified 3 | # in D:\ADT\sdk/tools/proguard/proguard-android.txt 4 | # You can edit the include path and order by changing the proguardFiles 5 | # directive in build.gradle. 6 | # 7 | # For more details, see 8 | # http://developer.android.com/guide/developing/tools/proguard.html 9 | 10 | # Add any project specific keep options here: 11 | 12 | # If your project uses WebView with JS, uncomment the following 13 | # and specify the fully qualified class name to the JavaScript interface 14 | # class: 15 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 16 | # public *; 17 | #} 18 | -------------------------------------------------------------------------------- /app/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 25 | 29 | 30 | 31 | 32 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 50 | 51 | 52 | 53 | 54 | 55 | 60 | 61 | 64 | 68 | 71 | 72 | 73 | 74 | -------------------------------------------------------------------------------- /app/src/main/assets/xposed_init: -------------------------------------------------------------------------------- 1 | com.dvd.android.xposed.enableambientdisplay.XposedMod -------------------------------------------------------------------------------- /app/src/main/java/com/dvd/android/xposed/enableambientdisplay/MainActivity.java: -------------------------------------------------------------------------------- 1 | /* 2 | * The MIT License (MIT) 3 | * 4 | * Copyright (c) 2015 DVDAndroid 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in all 14 | * copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | * SOFTWARE. 23 | */ 24 | 25 | package com.dvd.android.xposed.enableambientdisplay; 26 | 27 | import android.annotation.SuppressLint; 28 | import android.app.Activity; 29 | import android.app.AlertDialog; 30 | import android.content.Context; 31 | import android.content.Intent; 32 | import android.content.SharedPreferences; 33 | import android.os.Build; 34 | import android.os.Bundle; 35 | import android.os.Handler; 36 | import android.preference.PreferenceFragment; 37 | import android.text.method.LinkMovementMethod; 38 | import android.view.Menu; 39 | import android.view.MenuItem; 40 | import android.widget.TextView; 41 | import android.widget.Toast; 42 | 43 | import com.dvd.android.xposed.enableambientdisplay.services.SensorService; 44 | 45 | import java.io.File; 46 | 47 | import static com.dvd.android.xposed.enableambientdisplay.utils.Utils.ACTION_DOZE; 48 | import static com.dvd.android.xposed.enableambientdisplay.utils.Utils.ACTION_HOT_REBOOT; 49 | import static com.dvd.android.xposed.enableambientdisplay.utils.Utils.ACTION_PREFS_CHANGED; 50 | import static com.dvd.android.xposed.enableambientdisplay.utils.Utils.ACTION_SLEEP; 51 | import static com.dvd.android.xposed.enableambientdisplay.utils.Utils.DOZE_ALPHA; 52 | import static com.dvd.android.xposed.enableambientdisplay.utils.Utils.DOZE_BRIGHTNESS; 53 | import static com.dvd.android.xposed.enableambientdisplay.utils.Utils.DOZE_IN; 54 | import static com.dvd.android.xposed.enableambientdisplay.utils.Utils.DOZE_OUT; 55 | import static com.dvd.android.xposed.enableambientdisplay.utils.Utils.DOZE_PROXIMITY; 56 | import static com.dvd.android.xposed.enableambientdisplay.utils.Utils.DOZE_PULSE_SCHEDULE; 57 | import static com.dvd.android.xposed.enableambientdisplay.utils.Utils.DOZE_RESETS; 58 | import static com.dvd.android.xposed.enableambientdisplay.utils.Utils.DOZE_VISIBILITY; 59 | import static com.dvd.android.xposed.enableambientdisplay.utils.Utils.DOZE_WITH_POWER_KEY; 60 | import static com.dvd.android.xposed.enableambientdisplay.utils.Utils.EXTRA_KEY; 61 | import static com.dvd.android.xposed.enableambientdisplay.utils.Utils.EXTRA_VALUE; 62 | 63 | public class MainActivity extends Activity { 64 | 65 | private static MenuItem mServiceItem; 66 | 67 | public static boolean isEnabled() { 68 | return false; 69 | } 70 | 71 | private static void updateMenuItem(boolean enabled) { 72 | if (mServiceItem == null) return; 73 | 74 | mServiceItem.setVisible(enabled); 75 | 76 | new android.os.Handler().postDelayed(new Runnable() { 77 | @Override 78 | public void run() { 79 | mServiceItem.setTitle(SensorService.isRunning() ? R.string.stop_service : R.string.start_service); 80 | } 81 | }, 500); 82 | } 83 | 84 | @Override 85 | protected void onCreate(Bundle savedInstanceState) { 86 | super.onCreate(savedInstanceState); 87 | setContentView(R.layout.activity_settings); 88 | if (savedInstanceState == null) 89 | getFragmentManager().beginTransaction().replace(R.id.fragment, new SettingsFragment()).commit(); 90 | } 91 | 92 | @Override 93 | @SuppressLint("WorldReadableFiles") 94 | @SuppressWarnings("deprecation") 95 | public boolean onCreateOptionsMenu(Menu menu) { 96 | getMenuInflater().inflate(R.menu.main, menu); 97 | 98 | mServiceItem = menu.findItem(R.id.service); 99 | 100 | 101 | //noinspection ConstantConditions 102 | if (!isEnabled()) { 103 | menu.removeItem(R.id.hot_reboot); 104 | menu.removeItem(R.id.service); 105 | } else { 106 | SharedPreferences prefs = getSharedPreferences(MainActivity.class.getSimpleName(), MODE_WORLD_READABLE); 107 | updateMenuItem(prefs.getBoolean(DOZE_PROXIMITY, false)); 108 | } 109 | return true; 110 | } 111 | 112 | @Override 113 | public boolean onOptionsItemSelected(MenuItem item) { 114 | switch (item.getItemId()) { 115 | case R.id.testIt: 116 | sendBroadcast(new Intent().setAction(ACTION_SLEEP)); 117 | 118 | new Handler().postDelayed(new Runnable() { 119 | @Override 120 | public void run() { 121 | sendBroadcast(new Intent().setAction(ACTION_DOZE)); 122 | } 123 | }, 2000); 124 | break; 125 | case R.id.service: 126 | Intent service = new Intent().setClass(this, SensorService.class); 127 | if (SensorService.isRunning()) { 128 | Toast.makeText(this, R.string.service_stopped, Toast.LENGTH_SHORT).show(); 129 | stopService(service); 130 | } else { 131 | Toast.makeText(this, R.string.service_started, Toast.LENGTH_SHORT).show(); 132 | startService(service); 133 | } 134 | updateMenuItem(true); 135 | break; 136 | case R.id.hot_reboot: 137 | sendBroadcast(new Intent(ACTION_HOT_REBOOT)); 138 | break; 139 | case R.id.info: 140 | AlertDialog d = new AlertDialog.Builder(this) 141 | .setPositiveButton(android.R.string.ok, null) 142 | .setTitle(R.string.info) 143 | .setMessage(R.string.about) 144 | .create(); 145 | d.show(); 146 | 147 | ((TextView) d.findViewById(android.R.id.message)).setMovementMethod(LinkMovementMethod.getInstance()); 148 | 149 | break; 150 | } 151 | 152 | return super.onOptionsItemSelected(item); 153 | } 154 | 155 | public static class SettingsFragment extends PreferenceFragment implements SharedPreferences.OnSharedPreferenceChangeListener { 156 | 157 | private Intent mIntent; 158 | private SharedPreferences mPrefs; 159 | private String mKey; 160 | 161 | @Override 162 | @SuppressLint("CommitPrefEdits") 163 | @SuppressWarnings("deprecation") 164 | public void onCreate(Bundle savedInstanceState) { 165 | super.onCreate(savedInstanceState); 166 | getPreferenceManager().setSharedPreferencesMode(Context.MODE_WORLD_READABLE); 167 | getPreferenceManager().setSharedPreferencesName(MainActivity.class.getSimpleName()); 168 | addPreferencesFromResource(R.xml.prefs); 169 | // SELinux test, see XposedMod 170 | getPreferenceManager().getSharedPreferences().edit().putBoolean("can_read_prefs", true).apply(); 171 | 172 | SharedPreferences prefs = getActivity().getPreferences(Context.MODE_WORLD_READABLE); 173 | 174 | //noinspection ConstantConditions 175 | if (isEnabled()) { 176 | getPreferenceScreen().removePreference(findPreference("not_enabled")); 177 | } 178 | 179 | if (prefs.getBoolean("welcome", true)) { 180 | new AlertDialog.Builder(getActivity()) 181 | .setPositiveButton(android.R.string.ok, null) 182 | .setTitle(R.string.info) 183 | .setMessage(R.string.aosp) 184 | .show(); 185 | 186 | prefs.edit().putBoolean("welcome", false).apply(); 187 | } 188 | 189 | if (Build.VERSION.SDK_INT > 24) { 190 | getPreferenceScreen().removePreference(findPreference(DOZE_RESETS)); 191 | } else if (Build.VERSION.SDK_INT != 22 || Build.VERSION.SDK_INT != 23) { 192 | getPreferenceScreen().removePreference(findPreference(DOZE_ALPHA)); 193 | } 194 | 195 | } 196 | 197 | @Override 198 | public void onResume() { 199 | super.onResume(); 200 | getPreferenceManager().getSharedPreferences().registerOnSharedPreferenceChangeListener(this); 201 | } 202 | 203 | @Override 204 | @SuppressLint("SetWorldReadable") 205 | public void onPause() { 206 | super.onPause(); 207 | getPreferenceManager().getSharedPreferences().unregisterOnSharedPreferenceChangeListener(this); 208 | File sharedPrefsDir = new File(getActivity().getFilesDir(), "../shared_prefs"); 209 | File sharedPrefsFile = new File(sharedPrefsDir, MainActivity.class.getSimpleName() + ".xml"); 210 | if (sharedPrefsFile.exists()) { 211 | //noinspection ResultOfMethodCallIgnored 212 | sharedPrefsFile.setReadable(true, false); 213 | } 214 | } 215 | 216 | 217 | @Override 218 | @SuppressLint("CommitPrefEdits") 219 | public void onSharedPreferenceChanged(SharedPreferences prefs, String key) { 220 | mIntent = new Intent(); 221 | mPrefs = prefs; 222 | mKey = key; 223 | 224 | switch (key) { 225 | case DOZE_BRIGHTNESS: 226 | Toast.makeText(getActivity(), R.string.reboot_required, Toast.LENGTH_SHORT).show(); 227 | break; 228 | case DOZE_IN: 229 | case DOZE_OUT: 230 | updateIntent(1000); 231 | break; 232 | case DOZE_VISIBILITY: 233 | updateIntent(3000); 234 | break; 235 | case DOZE_RESETS: 236 | updateIntent(1); 237 | break; 238 | case DOZE_ALPHA: 239 | if (Build.VERSION.SDK_INT >= 22) { 240 | updateIntent(222); 241 | } else { 242 | Toast.makeText(getActivity(), R.string.reboot_required, Toast.LENGTH_SHORT).show(); 243 | } 244 | break; 245 | case DOZE_WITH_POWER_KEY: 246 | updateIntent(false); 247 | 248 | if (mPrefs.getBoolean(mKey + "_warning", true)) { 249 | new AlertDialog.Builder(getActivity()).setTitle(R.string.caution) 250 | .setMessage(R.string.caution_power_key) 251 | .setPositiveButton(android.R.string.ok, null).show(); 252 | 253 | mPrefs.edit().putBoolean(mKey + "_warning", false).apply(); 254 | } 255 | break; 256 | case DOZE_PULSE_SCHEDULE: 257 | updateIntent("10s,30s,60s"); 258 | break; 259 | case DOZE_PROXIMITY: 260 | mIntent.setClass(getActivity(), SensorService.class); 261 | 262 | //noinspection ConstantConditions 263 | if (prefs.getBoolean(key, false) && isEnabled()) { 264 | Toast.makeText(getActivity(), R.string.service_started, Toast.LENGTH_SHORT).show(); 265 | getActivity().startService(mIntent); 266 | } else { 267 | if (SensorService.isRunning()) { 268 | Toast.makeText(getActivity(), R.string.service_stopped, Toast.LENGTH_SHORT).show(); 269 | getActivity().stopService(mIntent); 270 | } 271 | } 272 | updateMenuItem(prefs.getBoolean(key, false)); 273 | } 274 | 275 | if (mIntent.getAction() != null) { 276 | prefs.edit().commit(); 277 | getActivity().sendBroadcast(mIntent); 278 | } 279 | } 280 | 281 | private void updateIntent(Object defaultValue) { 282 | mIntent.setAction(ACTION_PREFS_CHANGED); 283 | mIntent.putExtra(EXTRA_KEY, mKey); 284 | if (defaultValue instanceof Boolean) 285 | mIntent.putExtra(EXTRA_VALUE, mPrefs.getBoolean(mKey, (Boolean) defaultValue)); 286 | if (defaultValue instanceof String) 287 | mIntent.putExtra(EXTRA_VALUE, mPrefs.getString(mKey, (String) defaultValue)); 288 | if (defaultValue instanceof Integer) 289 | mIntent.putExtra(EXTRA_VALUE, mPrefs.getInt(mKey, (int) defaultValue)); 290 | } 291 | } 292 | } -------------------------------------------------------------------------------- /app/src/main/java/com/dvd/android/xposed/enableambientdisplay/XposedMod.java: -------------------------------------------------------------------------------- 1 | /* 2 | * The MIT License (MIT) 3 | * 4 | * Copyright (c) 2015 DVDAndroid 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in all 14 | * copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | * SOFTWARE. 23 | */ 24 | 25 | package com.dvd.android.xposed.enableambientdisplay; 26 | 27 | 28 | import android.os.Build; 29 | 30 | import com.dvd.android.xposed.enableambientdisplay.hook.AndroidHook; 31 | import com.dvd.android.xposed.enableambientdisplay.hook.SystemUiHook; 32 | import com.dvd.android.xposed.enableambientdisplay.utils.Utils; 33 | 34 | import de.robv.android.xposed.IXposedHookInitPackageResources; 35 | import de.robv.android.xposed.IXposedHookLoadPackage; 36 | import de.robv.android.xposed.IXposedHookZygoteInit; 37 | import de.robv.android.xposed.XC_MethodReplacement; 38 | import de.robv.android.xposed.XSharedPreferences; 39 | import de.robv.android.xposed.callbacks.XC_InitPackageResources; 40 | import de.robv.android.xposed.callbacks.XC_LoadPackage; 41 | 42 | import static android.content.res.XResources.setSystemWideReplacement; 43 | import static com.dvd.android.xposed.enableambientdisplay.utils.Utils.DOZE_BRIGHTNESS; 44 | import static com.dvd.android.xposed.enableambientdisplay.utils.Utils.PACKAGE_SYSTEMUI; 45 | import static com.dvd.android.xposed.enableambientdisplay.utils.Utils.THIS_PKG_NAME; 46 | import static com.dvd.android.xposed.enableambientdisplay.utils.Utils.logD; 47 | import static com.dvd.android.xposed.enableambientdisplay.utils.Utils.logW; 48 | import static de.robv.android.xposed.XposedHelpers.findAndHookMethod; 49 | 50 | public class XposedMod implements IXposedHookZygoteInit, IXposedHookLoadPackage, IXposedHookInitPackageResources { 51 | 52 | private static final String TAG = "XposedMod"; 53 | private static XSharedPreferences sPrefs; 54 | 55 | @Override 56 | public void initZygote(StartupParam startupParam) throws Throwable { 57 | if (Build.VERSION.SDK_INT > 23) { // for context.getSharedPreferences("", MODE_WORLD_READABLE) disabled from nougat. 58 | findAndHookMethod("android.app.ContextImpl", null, "checkMode", int.class, new XC_MethodReplacement() { 59 | @Override 60 | protected Object replaceHookedMethod(MethodHookParam methodHookParam) throws Throwable { 61 | return null; 62 | } 63 | }); 64 | } 65 | 66 | sPrefs = new XSharedPreferences(Utils.THIS_PKG_NAME, MainActivity.class.getSimpleName()); 67 | logD(TAG, sPrefs.toString()); 68 | Utils.debug = sPrefs.getBoolean("debug", false); 69 | 70 | if (!sPrefs.getBoolean("can_read_prefs", false)) { 71 | // With SELinux enforcing, it might happen that we don't have access 72 | // to the prefs file. Test this by reading a test key that should be 73 | // set to true. If it is false, we either can't read the file or the 74 | // user has never opened the preference screen before. 75 | // Credits to AndroidN-ify 76 | logW(TAG, "Can't read prefs file, default values will be applied in hooks!"); 77 | } 78 | 79 | setSystemWideReplacement("android", "string", "config_dozeComponent", "com.android.systemui/com.android.systemui.doze.DozeService"); 80 | setSystemWideReplacement("android", "bool", "config_dozeAfterScreenOff", true); 81 | setSystemWideReplacement("android", "bool", "config_powerDecoupleInteractiveModeFromDisplay", true); 82 | 83 | setSystemWideReplacement("android", "integer", DOZE_BRIGHTNESS, sPrefs.getInt(DOZE_BRIGHTNESS, 17)); 84 | } 85 | 86 | @Override 87 | public void handleLoadPackage(XC_LoadPackage.LoadPackageParam lpparam) throws Throwable { 88 | switch (lpparam.packageName) { 89 | case PACKAGE_SYSTEMUI: 90 | logD(TAG, "Hooking SystemUI"); 91 | SystemUiHook.hook(lpparam.classLoader, sPrefs); 92 | break; 93 | case Utils.PACKAGE_ANDROID: 94 | logD(TAG, "Hooking Android package"); 95 | AndroidHook.hook(lpparam.classLoader, sPrefs); 96 | break; 97 | case THIS_PKG_NAME: 98 | logD(TAG, "Hooking this module"); 99 | findAndHookMethod(THIS_PKG_NAME + ".MainActivity", lpparam.classLoader, "isEnabled", XC_MethodReplacement.returnConstant(true)); 100 | break; 101 | } 102 | } 103 | 104 | @Override 105 | public void handleInitPackageResources(XC_InitPackageResources.InitPackageResourcesParam resparam) throws Throwable { 106 | if (resparam.packageName.equals(PACKAGE_SYSTEMUI)) { 107 | logD(TAG, "Hooking SystemUI resources"); 108 | SystemUiHook.hookRes(resparam, sPrefs); 109 | } 110 | } 111 | } -------------------------------------------------------------------------------- /app/src/main/java/com/dvd/android/xposed/enableambientdisplay/hook/AndroidHook.java: -------------------------------------------------------------------------------- 1 | /* 2 | * The MIT License (MIT) 3 | * 4 | * Copyright (c) 2015 DVDAndroid 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in all 14 | * copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | * SOFTWARE. 23 | */ 24 | 25 | package com.dvd.android.xposed.enableambientdisplay.hook; 26 | 27 | import android.content.BroadcastReceiver; 28 | import android.content.Context; 29 | import android.content.Intent; 30 | import android.content.IntentFilter; 31 | import android.os.Build; 32 | import android.os.PowerManager; 33 | import android.provider.Settings; 34 | import android.view.KeyEvent; 35 | 36 | import com.dvd.android.xposed.enableambientdisplay.utils.Utils; 37 | 38 | import java.lang.reflect.InvocationTargetException; 39 | 40 | import de.robv.android.xposed.XC_MethodHook; 41 | import de.robv.android.xposed.XC_MethodReplacement; 42 | import de.robv.android.xposed.XSharedPreferences; 43 | 44 | import static android.view.KeyEvent.KEYCODE_HOME; 45 | import static android.view.KeyEvent.KEYCODE_POWER; 46 | import static android.view.KeyEvent.KEYCODE_WAKEUP; 47 | import static com.dvd.android.xposed.enableambientdisplay.utils.Utils.DOZE_WITH_POWER_KEY; 48 | import static com.dvd.android.xposed.enableambientdisplay.utils.Utils.logD; 49 | import static de.robv.android.xposed.XposedBridge.invokeOriginalMethod; 50 | import static de.robv.android.xposed.XposedHelpers.findAndHookMethod; 51 | import static de.robv.android.xposed.XposedHelpers.getObjectField; 52 | 53 | public class AndroidHook { 54 | 55 | private static final String TAG = "AndroidHook"; 56 | private static final String CLASS_PHONE_WINDOW_MANAGER = "com.android.internal.policy.impl.PhoneWindowManager"; 57 | private static final String CLASS_PHONE_WINDOW_MANAGER_23 = "com.android.server.policy.PhoneWindowManager"; 58 | private static boolean POWER_KEY_OVERWRITE = false; 59 | 60 | public static void hook(ClassLoader classLoader, final XSharedPreferences prefs) { 61 | String hookClass = Build.VERSION.SDK_INT >= 23 ? CLASS_PHONE_WINDOW_MANAGER_23 : CLASS_PHONE_WINDOW_MANAGER; 62 | 63 | findAndHookMethod(hookClass, classLoader, "interceptKeyBeforeQueueing", KeyEvent.class, int.class, new XC_MethodHook() { 64 | @Override 65 | protected void beforeHookedMethod(MethodHookParam param) throws Throwable { 66 | KeyEvent event = (KeyEvent) param.args[0]; 67 | Context mContext = (Context) getObjectField(param.thisObject, "mContext"); 68 | 69 | int keyCode = event.getKeyCode(); 70 | boolean power = Build.VERSION.SDK_INT < 23 && keyCode == KEYCODE_POWER; 71 | boolean interactive = ((int) param.args[1] & 0x20000000) != 0; 72 | 73 | logD(TAG, "Interactive: " + interactive); 74 | logD(TAG, "power: " + power); 75 | logD(TAG, "keyCode: " + keyCode); 76 | 77 | if (!interactive && (keyCode == KEYCODE_HOME || keyCode == KEYCODE_WAKEUP || power)) { 78 | sendAction(mContext, param, prefs); 79 | 80 | param.setResult(-1); 81 | } 82 | } 83 | }); 84 | 85 | if (Build.VERSION.SDK_INT < 23) return; 86 | 87 | findAndHookMethod(hookClass, classLoader, "wakeUpFromPowerKey", long.class, new XC_MethodReplacement() { 88 | @Override 89 | protected Object replaceHookedMethod(MethodHookParam param) throws Throwable { 90 | Context mContext = (Context) getObjectField(param.thisObject, "mContext"); 91 | registerReceiver(mContext); 92 | 93 | sendAction(mContext, param, prefs); 94 | return null; 95 | } 96 | }); 97 | } 98 | 99 | private static void registerReceiver(final Context context) { 100 | context.registerReceiver(new BroadcastReceiver() { 101 | @Override 102 | public void onReceive(Context context, Intent intent) { 103 | POWER_KEY_OVERWRITE = intent.getBooleanExtra(DOZE_WITH_POWER_KEY, false); 104 | } 105 | }, new IntentFilter(Utils.ACTION_PREFS_CHANGED)); 106 | } 107 | 108 | private static void initPrefs(XSharedPreferences prefs) { 109 | prefs.reload(); 110 | POWER_KEY_OVERWRITE = prefs.getBoolean(DOZE_WITH_POWER_KEY, false); 111 | } 112 | 113 | private static void sendAction(final Context context, final XC_MethodHook.MethodHookParam param, XSharedPreferences prefs) throws InvocationTargetException, IllegalAccessException { 114 | initPrefs(prefs); 115 | PowerManager mPowerManager = (PowerManager) context.getSystemService(Context.POWER_SERVICE); 116 | 117 | if (POWER_KEY_OVERWRITE) { 118 | int value = Settings.Secure.getInt(context.getContentResolver(), "doze_enabled", 1); 119 | if (mPowerManager.isPowerSaveMode() || value == 0) { 120 | invokeOriginalMethod(param.method, param.thisObject, param.args); 121 | Utils.logD(TAG, "Cannot doze."); 122 | } else { 123 | context.sendBroadcast(new Intent(Utils.ACTION_DOZE)); 124 | Utils.logD(TAG, "Device turned up. Dozing"); 125 | } 126 | } else { 127 | invokeOriginalMethod(param.method, param.thisObject, param.args); 128 | } 129 | } 130 | 131 | } 132 | -------------------------------------------------------------------------------- /app/src/main/java/com/dvd/android/xposed/enableambientdisplay/hook/SystemUiHook.java: -------------------------------------------------------------------------------- 1 | /* 2 | * The MIT License (MIT) 3 | * 4 | * Copyright (c) 2015 DVDAndroid 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in all 14 | * copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | * SOFTWARE. 23 | */ 24 | 25 | package com.dvd.android.xposed.enableambientdisplay.hook; 26 | 27 | import android.content.BroadcastReceiver; 28 | import android.content.Context; 29 | import android.content.Intent; 30 | import android.content.IntentFilter; 31 | import android.os.Build; 32 | import android.os.IBinder; 33 | import android.os.PowerManager; 34 | import android.os.SystemClock; 35 | import android.widget.ImageView; 36 | 37 | import com.dvd.android.xposed.enableambientdisplay.utils.Utils; 38 | 39 | import java.lang.reflect.Method; 40 | 41 | import de.robv.android.xposed.XC_MethodHook; 42 | import de.robv.android.xposed.XSharedPreferences; 43 | import de.robv.android.xposed.XposedHelpers; 44 | import de.robv.android.xposed.callbacks.XC_InitPackageResources; 45 | 46 | import static com.dvd.android.xposed.enableambientdisplay.utils.Utils.ACTION_HOT_REBOOT; 47 | import static com.dvd.android.xposed.enableambientdisplay.utils.Utils.ACTION_PREFS_CHANGED; 48 | import static com.dvd.android.xposed.enableambientdisplay.utils.Utils.ACTION_SLEEP; 49 | import static com.dvd.android.xposed.enableambientdisplay.utils.Utils.DOZE_ALPHA; 50 | import static com.dvd.android.xposed.enableambientdisplay.utils.Utils.DOZE_IN; 51 | import static com.dvd.android.xposed.enableambientdisplay.utils.Utils.DOZE_OUT; 52 | import static com.dvd.android.xposed.enableambientdisplay.utils.Utils.DOZE_PICK_UP; 53 | import static com.dvd.android.xposed.enableambientdisplay.utils.Utils.DOZE_PULSE_SCHEDULE; 54 | import static com.dvd.android.xposed.enableambientdisplay.utils.Utils.DOZE_RESETS; 55 | import static com.dvd.android.xposed.enableambientdisplay.utils.Utils.DOZE_SUPP; 56 | import static com.dvd.android.xposed.enableambientdisplay.utils.Utils.DOZE_VISIBILITY; 57 | import static com.dvd.android.xposed.enableambientdisplay.utils.Utils.EXTRA_KEY; 58 | import static com.dvd.android.xposed.enableambientdisplay.utils.Utils.EXTRA_VALUE; 59 | import static com.dvd.android.xposed.enableambientdisplay.utils.Utils.logD; 60 | import static com.dvd.android.xposed.enableambientdisplay.utils.Utils.logE; 61 | import static de.robv.android.xposed.XposedBridge.hookMethod; 62 | import static de.robv.android.xposed.XposedHelpers.callMethod; 63 | import static de.robv.android.xposed.XposedHelpers.callStaticMethod; 64 | import static de.robv.android.xposed.XposedHelpers.findAndHookMethod; 65 | import static de.robv.android.xposed.XposedHelpers.findClass; 66 | import static de.robv.android.xposed.XposedHelpers.findMethodExactIfExists; 67 | import static de.robv.android.xposed.XposedHelpers.setObjectField; 68 | 69 | public class SystemUiHook { 70 | 71 | private static final String TAG = "SystemUiHook"; 72 | private static final String CLASS_DOZE_PARAMETERS_PATH = "com.android.systemui.statusbar.phone.DozeParameters"; 73 | private static final String CLASS_KEYGUARD = "com.android.systemui.keyguard.KeyguardViewMediator"; 74 | private static final String CLASS_NOTIFICATION_VIEW = "com.android.systemui.statusbar.NotificationTemplateViewWrapper"; 75 | private static Context sContext; 76 | 77 | private static int VALUE_DOZE_IN = 1000; 78 | private static int VALUE_DOZE_OUT = 1000; 79 | private static int VALUE_DOZE_VISIBILITY = 3000; 80 | private static int VALUE_DOZE_RESETS = 1; 81 | private static int VALUE_DOZE_ALPHA = 222; 82 | private static String VALUE_DOZE_PULSE_SCHEDULE = "10s,30s,60s"; 83 | 84 | private static BroadcastReceiver sPrefsChange = new BroadcastReceiver() { 85 | @Override 86 | public void onReceive(Context context, Intent intent) { 87 | switch (intent.getAction()) { 88 | case ACTION_PREFS_CHANGED: 89 | logD(TAG, "Preference change broadcast signal received"); 90 | 91 | String key = intent.getStringExtra(EXTRA_KEY); 92 | if (key == null) break; 93 | 94 | logD(TAG, "Changed preference: " + key); 95 | 96 | switch (key) { 97 | case DOZE_IN: 98 | VALUE_DOZE_IN = intent.getIntExtra(EXTRA_VALUE, 1000); 99 | break; 100 | case DOZE_OUT: 101 | VALUE_DOZE_OUT = intent.getIntExtra(EXTRA_VALUE, 1000); 102 | break; 103 | case DOZE_VISIBILITY: 104 | VALUE_DOZE_VISIBILITY = intent.getIntExtra(EXTRA_VALUE, 3000); 105 | break; 106 | case DOZE_RESETS: 107 | VALUE_DOZE_RESETS = intent.getIntExtra(EXTRA_VALUE, 1); 108 | break; 109 | case DOZE_ALPHA: 110 | VALUE_DOZE_ALPHA = intent.getIntExtra(EXTRA_VALUE, 222); 111 | case DOZE_PULSE_SCHEDULE: 112 | VALUE_DOZE_PULSE_SCHEDULE = intent.getStringExtra(EXTRA_VALUE); 113 | break; 114 | } 115 | break; 116 | case ACTION_SLEEP: 117 | logD(TAG, "Sleep broadcast signal received"); 118 | try { 119 | PowerManager powerManager = (PowerManager) sContext.getSystemService(Context.POWER_SERVICE); 120 | 121 | callMethod(powerManager, "goToSleep", SystemClock.uptimeMillis()); 122 | } catch (Throwable t) { 123 | logE(TAG, t.getMessage(), t); 124 | } 125 | break; 126 | case ACTION_HOT_REBOOT: 127 | logD(TAG, "Hot reboot broadcast signal received"); 128 | //from gravitybox 129 | try { 130 | Class classSm = findClass("android.os.ServiceManager", null); 131 | Class classIpm = findClass("android.os.IPowerManager.Stub", null); 132 | IBinder b = (IBinder) callStaticMethod(classSm, "getService", Context.POWER_SERVICE); 133 | Object ipm = callStaticMethod(classIpm, "asInterface", b); 134 | callMethod(ipm, "crash", "Hot reboot"); 135 | } catch (Throwable t) { 136 | try { 137 | SystemProp.set("ctl.restart", "surfaceflinger"); 138 | SystemProp.set("ctl.restart", "zygote"); 139 | } catch (Throwable t2) { 140 | logE(TAG, "Hot reboot error: ", t); 141 | logE(TAG, "Hot reboot error: ", t2); 142 | } 143 | } 144 | } 145 | } 146 | }; 147 | 148 | public static void hook(final ClassLoader classLoader, XSharedPreferences prefs) { 149 | try { 150 | Class keyguardClass = XposedHelpers.findClass(CLASS_KEYGUARD, classLoader); 151 | 152 | String setupMethodName = Build.VERSION.SDK_INT >= 22 ? "setupLocked" : "setup"; 153 | findAndHookMethod(keyguardClass, setupMethodName, new XC_MethodHook() { 154 | @Override 155 | protected void afterHookedMethod(final MethodHookParam param) throws Throwable { 156 | sContext = (Context) XposedHelpers.getObjectField(param.thisObject, "mContext"); 157 | 158 | registerReceiver(sContext); 159 | } 160 | }); 161 | 162 | final Class hookClass = findClass(CLASS_DOZE_PARAMETERS_PATH, classLoader); 163 | 164 | initPrefs(prefs); 165 | 166 | Method pulseInApi21 = findMethodExactIfExists(hookClass, "getPulseInDuration"); 167 | Method pulseInAOSP = findMethodExactIfExists(hookClass, "getPulseInDuration", boolean.class); 168 | Method pulseInCM = findMethodExactIfExists(hookClass, "getPulseInDuration", int.class); 169 | 170 | if (pulseInApi21 != null) 171 | hookPulseInMethod(pulseInApi21); 172 | if (pulseInAOSP != null) 173 | hookPulseInMethod(pulseInAOSP); 174 | if (pulseInCM != null) 175 | hookPulseInMethod(pulseInCM); 176 | 177 | findAndHookMethod(hookClass, "getPulseVisibleDuration", new XC_MethodHook() { 178 | @Override 179 | protected void beforeHookedMethod(MethodHookParam param) throws Throwable { 180 | param.setResult(VALUE_DOZE_VISIBILITY); 181 | } 182 | }); 183 | findAndHookMethod(hookClass, "getPulseOutDuration", new XC_MethodHook() { 184 | @Override 185 | protected void beforeHookedMethod(MethodHookParam param) throws Throwable { 186 | param.setResult(VALUE_DOZE_OUT); 187 | } 188 | }); 189 | 190 | if (Build.VERSION.SDK_INT < 25) { 191 | findAndHookMethod(hookClass, "getPulseScheduleResets", new XC_MethodHook() { 192 | @Override 193 | protected void beforeHookedMethod(MethodHookParam param) throws Throwable { 194 | param.setResult(VALUE_DOZE_RESETS); 195 | } 196 | }); 197 | 198 | final Class pulseSchedule = findClass(CLASS_DOZE_PARAMETERS_PATH + "$PulseSchedule", classLoader); 199 | findAndHookMethod(hookClass, "getPulseSchedule", new XC_MethodHook() { 200 | @Override 201 | protected void beforeHookedMethod(MethodHookParam param) throws Throwable { 202 | super.beforeHookedMethod(param); 203 | 204 | param.setResult(callMethod(pulseSchedule.newInstance(), "parse", VALUE_DOZE_PULSE_SCHEDULE)); 205 | } 206 | }); 207 | } 208 | 209 | if (Build.VERSION.SDK_INT == 22 || Build.VERSION.SDK_INT == 23) { 210 | Class notificationView = findClass(CLASS_NOTIFICATION_VIEW, classLoader); 211 | findAndHookMethod(notificationView, "fadeIconAlpha", ImageView.class, boolean.class, long.class, new XC_MethodHook() { 212 | @Override 213 | protected void beforeHookedMethod(MethodHookParam param) throws Throwable { 214 | setObjectField(param.thisObject, "mIconDarkAlpha", VALUE_DOZE_ALPHA); 215 | } 216 | }); 217 | findAndHookMethod(notificationView, "updateIconAlpha", ImageView.class, boolean.class, new XC_MethodHook() { 218 | @Override 219 | protected void beforeHookedMethod(MethodHookParam param) throws Throwable { 220 | setObjectField(param.thisObject, "mIconDarkAlpha", VALUE_DOZE_ALPHA); 221 | } 222 | }); 223 | } 224 | } catch (Throwable t) { 225 | logE(TAG, t.getMessage(), t); 226 | } 227 | } 228 | 229 | private static void hookPulseInMethod(Method method) { 230 | hookMethod(method, new XC_MethodHook() { 231 | @Override 232 | protected void beforeHookedMethod(MethodHookParam param) throws Throwable { 233 | param.setResult(VALUE_DOZE_IN); 234 | } 235 | }); 236 | } 237 | 238 | public static void hookRes(XC_InitPackageResources.InitPackageResourcesParam resParam, XSharedPreferences prefs) { 239 | resParam.res.setReplacement(Utils.PACKAGE_SYSTEMUI, "bool", DOZE_SUPP, true); 240 | 241 | if (Build.VERSION.SDK_INT < 25) 242 | resParam.res.setReplacement(Utils.PACKAGE_SYSTEMUI, "bool", DOZE_PICK_UP, true); 243 | 244 | if (Build.VERSION.SDK_INT < 22) { 245 | initPrefs(prefs); 246 | resParam.res.setReplacement(Utils.PACKAGE_SYSTEMUI, "integer", DOZE_ALPHA, VALUE_DOZE_ALPHA); 247 | } 248 | } 249 | 250 | private static void initPrefs(XSharedPreferences prefs) { 251 | prefs.reload(); 252 | VALUE_DOZE_IN = prefs.getInt(DOZE_IN, 1000); 253 | VALUE_DOZE_OUT = prefs.getInt(DOZE_OUT, 1000); 254 | VALUE_DOZE_VISIBILITY = prefs.getInt(DOZE_VISIBILITY, 3000); 255 | VALUE_DOZE_RESETS = prefs.getInt(DOZE_RESETS, 1); 256 | VALUE_DOZE_ALPHA = prefs.getInt(DOZE_ALPHA, 222); 257 | VALUE_DOZE_PULSE_SCHEDULE = prefs.getString(DOZE_PULSE_SCHEDULE, "10s,30s,60s"); 258 | } 259 | 260 | private static void registerReceiver(final Context context) { 261 | IntentFilter intentFilter = new IntentFilter(); 262 | intentFilter.addAction(ACTION_SLEEP); 263 | intentFilter.addAction(ACTION_PREFS_CHANGED); 264 | intentFilter.addAction(ACTION_HOT_REBOOT); 265 | context.registerReceiver(sPrefsChange, intentFilter); 266 | } 267 | 268 | //from gravitybox 269 | static class SystemProp { 270 | // Set the value for the given key 271 | public static void set(String key, String val) { 272 | try { 273 | Class classSystemProperties = findClass("android.os.SystemProperties", null); 274 | callStaticMethod(classSystemProperties, "set", key, val); 275 | } catch (Throwable t) { 276 | logE(TAG, "SystemProp.set failed: ", t); 277 | } 278 | } 279 | } 280 | 281 | } 282 | -------------------------------------------------------------------------------- /app/src/main/java/com/dvd/android/xposed/enableambientdisplay/services/BootReceiver.java: -------------------------------------------------------------------------------- 1 | /* 2 | * The MIT License (MIT) 3 | * 4 | * Copyright (c) 2015 DVDAndroid 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in all 14 | * copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | * SOFTWARE. 23 | */ 24 | 25 | package com.dvd.android.xposed.enableambientdisplay.services; 26 | 27 | import android.annotation.SuppressLint; 28 | import android.content.BroadcastReceiver; 29 | import android.content.Context; 30 | import android.content.Intent; 31 | import android.content.SharedPreferences; 32 | 33 | import com.dvd.android.xposed.enableambientdisplay.MainActivity; 34 | 35 | import static android.content.Context.MODE_WORLD_READABLE; 36 | import static com.dvd.android.xposed.enableambientdisplay.MainActivity.isEnabled; 37 | 38 | public class BootReceiver extends BroadcastReceiver { 39 | 40 | @Override 41 | public void onReceive(final Context context, Intent intent) { 42 | // noinspection ConstantConditions 43 | if (isEnabled() && isSensorEnabled(context)) { 44 | context.startService(new Intent(context, SensorService.class)); 45 | } 46 | } 47 | 48 | @SuppressLint("WorldReadableFiles") 49 | private boolean isSensorEnabled(Context context) { 50 | SharedPreferences prefs = context.getSharedPreferences(MainActivity.class.getSimpleName(), MODE_WORLD_READABLE); 51 | return prefs.getBoolean("doze_proximity", false); 52 | } 53 | 54 | } -------------------------------------------------------------------------------- /app/src/main/java/com/dvd/android/xposed/enableambientdisplay/services/SensorService.java: -------------------------------------------------------------------------------- 1 | /* 2 | * The MIT License (MIT) 3 | * 4 | * Copyright (c) 2015 DVDAndroid 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in all 14 | * copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | * SOFTWARE. 23 | */ 24 | 25 | package com.dvd.android.xposed.enableambientdisplay.services; 26 | 27 | import android.app.Service; 28 | import android.content.BroadcastReceiver; 29 | import android.content.Context; 30 | import android.content.Intent; 31 | import android.content.IntentFilter; 32 | import android.content.SharedPreferences; 33 | import android.hardware.Sensor; 34 | import android.hardware.SensorEvent; 35 | import android.hardware.SensorEventListener; 36 | import android.hardware.SensorManager; 37 | import android.os.IBinder; 38 | import android.os.PowerManager; 39 | import android.preference.PreferenceManager; 40 | 41 | import static com.dvd.android.xposed.enableambientdisplay.utils.Utils.ACTION_DOZE; 42 | import static com.dvd.android.xposed.enableambientdisplay.utils.Utils.DOZE_PROXIMITY; 43 | 44 | public class SensorService extends Service 45 | implements SharedPreferences.OnSharedPreferenceChangeListener { 46 | 47 | private static final int DELAY_BETWEEN_DOZES_IN_MS = 2500; 48 | private static final String TAG = "SensorService"; 49 | private static boolean isRunning; 50 | private ProximitySensor mSensor; 51 | private PowerManager mPowerManager; 52 | 53 | private long mLastDoze; 54 | private SharedPreferences mPrefs; 55 | private boolean mDozeProximity; 56 | private boolean displayTurnedOff = false; 57 | private BroadcastReceiver mScreenStateReceiver = new BroadcastReceiver() { 58 | @Override 59 | public void onReceive(Context context, Intent intent) { 60 | if (intent.getAction().equals(Intent.ACTION_SCREEN_OFF)) { 61 | onDisplayOff(); 62 | } else if (intent.getAction().equals(Intent.ACTION_SCREEN_ON)) { 63 | onDisplayOn(); 64 | } 65 | } 66 | }; 67 | private Context mContext; 68 | 69 | public static boolean isRunning() { 70 | return isRunning; 71 | } 72 | 73 | @Override 74 | public void onCreate() { 75 | mContext = this; 76 | mPowerManager = (PowerManager) getSystemService(Context.POWER_SERVICE); 77 | mSensor = new ProximitySensor(mContext); 78 | mPrefs = PreferenceManager.getDefaultSharedPreferences(mContext); 79 | mPrefs.registerOnSharedPreferenceChangeListener(this); 80 | mDozeProximity = mPrefs.getBoolean(DOZE_PROXIMITY, true); 81 | 82 | if (!isInteractive() && mDozeProximity) { 83 | mSensor.enable(); 84 | } 85 | 86 | isRunning = true; 87 | } 88 | 89 | @Override 90 | public int onStartCommand(Intent intent, int flags, int startId) { 91 | IntentFilter screenStateFilter = new IntentFilter(Intent.ACTION_SCREEN_ON); 92 | screenStateFilter.addAction(Intent.ACTION_SCREEN_OFF); 93 | mContext.registerReceiver(mScreenStateReceiver, screenStateFilter); 94 | 95 | return START_STICKY; 96 | } 97 | 98 | @Override 99 | public void onDestroy() { 100 | isRunning = false; 101 | mContext.unregisterReceiver(mScreenStateReceiver); 102 | mPrefs.unregisterOnSharedPreferenceChangeListener(this); 103 | 104 | super.onDestroy(); 105 | } 106 | 107 | @Override 108 | public IBinder onBind(Intent intent) { 109 | return null; 110 | } 111 | 112 | private void launchDozePulse() { 113 | mContext.sendBroadcast(new Intent(ACTION_DOZE)); 114 | mLastDoze = System.currentTimeMillis(); 115 | } 116 | 117 | private boolean isInteractive() { 118 | return mPowerManager.isInteractive(); 119 | } 120 | 121 | private void onDisplayOn() { 122 | mSensor.disable(); 123 | } 124 | 125 | private void onDisplayOff() { 126 | if (mDozeProximity) { 127 | mSensor.enable(); 128 | } 129 | displayTurnedOff = true; 130 | } 131 | 132 | @Override 133 | public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) { 134 | 135 | if (key.equals(DOZE_PROXIMITY)) 136 | mDozeProximity = sharedPreferences.getBoolean(DOZE_PROXIMITY, true); 137 | 138 | } 139 | 140 | class ProximitySensor implements SensorEventListener { 141 | private SensorManager mSensorManager; 142 | private Sensor mSensor; 143 | 144 | private boolean mIsNear = false; 145 | 146 | public ProximitySensor(Context context) { 147 | mSensorManager = (SensorManager) context.getSystemService(Context.SENSOR_SERVICE); 148 | mSensor = mSensorManager.getDefaultSensor(Sensor.TYPE_PROXIMITY); 149 | } 150 | 151 | @Override 152 | public void onSensorChanged(SensorEvent event) { 153 | long now = System.currentTimeMillis(); 154 | mIsNear = event.values[0] < mSensor.getMaximumRange(); 155 | 156 | if (!mIsNear && (now - mLastDoze > DELAY_BETWEEN_DOZES_IN_MS) && !displayTurnedOff) { 157 | launchDozePulse(); 158 | } 159 | 160 | displayTurnedOff = false; 161 | } 162 | 163 | @Override 164 | public void onAccuracyChanged(Sensor sensor, int accuracy) { 165 | /* Empty */ 166 | } 167 | 168 | public void enable() { 169 | mSensorManager.registerListener(this, mSensor, SensorManager.SENSOR_DELAY_NORMAL); 170 | } 171 | 172 | public void disable() { 173 | mSensorManager.unregisterListener(this, mSensor); 174 | } 175 | } 176 | } 177 | -------------------------------------------------------------------------------- /app/src/main/java/com/dvd/android/xposed/enableambientdisplay/utils/RegexValidatorPreference.java: -------------------------------------------------------------------------------- 1 | package com.dvd.android.xposed.enableambientdisplay.utils; 2 | 3 | import android.app.AlertDialog; 4 | import android.app.Dialog; 5 | import android.content.Context; 6 | import android.os.Bundle; 7 | import android.preference.EditTextPreference; 8 | import android.text.Editable; 9 | import android.text.TextWatcher; 10 | import android.util.AttributeSet; 11 | 12 | public class RegexValidatorPreference extends EditTextPreference implements TextWatcher { 13 | 14 | public RegexValidatorPreference(Context context) { 15 | this(context, null); 16 | } 17 | 18 | public RegexValidatorPreference(Context context, AttributeSet attrs) { 19 | super(context, attrs); 20 | 21 | getEditText().setSingleLine(true); 22 | getEditText().setMaxLines(1); 23 | getEditText().setLines(1); 24 | } 25 | 26 | @Override 27 | protected void showDialog(Bundle state) { 28 | super.showDialog(state); 29 | 30 | getEditText().removeTextChangedListener(this); 31 | getEditText().addTextChangedListener(this); 32 | onEditTextChanged(); 33 | } 34 | 35 | @Override 36 | public void afterTextChanged(Editable s) { 37 | } 38 | 39 | @Override 40 | public void beforeTextChanged(CharSequence s, int start, int count, int after) { 41 | } 42 | 43 | @Override 44 | public void onTextChanged(CharSequence s, int start, int before, int count) { 45 | onEditTextChanged(); 46 | } 47 | 48 | private void onEditTextChanged() { 49 | try { 50 | boolean matches = getEditText().getText().toString().matches("^\\d+s(,\\d+s)*$"); 51 | 52 | Dialog dlg = getDialog(); 53 | if (dlg instanceof AlertDialog) { 54 | ((AlertDialog) dlg).getButton(AlertDialog.BUTTON_POSITIVE).setEnabled(matches); 55 | } 56 | } catch (NullPointerException ignore) { 57 | } 58 | } 59 | 60 | 61 | @Override 62 | protected boolean persistString(String value) { 63 | setSummary(value); 64 | return super.persistString(value); 65 | } 66 | 67 | } -------------------------------------------------------------------------------- /app/src/main/java/com/dvd/android/xposed/enableambientdisplay/utils/SeekBarDialogPreference.java: -------------------------------------------------------------------------------- 1 | /* 2 | * The MIT License (MIT) 3 | * 4 | * Copyright (c) 2015 DVDAndroid 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in all 14 | * copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | * SOFTWARE. 23 | */ 24 | 25 | package com.dvd.android.xposed.enableambientdisplay.utils; 26 | 27 | import android.app.AlertDialog; 28 | import android.content.Context; 29 | import android.content.DialogInterface; 30 | import android.content.res.TypedArray; 31 | import android.os.Parcel; 32 | import android.os.Parcelable; 33 | import android.preference.DialogPreference; 34 | import android.util.AttributeSet; 35 | import android.view.View; 36 | import android.widget.SeekBar; 37 | import android.widget.SeekBar.OnSeekBarChangeListener; 38 | import android.widget.TextView; 39 | 40 | import com.dvd.android.xposed.enableambientdisplay.R; 41 | 42 | /** 43 | * A {@link DialogPreference} that provides a user with the means to select an 44 | * integer from a {@link SeekBar}, and persist it. 45 | * 46 | * @author lukehorvat 47 | * 48 | */ 49 | public class SeekBarDialogPreference extends DialogPreference { 50 | private static final int DEFAULT_MIN_PROGRESS = 0; 51 | private static final int DEFAULT_MAX_PROGRESS = 100; 52 | private static final int DEFAULT_PROGRESS = 0; 53 | 54 | private int mMinProgress; 55 | private int mMaxProgress; 56 | private int mProgress; 57 | private int mDefaultProgress; 58 | private CharSequence mProgressTextSuffix; 59 | private TextView mProgressText; 60 | private SeekBar mSeekBar; 61 | 62 | public SeekBarDialogPreference(Context context) { 63 | this(context, null); 64 | } 65 | 66 | public SeekBarDialogPreference(Context context, AttributeSet attrs) { 67 | super(context, attrs); 68 | 69 | // get attributes specified in XML 70 | TypedArray a = context.getTheme().obtainStyledAttributes(attrs, 71 | R.styleable.SeekBarDialogPreference, 0, 0); 72 | try { 73 | mDefaultProgress = a.getInteger( 74 | R.styleable.SeekBarDialogPreference_android_defaultValue, 75 | -1); 76 | 77 | setMinProgress(a.getInteger(R.styleable.SeekBarDialogPreference_min, 78 | DEFAULT_MIN_PROGRESS)); 79 | setMaxProgress(a.getInteger( 80 | R.styleable.SeekBarDialogPreference_android_max, 81 | DEFAULT_MAX_PROGRESS)); 82 | setProgressTextSuffix(a.getString( 83 | R.styleable.SeekBarDialogPreference_progressTextSuffix)); 84 | } finally { 85 | a.recycle(); 86 | } 87 | 88 | // set layout 89 | setDialogLayoutResource(R.layout.preference_seek_bar_dialog); 90 | setPositiveButtonText(android.R.string.ok); 91 | setNegativeButtonText(android.R.string.cancel); 92 | setDialogIcon(null); 93 | } 94 | 95 | @Override 96 | protected void onPrepareDialogBuilder(AlertDialog.Builder builder) { 97 | super.onPrepareDialogBuilder(builder); 98 | builder.setNeutralButton(R.string.def, 99 | new DialogInterface.OnClickListener() { 100 | @Override 101 | public void onClick(DialogInterface dialog, int which) { 102 | setProgress(mDefaultProgress); 103 | } 104 | }); 105 | } 106 | 107 | @Override 108 | protected void onSetInitialValue(boolean restore, Object defaultValue) { 109 | setProgress(restore ? getPersistedInt(DEFAULT_PROGRESS) 110 | : (Integer) defaultValue); 111 | } 112 | 113 | @Override 114 | protected Object onGetDefaultValue(TypedArray a, int index) { 115 | return a.getInt(index, DEFAULT_PROGRESS); 116 | } 117 | 118 | @Override 119 | protected void onBindDialogView(View view) { 120 | super.onBindDialogView(view); 121 | 122 | TextView dialogMessageText = (TextView) view 123 | .findViewById(R.id.text_dialog_message); 124 | dialogMessageText.setText(getDialogMessage()); 125 | 126 | mProgressText = (TextView) view.findViewById(R.id.text_progress); 127 | 128 | mSeekBar = (SeekBar) view.findViewById(R.id.seek_bar); 129 | mSeekBar.setOnSeekBarChangeListener(new OnSeekBarChangeListener() { 130 | @Override 131 | public void onStopTrackingTouch(SeekBar seekBar) { 132 | } 133 | 134 | @Override 135 | public void onStartTrackingTouch(SeekBar seekBar) { 136 | } 137 | 138 | @Override 139 | public void onProgressChanged(SeekBar seekBar, int progress, 140 | boolean fromUser) { 141 | // update text that displays the current SeekBar progress value 142 | // note: this does not persist the progress value. that is only 143 | // ever done in setProgress() 144 | String progressStr = String.valueOf(progress + mMinProgress); 145 | mProgressText.setText(mProgressTextSuffix == null ? progressStr 146 | : progressStr.concat(mProgressTextSuffix.toString())); 147 | } 148 | }); 149 | mSeekBar.setMax(mMaxProgress - mMinProgress); 150 | mSeekBar.setProgress(mProgress - mMinProgress); 151 | } 152 | 153 | public int getMinProgress() { 154 | return mMinProgress; 155 | } 156 | 157 | public void setMinProgress(int minProgress) { 158 | mMinProgress = minProgress; 159 | setProgress(Math.max(mProgress, mMinProgress)); 160 | } 161 | 162 | public int getMaxProgress() { 163 | return mMaxProgress; 164 | } 165 | 166 | public void setMaxProgress(int maxProgress) { 167 | mMaxProgress = maxProgress; 168 | setProgress(Math.min(mProgress, mMaxProgress)); 169 | } 170 | 171 | public int getProgress() { 172 | return mProgress; 173 | } 174 | 175 | public void setProgress(int progress) { 176 | progress = Math.max(Math.min(progress, mMaxProgress), mMinProgress); 177 | 178 | if (progress != mProgress) { 179 | mProgress = progress; 180 | persistInt(progress); 181 | notifyChanged(); 182 | } 183 | 184 | setSummary(mProgressTextSuffix == null ? Integer.toString(progress) 185 | : Integer.toString(progress) 186 | .concat(mProgressTextSuffix.toString())); 187 | } 188 | 189 | public CharSequence getProgressTextSuffix() { 190 | return mProgressTextSuffix; 191 | } 192 | 193 | public void setProgressTextSuffix(CharSequence progressTextSuffix) { 194 | mProgressTextSuffix = progressTextSuffix; 195 | } 196 | 197 | @Override 198 | protected void onDialogClosed(boolean positiveResult) { 199 | super.onDialogClosed(positiveResult); 200 | 201 | // when the user selects "OK", persist the new value 202 | if (positiveResult) { 203 | int seekBarProgress = mSeekBar.getProgress() + mMinProgress; 204 | if (callChangeListener(seekBarProgress)) { 205 | setProgress(seekBarProgress); 206 | } 207 | } 208 | } 209 | 210 | @Override 211 | protected Parcelable onSaveInstanceState() { 212 | // save the instance state so that it will survive screen orientation 213 | // changes and other events that may temporarily destroy it 214 | final Parcelable superState = super.onSaveInstanceState(); 215 | 216 | // set the state's value with the class member that holds current 217 | // setting value 218 | final SavedState myState = new SavedState(superState); 219 | myState.minProgress = getMinProgress(); 220 | myState.maxProgress = getMaxProgress(); 221 | myState.progress = getProgress(); 222 | 223 | return myState; 224 | } 225 | 226 | @Override 227 | protected void onRestoreInstanceState(Parcelable state) { 228 | // check whether we saved the state in onSaveInstanceState() 229 | if (state == null || !state.getClass().equals(SavedState.class)) { 230 | // didn't save the state, so call superclass 231 | super.onRestoreInstanceState(state); 232 | return; 233 | } 234 | 235 | // restore the state 236 | SavedState myState = (SavedState) state; 237 | setMinProgress(myState.minProgress); 238 | setMaxProgress(myState.maxProgress); 239 | setProgress(myState.progress); 240 | 241 | super.onRestoreInstanceState(myState.getSuperState()); 242 | } 243 | 244 | private static class SavedState extends BaseSavedState { 245 | @SuppressWarnings("unused") 246 | public static final Parcelable.Creator CREATOR = new Parcelable.Creator() { 247 | @Override 248 | public SavedState createFromParcel(Parcel in) { 249 | return new SavedState(in); 250 | } 251 | 252 | @Override 253 | public SavedState[] newArray(int size) { 254 | return new SavedState[size]; 255 | } 256 | }; 257 | int minProgress; 258 | int maxProgress; 259 | int progress; 260 | 261 | public SavedState(Parcelable superState) { 262 | super(superState); 263 | } 264 | 265 | public SavedState(Parcel source) { 266 | super(source); 267 | 268 | minProgress = source.readInt(); 269 | maxProgress = source.readInt(); 270 | progress = source.readInt(); 271 | } 272 | 273 | @Override 274 | public void writeToParcel(Parcel dest, int flags) { 275 | super.writeToParcel(dest, flags); 276 | 277 | dest.writeInt(minProgress); 278 | dest.writeInt(maxProgress); 279 | dest.writeInt(progress); 280 | } 281 | } 282 | } -------------------------------------------------------------------------------- /app/src/main/java/com/dvd/android/xposed/enableambientdisplay/utils/Utils.java: -------------------------------------------------------------------------------- 1 | /* 2 | * The MIT License (MIT) 3 | * 4 | * Copyright (c) 2015 DVDAndroid 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in all 14 | * copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | * SOFTWARE. 23 | */ 24 | 25 | package com.dvd.android.xposed.enableambientdisplay.utils; 26 | 27 | import static de.robv.android.xposed.XposedBridge.log; 28 | 29 | public class Utils { 30 | 31 | public static final String ACTION_DOZE = "com.android.systemui.doze.pulse"; 32 | public static final String ACTION_SLEEP = "dvd.ACTION_SLEEP"; 33 | public static final String ACTION_PREFS_CHANGED = "dvd.ACTION_PREFS_CHANGED"; 34 | public static final String ACTION_HOT_REBOOT = "dvd.ACTION_HOT_REBOOT"; 35 | public static final String EXTRA_KEY = "dvd.EXTRA_KEY"; 36 | public static final String EXTRA_VALUE = "dvd.EXTRA_VALUE"; 37 | 38 | public static final String PACKAGE_SYSTEMUI = "com.android.systemui"; 39 | public static final String PACKAGE_ANDROID = "android"; 40 | public static final String THIS_PKG_NAME = "com.dvd.android.xposed.enableambientdisplay"; 41 | 42 | public static final String DOZE_SUPP = "doze_display_state_supported"; 43 | public static final String DOZE_PICK_UP = "doze_pulse_on_pick_up"; 44 | public static final String DOZE_IN = "doze_pulse_duration_in"; 45 | public static final String DOZE_OUT = "doze_pulse_duration_out"; 46 | public static final String DOZE_VISIBILITY = "doze_pulse_duration_visible"; 47 | public static final String DOZE_ALPHA = "doze_small_icon_alpha"; 48 | public static final String DOZE_RESETS = "doze_pulse_schedule_resets"; 49 | public static final String DOZE_PULSE_SCHEDULE = "doze_pulse_schedule"; 50 | public static final String DOZE_PROXIMITY = "doze_proximity"; 51 | public static final String DOZE_BRIGHTNESS = "config_screenBrightnessDoze"; 52 | public static final String DOZE_WITH_POWER_KEY = "doze_power_key"; 53 | 54 | private static final String LOG_FORMAT = "[Enable Ambient Display] %1$s %2$s: %3$s"; 55 | public static boolean debug = false; 56 | 57 | public static void logD(String tag, String msg) { 58 | if (debug) log(String.format(LOG_FORMAT, "[DEBUG]", tag, msg)); 59 | } 60 | 61 | public static void logE(String tag, String msg, Throwable t) { 62 | log(String.format(LOG_FORMAT, "[ERROR]", tag, msg)); 63 | if (t != null) 64 | log(t); 65 | } 66 | 67 | public static void logW(String tag, String msg) { 68 | log(String.format(LOG_FORMAT, "[WARNING]", tag, msg)); 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /app/src/main/res/layout/activity_settings.xml: -------------------------------------------------------------------------------- 1 | 2 | 25 | 26 | 31 | 32 | 36 | 37 | -------------------------------------------------------------------------------- /app/src/main/res/layout/long_title_preference.xml: -------------------------------------------------------------------------------- 1 | 2 | 16 | 17 | 20 | 31 | 32 | 38 | 39 | 45 | 46 | 55 | 56 | 57 | 58 | 59 | 67 | 68 | 69 | -------------------------------------------------------------------------------- /app/src/main/res/layout/preference_seek_bar_dialog.xml: -------------------------------------------------------------------------------- 1 | 2 | 25 | 26 | 30 | 31 | 38 | 39 | 40 | 46 | 47 | 48 | 54 | 55 | -------------------------------------------------------------------------------- /app/src/main/res/menu/main.xml: -------------------------------------------------------------------------------- 1 | 2 | 25 | 26 | 28 | 29 | 32 | 33 | 36 | 37 | 40 | 41 | 44 | 45 | -------------------------------------------------------------------------------- /app/src/main/res/mipmap-hdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DVDAndroid/Xposed-EnableAmbientDisplay/f9e16f17e7a4f7aa002d50a971ec4121ab116363/app/src/main/res/mipmap-hdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-mdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DVDAndroid/Xposed-EnableAmbientDisplay/f9e16f17e7a4f7aa002d50a971ec4121ab116363/app/src/main/res/mipmap-mdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DVDAndroid/Xposed-EnableAmbientDisplay/f9e16f17e7a4f7aa002d50a971ec4121ab116363/app/src/main/res/mipmap-xhdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DVDAndroid/Xposed-EnableAmbientDisplay/f9e16f17e7a4f7aa002d50a971ec4121ab116363/app/src/main/res/mipmap-xxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xxxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DVDAndroid/Xposed-EnableAmbientDisplay/f9e16f17e7a4f7aa002d50a971ec4121ab116363/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/values-it/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | 25 | 26 | 27 | Abilita Ambient Display - Xposed 28 | Semplice modulo Xposed che aggiunge Ambient Display 29 | 30 | Luminosità dello schermo usata per oscurare lo schermo 31 | Quanto tempo serve per accendersi? 32 | Quanto tempo serve per spegnersi? 33 | Una volta acceso, quanto tempo serve rimanere acceso? 34 | Opacità da applicare alle piccole icone durante il dozing 35 | Un valore più elevato di luminosità determina un maggiore utilizzo di batteria 36 | Un valore inferiore di opacità oscura l\'icona 37 | Riavvio veloce 38 | Riavvio 39 | Impostazioni del tempo 40 | Riavvio richiesto 41 | Numero massimo di volte che lo schermo si accenderà 42 | Personalizzazioni 43 | Note 44 | Fai un test 45 | Modulo non abilitato 46 | Attivare doze con sensore di prossimità 47 | Doze con sensore di prossimità è disabilitato 48 | Doze con sensore di prossimità è abilitato 49 | Avvia servizio 50 | Servizio partito 51 | Info 52 | Default 53 | Questo modulo funziona con Google stock/AOSP-basate rom.\nSe hai un telefono Samsung o LG, prova questo modulo; se funziona, ok; se non funziona non posso fare niente 54 | Modulo creato da dvdandroid\n\nCodice sorgente disponibile su GitHub 55 | Servizio stoppato 56 | Stop servizio 57 | Il dispositivo si accenderà normalmente 58 | Invece di accendere il dispositivo, verrà visualizzato Ambient Display 59 | Doze al click del tasto di spegnimento 60 | Quando pulsare dopo l\'arrivo di una notifica 61 | Extra 62 | Attenzione! 63 | Il dispositivo non si può accendere più se qualcosa va storto. Per evitare ciò, impostare un altro metodo che faccia risvegliare il dispositivo (risveglio con i tasti del volume per esempio).\n\nSe non si effettuano precauzioni e qualcosa va storto, occorre disabilitare o disinstallare xposed. 64 | 65 | -------------------------------------------------------------------------------- /app/src/main/res/values/attrs.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /app/src/main/res/values/strings.xml: -------------------------------------------------------------------------------- 1 | 24 | 25 | 26 | Enable Ambient Display - Xposed 27 | Easy Xposed module for Lollipop which add Ambient Display 28 | 29 | How long does it take to fade in? 30 | Once faded in, how long does it stay visible? 31 | How long does it take to fade out? 32 | A higher value of brightness causes a higher use of battery 33 | A lower value of opacity obscures the icon 34 | Alpha to apply to small icons when dozing 35 | Screen brightness used to dim the screen while dozing. 36 | Maximum number of times the notification pulse schedule can be reset 37 | Hot reboot 38 | Reboot 39 | Time settings 40 | Reboot required 41 | Customizations 42 | Notes 43 | Test it 44 | Module not enabled 45 | Activate doze with proximity sensor 46 | Doze with proximity sensor is disabled 47 | Doze with proximity sensor is enabled 48 | Start service 49 | Service started 50 | Info 51 | This module works on Google stock/AOSP based roms.\nIf you have got a Samsung or a LG device, try this module; if it works OK, if it doesn\'t I can\'t do anything 52 | Default 53 | Module created by dvdandroid\n\nSource code available at GitHub 54 | Service stopped 55 | Stop service 56 | Doze on power key click 57 | Instead of wake up device, it will appear Ambient Display 58 | Device will wake up normally 59 | When to pulse after a buzzworthy notification arrives 60 | Extras 61 | Caution! 62 | The device can not turn over if something goes wrong. To avoid this, set another method that makes the device awake (waking up with the volume keys for example).\n\nIf no precautions are made and something goes wrong, you have to disable or uninstall Xposed. 63 | 64 | 65 | -------------------------------------------------------------------------------- /app/src/main/res/xml/prefs.xml: -------------------------------------------------------------------------------- 1 | 2 | 25 | 26 | 28 | 29 | 33 | 34 | 35 | 36 | 44 | 45 | 53 | 54 | 62 | 63 | 64 | 65 | 66 | 67 | 75 | 76 | 83 | 84 | 89 | 90 | 97 | 98 | 99 | 100 | 101 | 102 | 109 | 110 | 117 | 118 | 119 | 120 | 121 | 122 | 125 | 126 | 129 | 130 | 134 | 135 | 136 | 137 | -------------------------------------------------------------------------------- /build.gradle: -------------------------------------------------------------------------------- 1 | /* 2 | * The MIT License (MIT) 3 | * 4 | * Copyright (c) 2015 DVDAndroid 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in all 14 | * copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | * SOFTWARE. 23 | */ 24 | 25 | // Top-level build file where you can add configuration options common to all sub-projects/modules. 26 | 27 | buildscript { 28 | repositories { 29 | jcenter() 30 | } 31 | dependencies { 32 | //noinspection GradleDependency 33 | classpath 'com.android.tools.build:gradle:2.3.3' 34 | 35 | // NOTE: Do not place your application dependencies here; they belong 36 | // in the individual module build.gradle files 37 | } 38 | } 39 | 40 | allprojects { 41 | repositories { 42 | jcenter() 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /gradle.properties: -------------------------------------------------------------------------------- 1 | # Project-wide Gradle settings. 2 | 3 | # IDE (e.g. Android Studio) users: 4 | # Gradle settings configured through the IDE *will override* 5 | # any settings specified in this file. 6 | 7 | # For more details on how to configure your build environment visit 8 | # http://www.gradle.org/docs/current/userguide/build_environment.html 9 | 10 | # Specifies the JVM arguments used for the daemon process. 11 | # The setting is particularly useful for tweaking memory settings. 12 | # Default value: -Xmx10248m -XX:MaxPermSize=256m 13 | # org.gradle.jvmargs=-Xmx2048m -XX:MaxPermSize=512m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8 14 | 15 | # When configured, Gradle will run in incubating parallel mode. 16 | # This option should only be used with decoupled projects. More details, visit 17 | # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects 18 | # org.gradle.parallel=true -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DVDAndroid/Xposed-EnableAmbientDisplay/f9e16f17e7a4f7aa002d50a971ec4121ab116363/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | #Mon Aug 28 10:34:20 CEST 2017 2 | distributionBase=GRADLE_USER_HOME 3 | distributionPath=wrapper/dists 4 | zipStoreBase=GRADLE_USER_HOME 5 | zipStorePath=wrapper/dists 6 | distributionUrl=https\://services.gradle.org/distributions/gradle-3.3-all.zip 7 | -------------------------------------------------------------------------------- /gradlew: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | ############################################################################## 4 | ## 5 | ## Gradle start up script for UN*X 6 | ## 7 | ############################################################################## 8 | 9 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 10 | DEFAULT_JVM_OPTS="" 11 | 12 | APP_NAME="Gradle" 13 | APP_BASE_NAME=`basename "$0"` 14 | 15 | # Use the maximum available, or set MAX_FD != -1 to use that value. 16 | MAX_FD="maximum" 17 | 18 | warn ( ) { 19 | echo "$*" 20 | } 21 | 22 | die ( ) { 23 | echo 24 | echo "$*" 25 | echo 26 | exit 1 27 | } 28 | 29 | # OS specific support (must be 'true' or 'false'). 30 | cygwin=false 31 | msys=false 32 | darwin=false 33 | case "`uname`" in 34 | CYGWIN* ) 35 | cygwin=true 36 | ;; 37 | Darwin* ) 38 | darwin=true 39 | ;; 40 | MINGW* ) 41 | msys=true 42 | ;; 43 | esac 44 | 45 | # For Cygwin, ensure paths are in UNIX format before anything is touched. 46 | if $cygwin ; then 47 | [ -n "$JAVA_HOME" ] && JAVA_HOME=`cygpath --unix "$JAVA_HOME"` 48 | fi 49 | 50 | # Attempt to set APP_HOME 51 | # Resolve links: $0 may be a link 52 | PRG="$0" 53 | # Need this for relative symlinks. 54 | while [ -h "$PRG" ] ; do 55 | ls=`ls -ld "$PRG"` 56 | link=`expr "$ls" : '.*-> \(.*\)$'` 57 | if expr "$link" : '/.*' > /dev/null; then 58 | PRG="$link" 59 | else 60 | PRG=`dirname "$PRG"`"/$link" 61 | fi 62 | done 63 | SAVED="`pwd`" 64 | cd "`dirname \"$PRG\"`/" >&- 65 | APP_HOME="`pwd -P`" 66 | cd "$SAVED" >&- 67 | 68 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar 69 | 70 | # Determine the Java command to use to start the JVM. 71 | if [ -n "$JAVA_HOME" ] ; then 72 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then 73 | # IBM's JDK on AIX uses strange locations for the executables 74 | JAVACMD="$JAVA_HOME/jre/sh/java" 75 | else 76 | JAVACMD="$JAVA_HOME/bin/java" 77 | fi 78 | if [ ! -x "$JAVACMD" ] ; then 79 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME 80 | 81 | Please set the JAVA_HOME variable in your environment to match the 82 | location of your Java installation." 83 | fi 84 | else 85 | JAVACMD="java" 86 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 87 | 88 | Please set the JAVA_HOME variable in your environment to match the 89 | location of your Java installation." 90 | fi 91 | 92 | # Increase the maximum file descriptors if we can. 93 | if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then 94 | MAX_FD_LIMIT=`ulimit -H -n` 95 | if [ $? -eq 0 ] ; then 96 | if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then 97 | MAX_FD="$MAX_FD_LIMIT" 98 | fi 99 | ulimit -n $MAX_FD 100 | if [ $? -ne 0 ] ; then 101 | warn "Could not set maximum file descriptor limit: $MAX_FD" 102 | fi 103 | else 104 | warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" 105 | fi 106 | fi 107 | 108 | # For Darwin, add options to specify how the application appears in the dock 109 | if $darwin; then 110 | GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" 111 | fi 112 | 113 | # For Cygwin, switch paths to Windows format before running java 114 | if $cygwin ; then 115 | APP_HOME=`cygpath --path --mixed "$APP_HOME"` 116 | CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` 117 | 118 | # We build the pattern for arguments to be converted via cygpath 119 | ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` 120 | SEP="" 121 | for dir in $ROOTDIRSRAW ; do 122 | ROOTDIRS="$ROOTDIRS$SEP$dir" 123 | SEP="|" 124 | done 125 | OURCYGPATTERN="(^($ROOTDIRS))" 126 | # Add a user-defined pattern to the cygpath arguments 127 | if [ "$GRADLE_CYGPATTERN" != "" ] ; then 128 | OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" 129 | fi 130 | # Now convert the arguments - kludge to limit ourselves to /bin/sh 131 | i=0 132 | for arg in "$@" ; do 133 | CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` 134 | CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option 135 | 136 | if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition 137 | eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` 138 | else 139 | eval `echo args$i`="\"$arg\"" 140 | fi 141 | i=$((i+1)) 142 | done 143 | case $i in 144 | (0) set -- ;; 145 | (1) set -- "$args0" ;; 146 | (2) set -- "$args0" "$args1" ;; 147 | (3) set -- "$args0" "$args1" "$args2" ;; 148 | (4) set -- "$args0" "$args1" "$args2" "$args3" ;; 149 | (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; 150 | (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; 151 | (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; 152 | (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; 153 | (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; 154 | esac 155 | fi 156 | 157 | # Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules 158 | function splitJvmOpts() { 159 | JVM_OPTS=("$@") 160 | } 161 | eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS 162 | JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME" 163 | 164 | exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@" 165 | -------------------------------------------------------------------------------- /gradlew.bat: -------------------------------------------------------------------------------- 1 | @if "%DEBUG%" == "" @echo off 2 | @rem ########################################################################## 3 | @rem 4 | @rem Gradle startup script for Windows 5 | @rem 6 | @rem ########################################################################## 7 | 8 | @rem Set local scope for the variables with windows NT shell 9 | if "%OS%"=="Windows_NT" setlocal 10 | 11 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 12 | set DEFAULT_JVM_OPTS= 13 | 14 | set DIRNAME=%~dp0 15 | if "%DIRNAME%" == "" set DIRNAME=. 16 | set APP_BASE_NAME=%~n0 17 | set APP_HOME=%DIRNAME% 18 | 19 | @rem Find java.exe 20 | if defined JAVA_HOME goto findJavaFromJavaHome 21 | 22 | set JAVA_EXE=java.exe 23 | %JAVA_EXE% -version >NUL 2>&1 24 | if "%ERRORLEVEL%" == "0" goto init 25 | 26 | echo. 27 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 28 | echo. 29 | echo Please set the JAVA_HOME variable in your environment to match the 30 | echo location of your Java installation. 31 | 32 | goto fail 33 | 34 | :findJavaFromJavaHome 35 | set JAVA_HOME=%JAVA_HOME:"=% 36 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe 37 | 38 | if exist "%JAVA_EXE%" goto init 39 | 40 | echo. 41 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 42 | echo. 43 | echo Please set the JAVA_HOME variable in your environment to match the 44 | echo location of your Java installation. 45 | 46 | goto fail 47 | 48 | :init 49 | @rem Get command-line arguments, handling Windowz variants 50 | 51 | if not "%OS%" == "Windows_NT" goto win9xME_args 52 | if "%@eval[2+2]" == "4" goto 4NT_args 53 | 54 | :win9xME_args 55 | @rem Slurp the command line arguments. 56 | set CMD_LINE_ARGS= 57 | set _SKIP=2 58 | 59 | :win9xME_args_slurp 60 | if "x%~1" == "x" goto execute 61 | 62 | set CMD_LINE_ARGS=%* 63 | goto execute 64 | 65 | :4NT_args 66 | @rem Get arguments from the 4NT Shell from JP Software 67 | set CMD_LINE_ARGS=%$ 68 | 69 | :execute 70 | @rem Setup the command line 71 | 72 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar 73 | 74 | @rem Execute Gradle 75 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% 76 | 77 | :end 78 | @rem End local scope for the variables with windows NT shell 79 | if "%ERRORLEVEL%"=="0" goto mainEnd 80 | 81 | :fail 82 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of 83 | rem the _cmd.exe /c_ return code! 84 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 85 | exit /b 1 86 | 87 | :mainEnd 88 | if "%OS%"=="Windows_NT" endlocal 89 | 90 | :omega 91 | -------------------------------------------------------------------------------- /screenshots/ambient-display.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DVDAndroid/Xposed-EnableAmbientDisplay/f9e16f17e7a4f7aa002d50a971ec4121ab116363/screenshots/ambient-display.png -------------------------------------------------------------------------------- /screenshots/main_activity.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DVDAndroid/Xposed-EnableAmbientDisplay/f9e16f17e7a4f7aa002d50a971ec4121ab116363/screenshots/main_activity.png -------------------------------------------------------------------------------- /screenshots/settings.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DVDAndroid/Xposed-EnableAmbientDisplay/f9e16f17e7a4f7aa002d50a971ec4121ab116363/screenshots/settings.png -------------------------------------------------------------------------------- /settings.gradle: -------------------------------------------------------------------------------- 1 | include ':app' 2 | --------------------------------------------------------------------------------