├── app ├── .gitignore ├── src │ ├── main │ │ ├── ic_launcher-playstore.png │ │ ├── res │ │ │ ├── mipmap-hdpi │ │ │ │ ├── ic_launcher.png │ │ │ │ └── ic_launcher_round.png │ │ │ ├── mipmap-mdpi │ │ │ │ ├── ic_launcher.png │ │ │ │ └── ic_launcher_round.png │ │ │ ├── mipmap-xhdpi │ │ │ │ ├── ic_launcher.png │ │ │ │ └── ic_launcher_round.png │ │ │ ├── mipmap-xxhdpi │ │ │ │ ├── ic_launcher.png │ │ │ │ └── ic_launcher_round.png │ │ │ ├── mipmap-xxxhdpi │ │ │ │ ├── ic_launcher.png │ │ │ │ └── ic_launcher_round.png │ │ │ ├── values │ │ │ │ ├── colors.xml │ │ │ │ ├── ic_launcher_background.xml │ │ │ │ ├── themes.xml │ │ │ │ └── strings.xml │ │ │ ├── mipmap-anydpi-v26 │ │ │ │ ├── ic_launcher.xml │ │ │ │ └── ic_launcher_round.xml │ │ │ ├── values-night │ │ │ │ └── themes.xml │ │ │ ├── layout │ │ │ │ ├── activity_main.xml │ │ │ │ └── activity_permission.xml │ │ │ ├── drawable │ │ │ │ ├── ic_baseline_code_24.xml │ │ │ │ ├── ic_baseline_bedtime_24.xml │ │ │ │ ├── ic_baseline_email_24.xml │ │ │ │ ├── ic_baseline_insert_drive_file_24.xml │ │ │ │ ├── ic_launcher_foreground.xml │ │ │ │ └── ic_baseline_person_pin_24.xml │ │ │ └── xml │ │ │ │ └── main.xml │ │ ├── java │ │ │ └── com │ │ │ │ └── draco │ │ │ │ └── comatose │ │ │ │ ├── repositories │ │ │ │ ├── constants │ │ │ │ │ ├── SettingsConstants.kt │ │ │ │ │ └── DeviceIdleConstants.kt │ │ │ │ └── profiles │ │ │ │ │ └── DeviceIdleConstantsProfiles.kt │ │ │ │ ├── utils │ │ │ │ └── PermissionUtils.kt │ │ │ │ ├── receivers │ │ │ │ └── BootReceiver.kt │ │ │ │ ├── views │ │ │ │ ├── MainActivity.kt │ │ │ │ └── PermissionActivity.kt │ │ │ │ ├── viewmodels │ │ │ │ └── PermissionActivityViewModel.kt │ │ │ │ └── fragments │ │ │ │ └── MainPreferenceFragment.kt │ │ └── AndroidManifest.xml │ ├── test │ │ └── java │ │ │ └── com │ │ │ └── draco │ │ │ └── comatose │ │ │ └── ExampleUnitTest.kt │ └── androidTest │ │ └── java │ │ └── com │ │ └── draco │ │ └── comatose │ │ └── ExampleInstrumentedTest.kt ├── proguard-rules.pro └── build.gradle ├── extra.txt ├── README.md ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── .gitignore ├── .github └── workflows │ └── build.yml ├── settings.gradle ├── gradle.properties ├── LICENSE ├── gradlew.bat └── gradlew /app/.gitignore: -------------------------------------------------------------------------------- 1 | /build -------------------------------------------------------------------------------- /extra.txt: -------------------------------------------------------------------------------- 1 | tytydraco/Comatose MIGHT NEED SOME MORE WORK! 2 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Comatose 2 | Put your Android device into a deep sleep 3 | -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tytydraco/Comatose/HEAD/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /app/src/main/ic_launcher-playstore.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tytydraco/Comatose/HEAD/app/src/main/ic_launcher-playstore.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-hdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tytydraco/Comatose/HEAD/app/src/main/res/mipmap-hdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-mdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tytydraco/Comatose/HEAD/app/src/main/res/mipmap-mdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tytydraco/Comatose/HEAD/app/src/main/res/mipmap-xhdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tytydraco/Comatose/HEAD/app/src/main/res/mipmap-xxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xxxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tytydraco/Comatose/HEAD/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/values/colors.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | #673ab7 4 | -------------------------------------------------------------------------------- /app/src/main/res/mipmap-hdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tytydraco/Comatose/HEAD/app/src/main/res/mipmap-hdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-mdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tytydraco/Comatose/HEAD/app/src/main/res/mipmap-mdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tytydraco/Comatose/HEAD/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tytydraco/Comatose/HEAD/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tytydraco/Comatose/HEAD/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /app/src/main/res/values/ic_launcher_background.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | #673AB7 4 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *.iml 2 | .gradle 3 | /local.properties 4 | /.idea 5 | /app/release 6 | .DS_Store 7 | /build 8 | /captures 9 | .externalNativeBuild 10 | .cxx 11 | app/src/main/res/raw/rom 12 | *.so 13 | -------------------------------------------------------------------------------- /app/src/main/java/com/draco/comatose/repositories/constants/SettingsConstants.kt: -------------------------------------------------------------------------------- 1 | package com.draco.comatose.repositories.constants 2 | 3 | object SettingsConstants { 4 | const val DEVICE_IDLE_CONSTANTS = "device_idle_constants" 5 | } -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | #Mon Apr 05 17:03:11 PDT 2021 2 | distributionBase=GRADLE_USER_HOME 3 | distributionUrl=https\://services.gradle.org/distributions/gradle-6.8.2-bin.zip 4 | distributionPath=wrapper/dists 5 | zipStorePath=wrapper/dists 6 | zipStoreBase=GRADLE_USER_HOME 7 | -------------------------------------------------------------------------------- /app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /.github/workflows/build.yml: -------------------------------------------------------------------------------- 1 | name: Build 2 | 3 | on: 4 | workflow_dispatch: 5 | push: 6 | 7 | jobs: 8 | build: 9 | runs-on: ubuntu-latest 10 | 11 | steps: 12 | - uses: actions/checkout@v2 13 | - uses: tytydraco/android-public-build@main 14 | with: 15 | token: ${{ secrets.GITHUB_TOKEN }} 16 | -------------------------------------------------------------------------------- /settings.gradle: -------------------------------------------------------------------------------- 1 | dependencyResolutionManagement { 2 | repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS) 3 | repositories { 4 | google() 5 | mavenCentral() 6 | jcenter() // Warning: this repository is going to shut down soon 7 | } 8 | } 9 | rootProject.name = "Comatose" 10 | include ':app' 11 | -------------------------------------------------------------------------------- /app/src/main/res/values-night/themes.xml: -------------------------------------------------------------------------------- 1 | 2 | 8 | -------------------------------------------------------------------------------- /app/src/main/res/layout/activity_main.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 9 | -------------------------------------------------------------------------------- /app/src/test/java/com/draco/comatose/ExampleUnitTest.kt: -------------------------------------------------------------------------------- 1 | package com.draco.comatose 2 | 3 | import org.junit.Test 4 | 5 | import org.junit.Assert.* 6 | 7 | /** 8 | * Example local unit test, which will execute on the development machine (host). 9 | * 10 | * See [testing documentation](http://d.android.com/tools/testing). 11 | */ 12 | class ExampleUnitTest { 13 | @Test 14 | fun addition_isCorrect() { 15 | assertEquals(4, 2 + 2) 16 | } 17 | } -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_baseline_code_24.xml: -------------------------------------------------------------------------------- 1 | 7 | 10 | 11 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_baseline_bedtime_24.xml: -------------------------------------------------------------------------------- 1 | 7 | 10 | 11 | -------------------------------------------------------------------------------- /app/src/main/java/com/draco/comatose/utils/PermissionUtils.kt: -------------------------------------------------------------------------------- 1 | package com.draco.comatose.utils 2 | 3 | import android.content.Context 4 | import android.content.pm.PackageManager 5 | 6 | class PermissionUtils { 7 | companion object { 8 | /** 9 | * Return true if the permission is granted, false otherwise 10 | */ 11 | fun isPermissionsGranted(context: Context, permission: String): Boolean = 12 | context.checkSelfPermission(permission) == PackageManager.PERMISSION_GRANTED 13 | } 14 | } -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_baseline_email_24.xml: -------------------------------------------------------------------------------- 1 | 7 | 10 | 11 | -------------------------------------------------------------------------------- /app/src/main/res/values/themes.xml: -------------------------------------------------------------------------------- 1 | 2 | 9 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_baseline_insert_drive_file_24.xml: -------------------------------------------------------------------------------- 1 | 8 | 11 | 12 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_launcher_foreground.xml: -------------------------------------------------------------------------------- 1 | 7 | 11 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_baseline_person_pin_24.xml: -------------------------------------------------------------------------------- 1 | 7 | 10 | 11 | -------------------------------------------------------------------------------- /app/src/androidTest/java/com/draco/comatose/ExampleInstrumentedTest.kt: -------------------------------------------------------------------------------- 1 | package com.draco.comatose 2 | 3 | import androidx.test.platform.app.InstrumentationRegistry 4 | import androidx.test.ext.junit.runners.AndroidJUnit4 5 | 6 | import org.junit.Test 7 | import org.junit.runner.RunWith 8 | 9 | import org.junit.Assert.* 10 | 11 | /** 12 | * Instrumented test, which will execute on an Android device. 13 | * 14 | * See [testing documentation](http://d.android.com/tools/testing). 15 | */ 16 | @RunWith(AndroidJUnit4::class) 17 | class ExampleInstrumentedTest { 18 | @Test 19 | fun useAppContext() { 20 | // Context of the app under test. 21 | val appContext = InstrumentationRegistry.getInstrumentation().targetContext 22 | assertEquals("com.draco.comatose", appContext.packageName) 23 | } 24 | } -------------------------------------------------------------------------------- /app/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # You can control the set of applied configuration files using the 3 | # proguardFiles setting in build.gradle. 4 | # 5 | # For more details, see 6 | # http://developer.android.com/guide/developing/tools/proguard.html 7 | 8 | # If your project uses WebView with JS, uncomment the following 9 | # and specify the fully qualified class name to the JavaScript interface 10 | # class: 11 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 12 | # public *; 13 | #} 14 | 15 | # Uncomment this to preserve the line number information for 16 | # debugging stack traces. 17 | #-keepattributes SourceFile,LineNumberTable 18 | 19 | # If you keep the line number information, uncomment this to 20 | # hide the original source file name. 21 | #-renamesourcefileattribute SourceFile -------------------------------------------------------------------------------- /app/src/main/java/com/draco/comatose/receivers/BootReceiver.kt: -------------------------------------------------------------------------------- 1 | package com.draco.comatose.receivers 2 | 3 | import android.content.BroadcastReceiver 4 | import android.content.Context 5 | import android.content.Intent 6 | import android.provider.Settings 7 | import androidx.preference.PreferenceManager 8 | import com.draco.comatose.R 9 | import com.draco.comatose.repositories.constants.SettingsConstants 10 | 11 | class BootReceiver : BroadcastReceiver() { 12 | override fun onReceive(context: Context, intent: Intent) { 13 | if (intent.action == Intent.ACTION_BOOT_COMPLETED) { 14 | val sharedPrefs = PreferenceManager.getDefaultSharedPreferences(context) 15 | val config = sharedPrefs.getString(context.getString(R.string.pref_saved_constants_key), null) ?: return 16 | 17 | Settings.Global.putString( 18 | context.contentResolver, 19 | SettingsConstants.DEVICE_IDLE_CONSTANTS, 20 | config 21 | ) 22 | } 23 | } 24 | } -------------------------------------------------------------------------------- /gradle.properties: -------------------------------------------------------------------------------- 1 | # Project-wide Gradle settings. 2 | # IDE (e.g. Android Studio) users: 3 | # Gradle settings configured through the IDE *will override* 4 | # any settings specified in this file. 5 | # For more details on how to configure your build environment visit 6 | # http://www.gradle.org/docs/current/userguide/build_environment.html 7 | # Specifies the JVM arguments used for the daemon process. 8 | # The setting is particularly useful for tweaking memory settings. 9 | org.gradle.jvmargs=-Xmx2048m -Dfile.encoding=UTF-8 10 | # When configured, Gradle will run in incubating parallel mode. 11 | # This option should only be used with decoupled projects. More details, visit 12 | # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects 13 | # org.gradle.parallel=true 14 | # AndroidX package structure to make it clearer which packages are bundled with the 15 | # Android operating system, and which are packaged with your app"s APK 16 | # https://developer.android.com/topic/libraries/support-library/androidx-rn 17 | android.useAndroidX=true 18 | # Automatically convert third-party libraries to use AndroidX 19 | android.enableJetifier=true 20 | # Kotlin code style for this project: "official" or "obsolete": 21 | kotlin.code.style=official -------------------------------------------------------------------------------- /app/src/main/java/com/draco/comatose/views/MainActivity.kt: -------------------------------------------------------------------------------- 1 | package com.draco.comatose.views 2 | 3 | import android.content.Intent 4 | import android.os.Bundle 5 | import androidx.appcompat.app.AppCompatActivity 6 | import androidx.fragment.app.FragmentContainerView 7 | import com.draco.comatose.R 8 | import com.draco.comatose.fragments.MainPreferenceFragment 9 | import com.draco.comatose.utils.PermissionUtils 10 | 11 | class MainActivity : AppCompatActivity() { 12 | private lateinit var preferences: FragmentContainerView 13 | 14 | override fun onCreate(savedInstanceState: Bundle?) { 15 | super.onCreate(savedInstanceState) 16 | setContentView(R.layout.activity_main) 17 | 18 | preferences = findViewById(R.id.preferences) 19 | 20 | /* If we are missing a permission, lock the user in the permission activity */ 21 | if (!PermissionUtils.isPermissionsGranted(this, android.Manifest.permission.WRITE_SECURE_SETTINGS)) 22 | goToPermissionActivity() 23 | 24 | supportFragmentManager 25 | .beginTransaction() 26 | .replace(R.id.preferences, MainPreferenceFragment()) 27 | .commit() 28 | } 29 | 30 | private fun goToPermissionActivity() { 31 | val intent = Intent(this, PermissionActivity::class.java) 32 | startActivity(intent) 33 | } 34 | } -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | BSD 2-Clause License 2 | 3 | Copyright (c) 2022, Tyler Nijmeh 4 | All rights reserved. 5 | 6 | Redistribution and use in source and binary forms, with or without 7 | modification, are permitted provided that the following conditions are met: 8 | 9 | 1. Redistributions of source code must retain the above copyright notice, this 10 | list of conditions and the following disclaimer. 11 | 12 | 2. Redistributions in binary form must reproduce the above copyright notice, 13 | this list of conditions and the following disclaimer in the documentation 14 | and/or other materials provided with the distribution. 15 | 16 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 17 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 18 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 19 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 20 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 21 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 22 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 23 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 24 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 25 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 | -------------------------------------------------------------------------------- /app/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 7 | 9 | 10 | 18 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 29 | 30 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | -------------------------------------------------------------------------------- /app/src/main/java/com/draco/comatose/views/PermissionActivity.kt: -------------------------------------------------------------------------------- 1 | package com.draco.comatose.views 2 | 3 | import android.content.ClipData 4 | import android.content.ClipboardManager 5 | import android.content.Context 6 | import android.os.Bundle 7 | import android.widget.TextView 8 | import androidx.activity.viewModels 9 | import androidx.appcompat.app.AppCompatActivity 10 | import com.draco.comatose.R 11 | import com.draco.comatose.viewmodels.PermissionActivityViewModel 12 | import com.google.android.material.snackbar.Snackbar 13 | 14 | class PermissionActivity : AppCompatActivity() { 15 | private val viewModel: PermissionActivityViewModel by viewModels() 16 | 17 | private lateinit var command: TextView 18 | 19 | override fun onCreate(savedInstanceState: Bundle?) { 20 | super.onCreate(savedInstanceState) 21 | setContentView(R.layout.activity_permission) 22 | 23 | command = findViewById(R.id.command) 24 | 25 | /* Copy ADB command to clipboard */ 26 | command.setOnClickListener { 27 | val clipboardManager = getSystemService(Context.CLIPBOARD_SERVICE) as ClipboardManager 28 | val clip = ClipData.newPlainText("ADB Command", command.text.toString()) 29 | clipboardManager.setPrimaryClip(clip) 30 | 31 | Snackbar.make(command, R.string.copied, Snackbar.LENGTH_SHORT).show() 32 | } 33 | 34 | /* Once permission is granted, return */ 35 | viewModel.permissionGranted.observe(this) { 36 | if (it == true) 37 | finish() 38 | } 39 | } 40 | 41 | /* Disallow exit */ 42 | override fun onBackPressed() {} 43 | } -------------------------------------------------------------------------------- /app/build.gradle: -------------------------------------------------------------------------------- 1 | plugins { 2 | id 'com.android.application' 3 | id 'kotlin-android' 4 | id 'com.google.android.gms.oss-licenses-plugin' 5 | } 6 | 7 | android { 8 | compileSdk 30 9 | buildToolsVersion "30.0.3" 10 | 11 | defaultConfig { 12 | applicationId "com.draco.comatose" 13 | minSdk 23 14 | targetSdk 30 15 | versionCode 16 16 | versionName "3.0.2" 17 | 18 | testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" 19 | } 20 | 21 | buildTypes { 22 | release { 23 | minifyEnabled true 24 | shrinkResources true 25 | proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' 26 | } 27 | } 28 | compileOptions { 29 | sourceCompatibility JavaVersion.VERSION_1_8 30 | targetCompatibility JavaVersion.VERSION_1_8 31 | } 32 | kotlinOptions { 33 | jvmTarget = '1.8' 34 | } 35 | } 36 | 37 | dependencies { 38 | 39 | implementation 'androidx.core:core-ktx:1.3.2' 40 | implementation 'androidx.appcompat:appcompat:1.2.0' 41 | implementation 'com.google.android.material:material:1.3.0' 42 | 43 | implementation 'androidx.preference:preference-ktx:1.1.1' 44 | implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.4.1' 45 | 46 | implementation 'androidx.lifecycle:lifecycle-viewmodel-ktx:2.3.1' 47 | implementation 'androidx.lifecycle:lifecycle-livedata-ktx:2.3.1' 48 | implementation 'androidx.lifecycle:lifecycle-runtime-ktx:2.3.1' 49 | 50 | implementation 'com.google.android.gms:play-services-oss-licenses:17.0.0' 51 | 52 | testImplementation 'junit:junit:4.+' 53 | androidTestImplementation 'androidx.test.ext:junit:1.1.2' 54 | androidTestImplementation 'androidx.test.espresso:espresso-core:3.3.0' 55 | } -------------------------------------------------------------------------------- /app/src/main/java/com/draco/comatose/viewmodels/PermissionActivityViewModel.kt: -------------------------------------------------------------------------------- 1 | package com.draco.comatose.viewmodels 2 | 3 | import android.app.Application 4 | import androidx.lifecycle.AndroidViewModel 5 | import androidx.lifecycle.LiveData 6 | import androidx.lifecycle.MutableLiveData 7 | import androidx.lifecycle.viewModelScope 8 | import com.draco.comatose.BuildConfig 9 | import com.draco.comatose.utils.PermissionUtils 10 | import kotlinx.coroutines.Dispatchers 11 | import kotlinx.coroutines.delay 12 | import kotlinx.coroutines.launch 13 | 14 | class PermissionActivityViewModel(application: Application) : AndroidViewModel(application) { 15 | private val _permissionGranted = MutableLiveData(false) 16 | val permissionGranted: LiveData = _permissionGranted 17 | 18 | private fun askRootPermission() { 19 | try { 20 | ProcessBuilder( 21 | "su", 22 | "-c", 23 | "pm grant ${BuildConfig.APPLICATION_ID} android.permission.WRITE_SECURE_SETTINGS" 24 | ).start() 25 | } catch (_: Exception) {} 26 | } 27 | 28 | private fun isWriteSecureSettingsPermissionGranted(): Boolean { 29 | val context = getApplication().applicationContext 30 | return PermissionUtils.isPermissionsGranted(context, android.Manifest.permission.WRITE_SECURE_SETTINGS) 31 | } 32 | 33 | private fun startPermissionCheckLoop() { 34 | viewModelScope.launch(Dispatchers.IO) { 35 | while (!isWriteSecureSettingsPermissionGranted()) 36 | delay(100) 37 | _permissionGranted.postValue(true) 38 | } 39 | } 40 | 41 | init { 42 | if (!isWriteSecureSettingsPermissionGranted()) { 43 | viewModelScope.launch(Dispatchers.IO) { 44 | askRootPermission() 45 | } 46 | startPermissionCheckLoop() 47 | } 48 | } 49 | } -------------------------------------------------------------------------------- /app/src/main/res/layout/activity_permission.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 10 | 15 | 21 | 28 | 29 | 30 | 37 | 43 | 49 | 50 | -------------------------------------------------------------------------------- /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 | set DIRNAME=%~dp0 12 | if "%DIRNAME%" == "" set DIRNAME=. 13 | set APP_BASE_NAME=%~n0 14 | set APP_HOME=%DIRNAME% 15 | 16 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 17 | set DEFAULT_JVM_OPTS= 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 Windows variants 50 | 51 | if not "%OS%" == "Windows_NT" goto win9xME_args 52 | 53 | :win9xME_args 54 | @rem Slurp the command line arguments. 55 | set CMD_LINE_ARGS= 56 | set _SKIP=2 57 | 58 | :win9xME_args_slurp 59 | if "x%~1" == "x" goto execute 60 | 61 | set CMD_LINE_ARGS=%* 62 | 63 | :execute 64 | @rem Setup the command line 65 | 66 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar 67 | 68 | @rem Execute Gradle 69 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% 70 | 71 | :end 72 | @rem End local scope for the variables with windows NT shell 73 | if "%ERRORLEVEL%"=="0" goto mainEnd 74 | 75 | :fail 76 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of 77 | rem the _cmd.exe /c_ return code! 78 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 79 | exit /b 1 80 | 81 | :mainEnd 82 | if "%OS%"=="Windows_NT" endlocal 83 | 84 | :omega 85 | -------------------------------------------------------------------------------- /app/src/main/res/xml/main.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 9 | 14 | 19 | 24 | 29 | 30 | 31 | 36 | 41 | 46 | 51 | 52 | -------------------------------------------------------------------------------- /app/src/main/res/values/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | Comatose 3 | 4 | Permissions 5 | 6 | Woah there! 7 | We need a special permission to continue. Use ADB to run the following command (one line): 8 | adb shell pm grant com.draco.comatose android.permission.WRITE_SECURE_SETTINGS 9 | 10 | Waiting for permission 11 | Copied to clipboard 12 | 13 | Could not handle this action 14 | Successfully applied profile 15 | 16 | https://www.github.com/tytydraco 17 | https://www.github.com/tytydraco/Comatose 18 | mailto:tylernij@gmail.com 19 | 20 | Profiles 21 | About 22 | 23 | saved_constants 24 | 25 | default 26 | Default 27 | Use the device\'s default idle settings 28 | 29 | light 30 | Light 31 | Does not affect day-to-day usage 32 | 33 | moderate 34 | Moderate 35 | Additional savings with slightly less timely notifications 36 | 37 | high 38 | High 39 | A state of deep sleep where background processes and checks are delayed 40 | 41 | extreme 42 | Extreme 43 | Save as much power as possible with large sacrifices to background work 44 | 45 | Developer 46 | Tyler Nijmeh 47 | developer 48 | 49 | Source code 50 | Check out this project on GitHub 51 | source 52 | 53 | Contact 54 | Email me with questions, comments, and concerns 55 | contact 56 | 57 | Licenses 58 | View the open source licenses 59 | licenses 60 | -------------------------------------------------------------------------------- /app/src/main/java/com/draco/comatose/fragments/MainPreferenceFragment.kt: -------------------------------------------------------------------------------- 1 | package com.draco.comatose.fragments 2 | 3 | import android.content.Intent 4 | import android.content.SharedPreferences 5 | import android.net.Uri 6 | import android.os.Bundle 7 | import android.provider.Settings 8 | import androidx.preference.Preference 9 | import androidx.preference.PreferenceFragmentCompat 10 | import androidx.preference.PreferenceManager 11 | import com.draco.comatose.R 12 | import com.draco.comatose.repositories.constants.SettingsConstants 13 | import com.draco.comatose.repositories.profiles.DeviceIdleConstantsProfiles 14 | import com.google.android.gms.oss.licenses.OssLicensesMenuActivity 15 | import com.google.android.material.snackbar.Snackbar 16 | 17 | class MainPreferenceFragment : PreferenceFragmentCompat() { 18 | private lateinit var sharedPrefs: SharedPreferences 19 | 20 | override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) { 21 | setPreferencesFromResource(R.xml.main, rootKey) 22 | } 23 | 24 | override fun onActivityCreated(savedInstanceState: Bundle?) { 25 | super.onActivityCreated(savedInstanceState) 26 | sharedPrefs = PreferenceManager.getDefaultSharedPreferences(context) 27 | } 28 | 29 | override fun onPreferenceTreeClick(preference: Preference): Boolean { 30 | when (preference.key) { 31 | getString(R.string.pref_profile_key_default) -> applyProfile(DeviceIdleConstantsProfiles.DEFAULT) 32 | getString(R.string.pref_profile_key_light) -> applyProfile(DeviceIdleConstantsProfiles.LIGHT) 33 | getString(R.string.pref_profile_key_moderate) -> applyProfile(DeviceIdleConstantsProfiles.MODERATE) 34 | getString(R.string.pref_profile_key_high) -> applyProfile(DeviceIdleConstantsProfiles.HIGH) 35 | getString(R.string.pref_profile_key_extreme) -> applyProfile(DeviceIdleConstantsProfiles.EXTREME) 36 | 37 | getString(R.string.pref_developer_key) -> openURL(getString(R.string.developer_url)) 38 | getString(R.string.pref_source_key) -> openURL(getString(R.string.source_url)) 39 | getString(R.string.pref_contact_key) -> openURL(getString(R.string.contact_url)) 40 | getString(R.string.pref_licenses_key) -> { 41 | val intent = Intent(requireContext(), OssLicensesMenuActivity::class.java) 42 | startActivity(intent) 43 | } 44 | else -> return super.onPreferenceTreeClick(preference) 45 | } 46 | return true 47 | } 48 | 49 | private fun applyProfile(config: String?) { 50 | val contentResolver = requireContext().contentResolver 51 | Settings.Global.putString( 52 | contentResolver, 53 | SettingsConstants.DEVICE_IDLE_CONSTANTS, 54 | config 55 | ) 56 | 57 | with (sharedPrefs.edit()) { 58 | putString(requireContext().getString(R.string.pref_saved_constants_key), config) 59 | apply() 60 | } 61 | 62 | Snackbar.make(requireView(), getString(R.string.snackbar_applied), Snackbar.LENGTH_SHORT).show() 63 | } 64 | 65 | /** 66 | * Open a URL for the user 67 | */ 68 | private fun openURL(url: String) { 69 | val intent = Intent(Intent.ACTION_VIEW, Uri.parse(url)) 70 | try { 71 | startActivity(intent) 72 | } catch (e: Exception) { 73 | e.printStackTrace() 74 | Snackbar.make(requireView(), getString(R.string.snackbar_intent_failed), Snackbar.LENGTH_SHORT).show() 75 | } 76 | } 77 | } -------------------------------------------------------------------------------- /app/src/main/java/com/draco/comatose/repositories/constants/DeviceIdleConstants.kt: -------------------------------------------------------------------------------- 1 | package com.draco.comatose.repositories.constants 2 | 3 | object DeviceIdleConstants { 4 | /** 5 | * Time after being inactive to enter light idle mode 6 | */ 7 | const val LIGHT_AFTER_INACTIVE_TO = "light_after_inactive_to" 8 | 9 | /** 10 | * Time after we would like to go idle until we actually do (wait for apps to finish) 11 | */ 12 | const val LIGHT_PRE_IDLE_TO = "light_pre_idle_to" 13 | 14 | /** 15 | * Time to run in idle maintenance mode 16 | */ 17 | const val LIGHT_IDLE_TO = "light_idle_to" 18 | 19 | /** 20 | * Scale factor to apply to LIGHT_IDLE_TO after each cycle 21 | */ 22 | const val LIGHT_IDLE_FACTOR = "light_idle_factor" 23 | 24 | /** 25 | * Max time to run in idle maintenance mode 26 | */ 27 | const val LIGHT_MAX_IDLE_TO = "light_max_idle_to" 28 | 29 | /** 30 | * Minimum time to make available for maintenance before exiting 31 | */ 32 | const val LIGHT_IDLE_MAINTENANCE_MIN_BUDGET = "light_idle_maintenance_min_budget" 33 | 34 | /** 35 | * Maximum time to make available for maintenance before exiting 36 | */ 37 | const val LIGHT_IDLE_MAINTENANCE_MAX_BUDGET = "light_idle_maintenance_max_budget" 38 | 39 | /** 40 | * Minimum time to stay in light idle mode after light doze so that we do not exit maintenance mode too quickly 41 | */ 42 | const val MIN_LIGHT_MAINTENANCE_TIME = "min_light_maintenance_time" 43 | 44 | /** 45 | * Minimum time to stay in light idle mode after deep doze so that we do not exit maintenance mode too quickly 46 | */ 47 | const val MIN_DEEP_MAINTENANCE_TIME = "min_deep_maintenance_time" 48 | 49 | /** 50 | * How long we will wait to get a good location before idling 51 | */ 52 | const val LOCATING_TO = "locating_to" 53 | 54 | /** 55 | * Desired maximum accuracy (in meters) of location before idling 56 | */ 57 | const val LOCATION_ACCURACY = "location_accuracy" 58 | 59 | /** 60 | * Should the user still be in idle mode until unlock, or as soon as the screen turns on? 61 | */ 62 | const val WAIT_FOR_UNLOCK = "wait_for_unlock" 63 | 64 | /** 65 | * Pre idle time factor to make idle delay longer 66 | */ 67 | const val PRE_IDLE_FACTOR_LONG = "pre_idle_factor_long" 68 | 69 | /** 70 | * Pre idle time factor to make idle delay shorter 71 | */ 72 | const val PRE_IDLE_FACTOR_SHORT = "pre_idle_factor_short" 73 | 74 | /** 75 | * Time after being inactive to check if device is not in motion 76 | */ 77 | const val INACTIVE_TO = "inactive_to" 78 | 79 | /** 80 | * Time after not noticing any motion to enter the inactive state 81 | */ 82 | const val SENSING_TO = "sensing_to" 83 | 84 | /** 85 | * Time after noticing motion to start looking for motion again 86 | */ 87 | const val MOTION_INACTIVE_TO = "motion_inactive_to" 88 | 89 | /** 90 | * Time after INACTIVE_TO that we will check for motion 91 | */ 92 | const val IDLE_AFTER_INACTIVE_TO = "idle_after_inactive_to" 93 | 94 | /** 95 | * Initial time after being idle that we can start regular maintenance again 96 | */ 97 | const val IDLE_PENDING_TO = "idle_pending_to" 98 | 99 | /** 100 | * Maximum IDLE_PENDING_TO allowed 101 | */ 102 | const val MAX_IDLE_PENDING_TO = "max_idle_pending_to" 103 | 104 | /** 105 | * Scale factor to apply to IDLE_PENDING_TO after each cycle 106 | */ 107 | const val IDLE_PENDING_FACTOR = "idle_pending_factor" 108 | 109 | /** 110 | * Time in quick doze to wait for tasks to finish 111 | */ 112 | const val QUICK_DOZE_DELAY_TO = "quick_doze_delay_to" 113 | 114 | /** 115 | * Initial time to be in idle state before returning to pending idle 116 | */ 117 | const val IDLE_TO = "idle_to" 118 | 119 | /** 120 | * Maximum IDLE_TO time 121 | */ 122 | const val MAX_IDLE_TO = "max_idle_to" 123 | 124 | /** 125 | * Scale factor to apply to IDLE_TO after each cycle 126 | */ 127 | const val IDLE_FACTOR = "idle_factor" 128 | 129 | /** 130 | * Minimum time until next alarm to enter idle mode 131 | */ 132 | const val MIN_TIME_TO_ALARM = "min_time_to_alarm" 133 | 134 | /** 135 | * Max time to whitelist an app if it has high priority 136 | */ 137 | const val MAX_TEMP_APP_WHITELIST_DURATION = "max_temp_app_whitelist_duration" 138 | 139 | /** 140 | * Time to whitelist an app receiving SMS 141 | */ 142 | const val SMS_TEMP_APP_WHITELIST_DURATION = "sms_temp_app_whitelist_duration" 143 | 144 | /** 145 | * Time to whitelist an app receiving MMS 146 | */ 147 | const val MMS_TEMP_APP_WHITELIST_DURATION = "mms_temp_app_whitelist_duration" 148 | 149 | /** 150 | * Max time to whitelist an app that is handling pending intents 151 | */ 152 | const val NOTIFICATION_WHITELIST_DURATION = "notification_whitelist_duration" 153 | } -------------------------------------------------------------------------------- /gradlew: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env sh 2 | 3 | ############################################################################## 4 | ## 5 | ## Gradle start up script for UN*X 6 | ## 7 | ############################################################################## 8 | 9 | # Attempt to set APP_HOME 10 | # Resolve links: $0 may be a link 11 | PRG="$0" 12 | # Need this for relative symlinks. 13 | while [ -h "$PRG" ] ; do 14 | ls=`ls -ld "$PRG"` 15 | link=`expr "$ls" : '.*-> \(.*\)$'` 16 | if expr "$link" : '/.*' > /dev/null; then 17 | PRG="$link" 18 | else 19 | PRG=`dirname "$PRG"`"/$link" 20 | fi 21 | done 22 | SAVED="`pwd`" 23 | cd "`dirname \"$PRG\"`/" >/dev/null 24 | APP_HOME="`pwd -P`" 25 | cd "$SAVED" >/dev/null 26 | 27 | APP_NAME="Gradle" 28 | APP_BASE_NAME=`basename "$0"` 29 | 30 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 31 | DEFAULT_JVM_OPTS="" 32 | 33 | # Use the maximum available, or set MAX_FD != -1 to use that value. 34 | MAX_FD="maximum" 35 | 36 | warn () { 37 | echo "$*" 38 | } 39 | 40 | die () { 41 | echo 42 | echo "$*" 43 | echo 44 | exit 1 45 | } 46 | 47 | # OS specific support (must be 'true' or 'false'). 48 | cygwin=false 49 | msys=false 50 | darwin=false 51 | nonstop=false 52 | case "`uname`" in 53 | CYGWIN* ) 54 | cygwin=true 55 | ;; 56 | Darwin* ) 57 | darwin=true 58 | ;; 59 | MINGW* ) 60 | msys=true 61 | ;; 62 | NONSTOP* ) 63 | nonstop=true 64 | ;; 65 | esac 66 | 67 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar 68 | 69 | # Determine the Java command to use to start the JVM. 70 | if [ -n "$JAVA_HOME" ] ; then 71 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then 72 | # IBM's JDK on AIX uses strange locations for the executables 73 | JAVACMD="$JAVA_HOME/jre/sh/java" 74 | else 75 | JAVACMD="$JAVA_HOME/bin/java" 76 | fi 77 | if [ ! -x "$JAVACMD" ] ; then 78 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME 79 | 80 | Please set the JAVA_HOME variable in your environment to match the 81 | location of your Java installation." 82 | fi 83 | else 84 | JAVACMD="java" 85 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 86 | 87 | Please set the JAVA_HOME variable in your environment to match the 88 | location of your Java installation." 89 | fi 90 | 91 | # Increase the maximum file descriptors if we can. 92 | if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then 93 | MAX_FD_LIMIT=`ulimit -H -n` 94 | if [ $? -eq 0 ] ; then 95 | if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then 96 | MAX_FD="$MAX_FD_LIMIT" 97 | fi 98 | ulimit -n $MAX_FD 99 | if [ $? -ne 0 ] ; then 100 | warn "Could not set maximum file descriptor limit: $MAX_FD" 101 | fi 102 | else 103 | warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" 104 | fi 105 | fi 106 | 107 | # For Darwin, add options to specify how the application appears in the dock 108 | if $darwin; then 109 | GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" 110 | fi 111 | 112 | # For Cygwin, switch paths to Windows format before running java 113 | if $cygwin ; then 114 | APP_HOME=`cygpath --path --mixed "$APP_HOME"` 115 | CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` 116 | JAVACMD=`cygpath --unix "$JAVACMD"` 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 | # Escape application args 158 | save () { 159 | for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done 160 | echo " " 161 | } 162 | APP_ARGS=$(save "$@") 163 | 164 | # Collect all arguments for the java command, following the shell quoting and substitution rules 165 | eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS" 166 | 167 | # by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong 168 | if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then 169 | cd "$(dirname "$0")" 170 | fi 171 | 172 | exec "$JAVACMD" "$@" 173 | -------------------------------------------------------------------------------- /app/src/main/java/com/draco/comatose/repositories/profiles/DeviceIdleConstantsProfiles.kt: -------------------------------------------------------------------------------- 1 | package com.draco.comatose.repositories.profiles 2 | 3 | import com.draco.comatose.repositories.constants.DeviceIdleConstants 4 | 5 | object DeviceIdleConstantsProfiles { 6 | val DEFAULT = null 7 | 8 | /** 9 | * - Instantly enter light idle 2 minutes after the screen turns off 10 | * - Give apps 2 minutes to prepare for idle 11 | * - Handle light idle maintenance once every 10 minutes initially 12 | * - Handle light idle maintenance once every hour at the latest 13 | * - Take at most 2 minutes to fetch a location 14 | * - Take a location within at least 50 meters 15 | * - Enter deep idle 10 minutes after the screen goes off 16 | * - Enter inactive mode 2 minutes after finishing sensor work 17 | * - Re-enter deep idle 5 minutes after the device stops moving again 18 | * - Re-enter deep idle 5 minute if we are in a pending idle state 19 | */ 20 | const val LIGHT = 21 | "${DeviceIdleConstants.LIGHT_AFTER_INACTIVE_TO}=${2 * 60 * 1000}," + 22 | "${DeviceIdleConstants.LIGHT_PRE_IDLE_TO}=${2 * 60 * 1000}," + 23 | "${DeviceIdleConstants.LIGHT_IDLE_TO}=${10 * 60 * 1000}," + 24 | "${DeviceIdleConstants.LIGHT_MAX_IDLE_TO}=${60 * 60 * 1000}," + 25 | "${DeviceIdleConstants.LOCATING_TO}=${2 * 60 * 1000}," + 26 | "${DeviceIdleConstants.LOCATION_ACCURACY}=${50}," + 27 | "${DeviceIdleConstants.INACTIVE_TO}=${10 * 60 * 1000}," + 28 | "${DeviceIdleConstants.SENSING_TO}=${2 * 60 * 1000}," + 29 | "${DeviceIdleConstants.MOTION_INACTIVE_TO}=${5 * 60 * 1000}," + 30 | "${DeviceIdleConstants.IDLE_AFTER_INACTIVE_TO}=${5 * 60 * 1000}" 31 | 32 | /** 33 | * - Instantly enter light idle 1 minute after the screen turns off 34 | * - Give apps 1 minute to prepare for idle 35 | * - Handle light idle maintenance once every 15 minutes initially 36 | * - Handle light idle maintenance once every 3 hours at the latest 37 | * - Take at most 1 minute to fetch a location 38 | * - Take a location within at least 100 meters 39 | * - Enter deep idle 1 minute after the screen goes off 40 | * - Enter inactive mode 1 minute after finishing sensor work 41 | * - Re-enter deep idle 1 minute after the device stops moving again 42 | * - Re-enter deep idle 1 minute if we are in a pending idle state 43 | * - Handle deep idle maintenance once every 2 hours initially 44 | * - Handle deep idle maintenance once every 8 hours at the latest 45 | * - Give apps 30 seconds to prepare for quick doze 46 | * - Wake up 30 minutes before an alarm 47 | */ 48 | const val MODERATE = 49 | "${DeviceIdleConstants.LIGHT_AFTER_INACTIVE_TO}=${60 * 1000}," + 50 | "${DeviceIdleConstants.LIGHT_PRE_IDLE_TO}=${60 * 1000}," + 51 | "${DeviceIdleConstants.LIGHT_IDLE_TO}=${15 * 60 * 1000}," + 52 | "${DeviceIdleConstants.LIGHT_MAX_IDLE_TO}=${3 * 60 * 60 * 1000}," + 53 | "${DeviceIdleConstants.LOCATING_TO}=${60 * 1000}," + 54 | "${DeviceIdleConstants.LOCATION_ACCURACY}=${100}," + 55 | "${DeviceIdleConstants.INACTIVE_TO}=${60 * 1000}," + 56 | "${DeviceIdleConstants.SENSING_TO}=${60 * 1000}," + 57 | "${DeviceIdleConstants.MOTION_INACTIVE_TO}=${60 * 1000}," + 58 | "${DeviceIdleConstants.IDLE_AFTER_INACTIVE_TO}=${60 * 1000}," + 59 | "${DeviceIdleConstants.IDLE_TO}=${2 * 60 * 60 * 1000}," + 60 | "${DeviceIdleConstants.MAX_IDLE_TO}=${8 * 60 * 60 * 1000}," + 61 | "${DeviceIdleConstants.QUICK_DOZE_DELAY_TO}=${30 * 1000}," + 62 | "${DeviceIdleConstants.MIN_TIME_TO_ALARM}=${30 * 60 * 1000}" 63 | 64 | /** 65 | * - Instantly enter light idle 5 seconds after the screen turns off 66 | * - Give apps 30 seconds to prepare for idle 67 | * - Handle light idle maintenance once every 30 minutes initially 68 | * - Handle light idle maintenance once every 6 hours at the latest 69 | * - Take at most 10 seconds to fetch a location 70 | * - Take a location within at least 500 meters 71 | * - Enter deep idle 30 seconds after the screen goes off 72 | * - Enter inactive mode 30 seconds after finishing sensor work 73 | * - Re-enter deep idle 30 seconds after the device stops moving again 74 | * - Re-enter deep idle 30 seconds if we are in a pending idle state 75 | * - Handle deep idle maintenance once every 4 hours initially 76 | * - Handle deep idle maintenance once every 12 hours at the latest 77 | * - Give apps 10 seconds to prepare for quick doze 78 | * - Wake up 10 minutes before an alarm 79 | */ 80 | const val HIGH = 81 | "${DeviceIdleConstants.LIGHT_AFTER_INACTIVE_TO}=${5 * 1000}," + 82 | "${DeviceIdleConstants.LIGHT_PRE_IDLE_TO}=${30 * 1000}," + 83 | "${DeviceIdleConstants.LIGHT_IDLE_TO}=${30 * 60 * 1000}," + 84 | "${DeviceIdleConstants.LIGHT_MAX_IDLE_TO}=${6 * 60 * 60 * 1000}," + 85 | "${DeviceIdleConstants.LOCATING_TO}=${10 * 1000}," + 86 | "${DeviceIdleConstants.LOCATION_ACCURACY}=${500}," + 87 | "${DeviceIdleConstants.INACTIVE_TO}=${30 * 1000}," + 88 | "${DeviceIdleConstants.SENSING_TO}=${30 * 1000}," + 89 | "${DeviceIdleConstants.MOTION_INACTIVE_TO}=${30 * 1000}," + 90 | "${DeviceIdleConstants.IDLE_AFTER_INACTIVE_TO}=${30 * 1000}," + 91 | "${DeviceIdleConstants.IDLE_TO}=${4 * 60 * 60 * 1000}," + 92 | "${DeviceIdleConstants.MAX_IDLE_TO}=${12 * 60 * 60 * 1000}," + 93 | "${DeviceIdleConstants.QUICK_DOZE_DELAY_TO}=${10 * 1000}," + 94 | "${DeviceIdleConstants.MIN_TIME_TO_ALARM}=${10 * 60 * 1000}" 95 | 96 | /** 97 | * - Instantly enter light idle as soon as screen goes off 98 | * - Give apps 5 seconds to prepare for idle 99 | * - Handle light idle maintenance once every 1 hour initially 100 | * - Handle light idle maintenance once every 12 hours at the latest 101 | * - Take at most 5 seconds to fetch a location 102 | * - Take a location within at least 1000 meters 103 | * - Instantly enter deep idle as soon as screen goes off 104 | * - Instantly enter inactive mode after finishing sensor work 105 | * - Re-enter deep idle as soon as the device stops moving again 106 | * - Instantly enter deep idle if we are in a pending idle state 107 | * - Handle deep idle maintenance once every 6 hours initially 108 | * - Handle deep idle maintenance once every 48 hours at the latest 109 | * - Give apps 5 seconds to prepare for quick doze 110 | * - Wake up 5 minutes before an alarm 111 | */ 112 | const val EXTREME = 113 | "${DeviceIdleConstants.LIGHT_AFTER_INACTIVE_TO}=${0}," + 114 | "${DeviceIdleConstants.LIGHT_PRE_IDLE_TO}=${5 * 1000}," + 115 | "${DeviceIdleConstants.LIGHT_IDLE_TO}=${60 * 60 * 1000}," + 116 | "${DeviceIdleConstants.LIGHT_MAX_IDLE_TO}=${12 * 60 * 60 * 1000}," + 117 | "${DeviceIdleConstants.LOCATING_TO}=${5 * 1000}," + 118 | "${DeviceIdleConstants.LOCATION_ACCURACY}=${1000}," + 119 | "${DeviceIdleConstants.INACTIVE_TO}=${0}," + 120 | "${DeviceIdleConstants.SENSING_TO}=${0}," + 121 | "${DeviceIdleConstants.MOTION_INACTIVE_TO}=${0}," + 122 | "${DeviceIdleConstants.IDLE_AFTER_INACTIVE_TO}=${0}," + 123 | "${DeviceIdleConstants.IDLE_TO}=${6 * 60 * 60 * 1000}," + 124 | "${DeviceIdleConstants.MAX_IDLE_TO}=${48 * 60 * 60 * 1000}," + 125 | "${DeviceIdleConstants.QUICK_DOZE_DELAY_TO}=${5 * 1000}," + 126 | "${DeviceIdleConstants.MIN_TIME_TO_ALARM}=${5 * 60 * 1000}" 127 | } 128 | --------------------------------------------------------------------------------