From b1b228cec0596157fabc2028d0bd24adf1d6f2c7 Mon Sep 17 00:00:00 2001 From: Peter Cai Date: Tue, 25 Apr 2023 16:30:15 -0400 Subject: [PATCH 01/10] Restore {start,stop}ServiceAsUser usage --- .../typeblog/lunatic/Utils/ServiceUtils.java | 47 +++++++++++++++---- 1 file changed, 37 insertions(+), 10 deletions(-) diff --git a/src/net/typeblog/lunatic/Utils/ServiceUtils.java b/src/net/typeblog/lunatic/Utils/ServiceUtils.java index ee332aa..0d56b0a 100644 --- a/src/net/typeblog/lunatic/Utils/ServiceUtils.java +++ b/src/net/typeblog/lunatic/Utils/ServiceUtils.java @@ -20,6 +20,7 @@ package net.typeblog.lunatic.Utils; import android.content.Context; import android.content.Intent; +import android.os.UserHandle; import android.util.Log; import net.typeblog.lunatic.Constants.Constants; @@ -31,59 +32,85 @@ import net.typeblog.lunatic.Services.FlashlightService; import net.typeblog.lunatic.Services.MusicService; import net.typeblog.lunatic.Services.NotificationService; +import java.lang.reflect.Field; +import java.lang.reflect.Method; + public final class ServiceUtils { private static final String TAG = "SpotlightServiceUtils"; private static final boolean DEBUG = true; + // Use reflection hack because Android Studio does not use our overridden framework.jar by default + private static void startServiceAsCurrentUser(Context context, Intent intent) { + try { + final Field currentField = UserHandle.class.getField("CURRENT"); + UserHandle current = (UserHandle) currentField.get(null); + final Method startServiceAsUser = Context.class.getMethod("startServiceAsUser", Intent.class, UserHandle.class); + startServiceAsUser.invoke(context, intent, current); + } catch (Exception e) { + throw new RuntimeException(e); + } + } + + private static void stopServiceAsCurrentUser(Context context, Intent intent) { + try { + final Field currentField = UserHandle.class.getField("CURRENT"); + UserHandle current = (UserHandle) currentField.get(null); + final Method stopServiceAsUser = Context.class.getMethod("stopServiceAsUser", Intent.class, UserHandle.class); + stopServiceAsUser.invoke(context, intent, current); + } catch (Exception e) { + throw new RuntimeException(e); + } + } + public static void startCallReceiverService(Context context) { if (DEBUG) Log.d(TAG, "Starting Spotlight call receiver service"); - context.startService(new Intent(context, CallReceiverService.class)); + startServiceAsCurrentUser(context, new Intent(context, CallReceiverService.class)); } protected static void stopCallReceiverService(Context context) { if (DEBUG) Log.d(TAG, "Stopping Spotlight call receiver service"); - context.stopService(new Intent(context, CallReceiverService.class)); + stopServiceAsCurrentUser(context, new Intent(context, CallReceiverService.class)); } public static void startChargingService(Context context) { if (DEBUG) Log.d(TAG, "Starting Spotlight charging service"); - context.startService(new Intent(context, ChargingService.class)); + startServiceAsCurrentUser(context, new Intent(context, ChargingService.class)); } protected static void stopChargingService(Context context) { if (DEBUG) Log.d(TAG, "Stopping Spotlight charging service"); - context.stopService(new Intent(context, ChargingService.class)); + stopServiceAsCurrentUser(context, new Intent(context, ChargingService.class)); } public static void startNotificationService(Context context) { if (DEBUG) Log.d(TAG, "Starting Spotlight notifs service"); - context.startService(new Intent(context, NotificationService.class)); + startServiceAsCurrentUser(context, new Intent(context, NotificationService.class)); } protected static void stopNotificationService(Context context) { if (DEBUG) Log.d(TAG, "Stopping Spotlight notifs service"); - context.stopService(new Intent(context, NotificationService.class)); + stopServiceAsCurrentUser(context, new Intent(context, NotificationService.class)); } public static void startFlashlightService(Context context) { if (DEBUG) Log.d(TAG, "Starting Spotlight flashlight service"); - context.startService(new Intent(context, FlashlightService.class)); + startServiceAsCurrentUser(context, new Intent(context, FlashlightService.class)); } protected static void stopFlashlightService(Context context) { if (DEBUG) Log.d(TAG, "Stopping Spotlight flashlight service"); - context.stopService(new Intent(context, FlashlightService.class)); + stopServiceAsCurrentUser(context, new Intent(context, FlashlightService.class)); } public static void startMusicService(Context context) { if (DEBUG) Log.d(TAG, "Starting Spotlight Music service"); - context.startService(new Intent(context, MusicService.class)); + startServiceAsCurrentUser(context, new Intent(context, MusicService.class)); } protected static void stopMusicService(Context context) { if (DEBUG) Log.d(TAG, "Stopping Spotlight Music service"); - context.stopService(new Intent(context, MusicService.class)); + stopServiceAsCurrentUser(context, new Intent(context, MusicService.class)); } public static void checkSpotlightService(Context context) { From 8a71254683109851cb840595b48a7a3fbee66328 Mon Sep 17 00:00:00 2001 From: Peter Cai Date: Tue, 25 Apr 2023 16:33:27 -0400 Subject: [PATCH 02/10] Self-add to power exemption list --- src/net/typeblog/lunatic/Utils/ServiceUtils.java | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/net/typeblog/lunatic/Utils/ServiceUtils.java b/src/net/typeblog/lunatic/Utils/ServiceUtils.java index 0d56b0a..90111b0 100644 --- a/src/net/typeblog/lunatic/Utils/ServiceUtils.java +++ b/src/net/typeblog/lunatic/Utils/ServiceUtils.java @@ -20,6 +20,7 @@ package net.typeblog.lunatic.Utils; import android.content.Context; import android.content.Intent; +import android.os.PowerExemptionManager; import android.os.UserHandle; import android.util.Log; @@ -114,6 +115,9 @@ public final class ServiceUtils { } public static void checkSpotlightService(Context context) { + PowerExemptionManager pem = context.getSystemService(PowerExemptionManager.class); + pem.addToPermanentAllowList("net.typeblog.lunatic"); + AnimationManager animationManager = new AnimationManager(context); if (SettingsManager.isSpotlightEnabled(context)) { From 9210b09b7aa4c0dcee49d888d5c990c4dc651ecc Mon Sep 17 00:00:00 2001 From: Peter Cai Date: Tue, 25 Apr 2023 16:41:33 -0400 Subject: [PATCH 03/10] Also listen the normal BOOT_COMPLETED event --- AndroidManifest.xml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/AndroidManifest.xml b/AndroidManifest.xml index 132c690..a2c7088 100644 --- a/AndroidManifest.xml +++ b/AndroidManifest.xml @@ -24,6 +24,7 @@ + + android:exported="true"> - + From 4650e3d679e59a3c85ab59986d49ce80d3ebb545 Mon Sep 17 00:00:00 2001 From: Peter Cai Date: Wed, 26 Apr 2023 14:31:30 -0400 Subject: [PATCH 04/10] Self-grant notification access --- AndroidManifest.xml | 1 + src/net/typeblog/lunatic/Utils/ServiceUtils.java | 12 ++++++++++++ 2 files changed, 13 insertions(+) diff --git a/AndroidManifest.xml b/AndroidManifest.xml index a2c7088..a5829d5 100644 --- a/AndroidManifest.xml +++ b/AndroidManifest.xml @@ -25,6 +25,7 @@ + Date: Wed, 26 Apr 2023 14:38:20 -0400 Subject: [PATCH 05/10] Make notifs settings more consistent --- src/net/typeblog/lunatic/Settings/SettingsFragment.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/net/typeblog/lunatic/Settings/SettingsFragment.java b/src/net/typeblog/lunatic/Settings/SettingsFragment.java index 1fa3bea..a36deda 100644 --- a/src/net/typeblog/lunatic/Settings/SettingsFragment.java +++ b/src/net/typeblog/lunatic/Settings/SettingsFragment.java @@ -105,7 +105,8 @@ public class SettingsFragment extends PreferenceFragment implements OnPreference final String preferenceKey = preference.getKey(); if (preferenceKey.equals(Constants.SPOTLIGHT_NOTIFS_ENABLE)) { - SettingsManager.setSpotlightNotifsEnabled(getActivity(), true); + mNotifsPreference.setChecked(SettingsManager.isSpotlightNotifsEnabled(getActivity())); + return false; } if (preferenceKey.equals(Constants.SPOTLIGHT_BRIGHTNESS)) { From 76ba1dd0f8c172e809e356fc3c2b68f805068821 Mon Sep 17 00:00:00 2001 From: Peter Cai Date: Wed, 26 Apr 2023 15:04:14 -0400 Subject: [PATCH 06/10] Ignore release directory --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index 93b01d7..b8589a9 100644 --- a/.gitignore +++ b/.gitignore @@ -11,3 +11,4 @@ local.properties *.jks *.keystore keystore.properties +/release \ No newline at end of file From 8c7c50729527e19134e5f549cbf031195e8a5bbe Mon Sep 17 00:00:00 2001 From: Peter Cai Date: Wed, 26 Apr 2023 15:12:26 -0400 Subject: [PATCH 07/10] Set color for flashlight too --- src/net/typeblog/lunatic/Manager/AnimationManager.java | 1 + 1 file changed, 1 insertion(+) diff --git a/src/net/typeblog/lunatic/Manager/AnimationManager.java b/src/net/typeblog/lunatic/Manager/AnimationManager.java index 1b0c56b..df36f9a 100644 --- a/src/net/typeblog/lunatic/Manager/AnimationManager.java +++ b/src/net/typeblog/lunatic/Manager/AnimationManager.java @@ -228,6 +228,7 @@ public final class AnimationManager { submit(() -> { if (check(Constants.SpotlightMode.FLASHLIGHT)) { + mLEDManager.setColor(0xffffff); mLEDManager.setBrightness((int) (Constants.BRIGHTNESS * 100)); mLEDManager.enableAllLEDs(true); } From 7be74307eb69ba63d7b78a7e600585b416669211 Mon Sep 17 00:00:00 2001 From: Peter Cai Date: Sat, 29 Apr 2023 11:18:27 -0400 Subject: [PATCH 08/10] Stop notification animation after playing --- src/net/typeblog/lunatic/Manager/AnimationManager.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/net/typeblog/lunatic/Manager/AnimationManager.java b/src/net/typeblog/lunatic/Manager/AnimationManager.java index df36f9a..1ab0c2b 100644 --- a/src/net/typeblog/lunatic/Manager/AnimationManager.java +++ b/src/net/typeblog/lunatic/Manager/AnimationManager.java @@ -214,6 +214,8 @@ public final class AnimationManager { } catch (InterruptedException e) { mLEDManager.enableAllLEDs(false); } + + stopNotifications(); }); } From 635ed267bb36ce51c5cc74c810057d3f0ce86a69 Mon Sep 17 00:00:00 2001 From: Peter Cai Date: Sat, 29 Apr 2023 11:24:35 -0400 Subject: [PATCH 09/10] Correct battery animation --- src/net/typeblog/lunatic/Manager/AnimationManager.java | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/net/typeblog/lunatic/Manager/AnimationManager.java b/src/net/typeblog/lunatic/Manager/AnimationManager.java index 1ab0c2b..d6a9ad9 100644 --- a/src/net/typeblog/lunatic/Manager/AnimationManager.java +++ b/src/net/typeblog/lunatic/Manager/AnimationManager.java @@ -122,6 +122,7 @@ public final class AnimationManager { public void playCharging() { StatusManager.setChargingLedsActive(true); submit(() -> { + final int num_leds = mLEDManager.getNumLEDs(); int solid_leds = 0; mLEDManager.enableAllLEDs(false); mLEDManager.setColor(0xffffff); @@ -131,17 +132,17 @@ public final class AnimationManager { while (check(Constants.SpotlightMode.CHARGING)) { int batteryLevel = getBatteryLevel(); if (oldBatteryLevel != batteryLevel) { - solid_leds = Integer.valueOf(batteryLevel / mLEDManager.getNumLEDs()); + solid_leds = (int) Math.floor(batteryLevel / 100.0d * num_leds); for (int i = 0; i < solid_leds; i++) { - mLEDManager.enableLED(i, true); + mLEDManager.enableLED(num_leds - i - 1, true); Thread.sleep(150); } oldBatteryLevel = batteryLevel; } if (100 - solid_leds * mLEDManager.getNumLEDs() > 0) { - mLEDManager.enableLED(solid_leds, true); + mLEDManager.enableLED(num_leds - solid_leds - 1, true); Thread.sleep(500); - mLEDManager.enableLED(solid_leds, false); + mLEDManager.enableLED(num_leds - solid_leds - 1, false); Thread.sleep(500); } } From 883ace4eb27ca86b430bdffedfa06abaf61805bc Mon Sep 17 00:00:00 2001 From: Peter Cai Date: Sat, 29 Apr 2023 11:25:08 -0400 Subject: [PATCH 10/10] Remove unnecessary notification tracking we don't need this whatsoever. We only play animations when the notification is posted, and that's all we ever do. Animating all the time while notifications are there is only annoying. --- .../lunatic/Services/NotificationService.java | 13 ------------- 1 file changed, 13 deletions(-) diff --git a/src/net/typeblog/lunatic/Services/NotificationService.java b/src/net/typeblog/lunatic/Services/NotificationService.java index 2260f93..d0829f9 100644 --- a/src/net/typeblog/lunatic/Services/NotificationService.java +++ b/src/net/typeblog/lunatic/Services/NotificationService.java @@ -39,7 +39,6 @@ public class NotificationService extends NotificationListenerService { private static final String TAG = "SpotlightNotification"; private static final boolean DEBUG = true; - private ArrayList mNotifications = new ArrayList<>(); private AnimationManager mAnimationManager; @Override @@ -87,19 +86,7 @@ public class NotificationService extends NotificationListenerService { && !Arrays.asList(Constants.APPSTOIGNORE).contains(packageName) && !Arrays.asList(Constants.NOTIFSTOIGNORE).contains(packageName + ":" + packageChannelID) && (packageImportance >= NotificationManager.IMPORTANCE_DEFAULT || packageImportance == -1)) { - mNotifications.add(sbn.getId()); mAnimationManager.playNotifications(); } } - - @Override - public void onNotificationRemoved(StatusBarNotification sbn){ - if (DEBUG) Log.d(TAG, "onNotificationRemoved: package:" + sbn.getPackageName() + " | channel id: " + sbn.getNotification().getChannelId() + " | id: " + sbn.getId()); - if (mNotifications.contains(sbn.getId())) { - mNotifications.remove((Integer) sbn.getId()); - } - if (mNotifications.isEmpty()) { - mAnimationManager.stopNotifications(); - } - } }