diff --git a/.github/workflows/temp-quest-keepawake-build.yml b/.github/workflows/temp-quest-keepawake-build.yml new file mode 100644 index 0000000..f5e1f26 --- /dev/null +++ b/.github/workflows/temp-quest-keepawake-build.yml @@ -0,0 +1,29 @@ +name: Temp Quest KeepAwake APK +on: + pull_request: + branches: [main] + paths: + - 'quest-keepawake-build/**' + - '.github/workflows/temp-quest-keepawake-build.yml' +jobs: + build: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: actions/setup-java@v4 + with: + distribution: temurin + java-version: '17' + - uses: android-actions/setup-android@v3 + - uses: gradle/actions/setup-gradle@v4 + with: + gradle-version: '8.4' + - name: Install SDK 33 + run: sdkmanager 'platforms;android-33' 'build-tools;33.0.2' + - name: Build debug APK + run: gradle -p quest-keepawake-build assembleDebug --stacktrace + - uses: actions/upload-artifact@v4 + with: + name: QuestNavKeepAwake-always-on-debug + path: quest-keepawake-build/app/build/outputs/apk/debug/app-debug.apk + if-no-files-found: error diff --git a/quest-keepawake-build/app/build.gradle b/quest-keepawake-build/app/build.gradle new file mode 100644 index 0000000..f7dfe56 --- /dev/null +++ b/quest-keepawake-build/app/build.gradle @@ -0,0 +1,9 @@ +plugins { id 'com.android.application' } +android { + namespace 'com.questnav.keepawake' + compileSdk 33 + defaultConfig { applicationId 'com.questnav.keepawake'; minSdk 29; targetSdk 32; versionCode 2; versionName '1.1-always-on' } + buildTypes { release { minifyEnabled false }; debug { minifyEnabled false } } + compileOptions { sourceCompatibility JavaVersion.VERSION_17; targetCompatibility JavaVersion.VERSION_17 } + lint { abortOnError false } +} diff --git a/quest-keepawake-build/app/src/main/AndroidManifest.xml b/quest-keepawake-build/app/src/main/AndroidManifest.xml new file mode 100644 index 0000000..b456547 --- /dev/null +++ b/quest-keepawake-build/app/src/main/AndroidManifest.xml @@ -0,0 +1,17 @@ + + + + + + + + + + + + + + + + + diff --git a/quest-keepawake-build/app/src/main/java/com/questnav/keepawake/BootReceiver.java b/quest-keepawake-build/app/src/main/java/com/questnav/keepawake/BootReceiver.java new file mode 100644 index 0000000..19e6b1b --- /dev/null +++ b/quest-keepawake-build/app/src/main/java/com/questnav/keepawake/BootReceiver.java @@ -0,0 +1,3 @@ +package com.questnav.keepawake; +import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; +public class BootReceiver extends BroadcastReceiver { @Override public void onReceive(Context c, Intent i){ c.startForegroundService(new Intent(c, KeepAwakeService.class)); } } diff --git a/quest-keepawake-build/app/src/main/java/com/questnav/keepawake/KeepAwakeService.java b/quest-keepawake-build/app/src/main/java/com/questnav/keepawake/KeepAwakeService.java new file mode 100644 index 0000000..431c1a2 --- /dev/null +++ b/quest-keepawake-build/app/src/main/java/com/questnav/keepawake/KeepAwakeService.java @@ -0,0 +1,14 @@ +package com.questnav.keepawake; +import android.app.*; import android.content.*; import android.os.*; import android.provider.Settings; import android.util.Log; +public class KeepAwakeService extends Service { + private static final String TAG="KeepAwakeService", CHANNEL_ID="keepawake_channel"; private static final long INTERVAL_MS=2000; + private final Handler handler=new Handler(Looper.getMainLooper()); private boolean running; private PowerManager.WakeLock wakeLock; + private final Runnable keepAwakeRunnable=new Runnable(){ @Override public void run(){ if(!running)return; sendProxClose(); handler.postDelayed(this,INTERVAL_MS); }}; + @Override public void onCreate(){ super.onCreate(); } + @Override public int onStartCommand(Intent intent,int flags,int startId){ if(running)return START_STICKY; running=true; createChannel(); startForeground(1,new Notification.Builder(this,CHANNEL_ID).setContentTitle("Quest KeepAwake").setContentText("Always-on keep-awake is active").setSmallIcon(android.R.drawable.ic_lock_idle_lock).setOngoing(true).build()); PowerManager pm=(PowerManager)getSystemService(POWER_SERVICE); wakeLock=pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK,"QuestNavKeepAwake::StayAwake"); wakeLock.acquire(); applySettings(); sendProxClose(); handler.postDelayed(keepAwakeRunnable,INTERVAL_MS); Log.i(TAG,"Always-on service started"); return START_STICKY; } + @Override public void onDestroy(){ running=false; handler.removeCallbacks(keepAwakeRunnable); if(wakeLock!=null&&wakeLock.isHeld())wakeLock.release(); super.onDestroy(); } + @Override public IBinder onBind(Intent intent){ return null; } + private void applySettings(){ ContentResolver cr=getContentResolver(); try{Settings.System.putInt(cr,Settings.System.SCREEN_OFF_TIMEOUT,Integer.MAX_VALUE);}catch(Exception e){Log.w(TAG,"screen timeout",e);} try{Settings.Global.putInt(cr,Settings.Global.STAY_ON_WHILE_PLUGGED_IN,3);}catch(Exception e){Log.w(TAG,"stay on",e);} try{Settings.Secure.putInt(cr,"adaptive_sleep",-1); Settings.Secure.putInt(cr,"sleep_timeout",-1); Settings.Secure.putInt(cr,"wake_gesture_enabled",0);}catch(Exception e){Log.w(TAG,"secure settings",e);} } + private void sendProxClose(){ try{Intent i=new Intent("com.oculus.vrpowermanager.prox_close"); i.addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES); sendBroadcast(i); Log.d(TAG,"Sent prox_close");}catch(Exception e){Log.w(TAG,"prox_close",e);} } + private void createChannel(){ NotificationChannel c=new NotificationChannel(CHANNEL_ID,"KeepAwake Service",NotificationManager.IMPORTANCE_LOW); getSystemService(NotificationManager.class).createNotificationChannel(c); } +} diff --git a/quest-keepawake-build/app/src/main/java/com/questnav/keepawake/MainActivity.java b/quest-keepawake-build/app/src/main/java/com/questnav/keepawake/MainActivity.java new file mode 100644 index 0000000..d9c2d45 --- /dev/null +++ b/quest-keepawake-build/app/src/main/java/com/questnav/keepawake/MainActivity.java @@ -0,0 +1,5 @@ +package com.questnav.keepawake; +import android.app.Activity; import android.content.Intent; import android.os.Bundle; import android.widget.TextView; +public class MainActivity extends Activity { + @Override public void onCreate(Bundle b){ super.onCreate(b); startForegroundService(new Intent(this, KeepAwakeService.class)); TextView v=new TextView(this); v.setText("KeepAwake service is running.\nprox_close is sent every 2 seconds."); v.setTextSize(20); v.setPadding(32,32,32,32); setContentView(v); } +} diff --git a/quest-keepawake-build/build.gradle b/quest-keepawake-build/build.gradle new file mode 100644 index 0000000..cdf3806 --- /dev/null +++ b/quest-keepawake-build/build.gradle @@ -0,0 +1,3 @@ +plugins { + id 'com.android.application' version '8.1.4' apply false +} diff --git a/quest-keepawake-build/gradle.properties b/quest-keepawake-build/gradle.properties new file mode 100644 index 0000000..3c5e113 --- /dev/null +++ b/quest-keepawake-build/gradle.properties @@ -0,0 +1,2 @@ +org.gradle.jvmargs=-Xmx2048m -Dfile.encoding=UTF-8 +android.useAndroidX=true diff --git a/quest-keepawake-build/settings.gradle b/quest-keepawake-build/settings.gradle new file mode 100644 index 0000000..8f4955a --- /dev/null +++ b/quest-keepawake-build/settings.gradle @@ -0,0 +1,4 @@ +pluginManagement { repositories { google(); mavenCentral(); gradlePluginPortal() } } +dependencyResolutionManagement { repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS); repositories { google(); mavenCentral() } } +rootProject.name = 'QuestNavKeepAwake' +include ':app'