Compare commits

...

10 commits

Author SHA1 Message Date
Peter Cai 883ace4eb2 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.
2023-04-29 11:25:08 -04:00
Peter Cai 635ed267bb Correct battery animation 2023-04-29 11:24:35 -04:00
Peter Cai 7be74307eb Stop notification animation after playing 2023-04-29 11:18:27 -04:00
Peter Cai 8c7c507295 Set color for flashlight too 2023-04-26 15:12:26 -04:00
Peter Cai 76ba1dd0f8 Ignore release directory 2023-04-26 15:04:14 -04:00
Peter Cai 06f4ab7037 Make notifs settings more consistent 2023-04-26 14:38:20 -04:00
Peter Cai 4650e3d679 Self-grant notification access 2023-04-26 14:31:30 -04:00
Peter Cai 9210b09b7a Also listen the normal BOOT_COMPLETED event 2023-04-25 16:41:33 -04:00
Peter Cai 8a71254683 Self-add to power exemption list 2023-04-25 16:33:27 -04:00
Peter Cai b1b228cec0 Restore {start,stop}ServiceAsUser usage 2023-04-25 16:30:15 -04:00
6 changed files with 68 additions and 31 deletions

1
.gitignore vendored
View file

@ -11,3 +11,4 @@ local.properties
*.jks
*.keystore
keystore.properties
/release

View file

@ -24,6 +24,8 @@
<uses-permission android:name="android.permission.INTERACT_ACROSS_USERS" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<uses-permission android:name="android.permission.MANAGE_NOTIFICATION_LISTENERS" />
<uses-sdk
android:minSdkVersion="31"
@ -38,11 +40,10 @@
<receiver
android:name="net.typeblog.lunatic.BootCompletedReceiver"
android:exported="true"
android:permission="android.permission.RECEIVE_BOOT_COMPLETED">
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.LOCKED_BOOT_COMPLETED" />
<category android:name="android.intent.category.DEFAULT" />
<action android:name="android.intent.action.BOOT_COMPLETED" />
</intent-filter>
</receiver>

View file

@ -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);
}
}
@ -214,6 +215,8 @@ public final class AnimationManager {
} catch (InterruptedException e) {
mLEDManager.enableAllLEDs(false);
}
stopNotifications();
});
}
@ -228,6 +231,7 @@ public final class AnimationManager {
submit(() -> {
if (check(Constants.SpotlightMode.FLASHLIGHT)) {
mLEDManager.setColor(0xffffff);
mLEDManager.setBrightness((int) (Constants.BRIGHTNESS * 100));
mLEDManager.enableAllLEDs(true);
}

View file

@ -39,7 +39,6 @@ public class NotificationService extends NotificationListenerService {
private static final String TAG = "SpotlightNotification";
private static final boolean DEBUG = true;
private ArrayList<Integer> 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();
}
}
}

View file

@ -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)) {

View file

@ -18,8 +18,12 @@
package net.typeblog.lunatic.Utils;
import android.app.NotificationManager;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.os.PowerExemptionManager;
import android.os.UserHandle;
import android.util.Log;
import net.typeblog.lunatic.Constants.Constants;
@ -31,62 +35,101 @@ 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) {
PowerExemptionManager pem = context.getSystemService(PowerExemptionManager.class);
pem.addToPermanentAllowList("net.typeblog.lunatic");
// Self-grant notification access because why not :)
NotificationManager nm = context.getSystemService(NotificationManager.class);
try {
Method setNotificationListenerAccessGranted = NotificationManager.class.getMethod("setNotificationListenerAccessGranted",
ComponentName.class, boolean.class, boolean.class);
setNotificationListenerAccessGranted.invoke(nm, new ComponentName(context, NotificationService.class), true, true);
} catch (Exception e) {
throw new RuntimeException(e);
}
AnimationManager animationManager = new AnimationManager(context);
if (SettingsManager.isSpotlightEnabled(context)) {