Finalize masquerade rootless functionality with Substratum [2/3]
Change-Id: I61639bfdf395a32b9bd705edb295520642cbd8b5
diff --git a/app/src/main/java/masquerade/substratum/services/JobService.java b/app/src/main/java/masquerade/substratum/services/JobService.java
index 3c1b859..20cf166 100644
--- a/app/src/main/java/masquerade/substratum/services/JobService.java
+++ b/app/src/main/java/masquerade/substratum/services/JobService.java
@@ -1,4 +1,3 @@
-
package masquerade.substratum.services;
import android.app.ActivityManager;
@@ -15,6 +14,7 @@
import android.content.IntentSender;
import android.content.om.IOverlayManager;
import android.content.om.OverlayInfo;
+import android.content.pm.IPackageDeleteObserver;
import android.content.pm.IPackageInstallObserver2;
import android.content.pm.IPackageManager;
import android.content.pm.PackageInstaller;
@@ -26,6 +26,7 @@
import android.media.RingtoneManager;
import android.os.Binder;
import android.os.Bundle;
+import android.os.Environment;
import android.os.FileUtils;
import android.os.Handler;
import android.os.HandlerThread;
@@ -81,12 +82,18 @@
public static final String JOB_TIME_KEY = "job_time_key";
public static final String INSTALL_LIST_KEY = "install_list";
public static final String UNINSTALL_LIST_KEY = "uninstall_list";
- public static final String WITH_RESTART_UI_KEY = "with_restart_ui";
public static final String BOOTANIMATION_FILE_NAME = "bootanimation_file_name";
public static final String FONTS_PID = "fonts_pid";
public static final String FONTS_FILENAME = "fonts_filename";
public static final String AUDIO_PID = "audio_pid";
public static final String AUDIO_FILENAME = "audio_filename";
+ public static final String ENABLE_LIST_KEY = "enable_list";
+ public static final String DISABLE_LIST_KEY = "disable_list";
+ public static final String PRIORITY_LIST_KEY = "priority_list";
+ public static final String SOURCE_FILE_KEY = "source_file";
+ public static final String DESTINATION_FILE_KEY = "destination_file";
+ public static final String WITH_DELETE_PARENT_KEY = "delete_parent";
+ public static final String PROFILE_NAME_KEY = "profile_name";
public static final String COMMAND_VALUE_JOB_COMPLETE = "job_complete";
public static final String COMMAND_VALUE_INSTALL = "install";
public static final String COMMAND_VALUE_UNINSTALL = "uninstall";
@@ -95,6 +102,13 @@
public static final String COMMAND_VALUE_BOOTANIMATION = "bootanimation";
public static final String COMMAND_VALUE_FONTS = "fonts";
public static final String COMMAND_VALUE_AUDIO = "audio";
+ public static final String COMMAND_VALUE_ENABLE = "enable";
+ public static final String COMMAND_VALUE_DISABLE = "disable";
+ public static final String COMMAND_VALUE_PRIORITY = "priority";
+ public static final String COMMAND_VALUE_COPY = "copy";
+ public static final String COMMAND_VALUE_MOVE = "move";
+ public static final String COMMAND_VALUE_DELETE = "delete";
+ public static final String COMMAND_VALUE_PROFILE = "profile";
private static IOverlayManager mOMS;
private static IPackageManager mPM;
@@ -104,6 +118,7 @@
private MainHandler mMainHandler;
private final List<Runnable> mJobQueue = new ArrayList<>(0);
private long mLastJobTime;
+ private boolean mIsRunning;
@Override
public void onCreate() {
@@ -121,11 +136,10 @@
return START_NOT_STICKY;
}
- // one job at a time please
- // if (isProcessing()) {
- // log("Got start command while still processing last job, aborting");
- // return START_NOT_STICKY;
- // }
+ // Don't run job if there is another running job
+ mIsRunning = false;
+ if (isProcessing()) mIsRunning = true;
+
// filter out duplicate intents
long jobTime = intent.getLongExtra(JOB_TIME_KEY, 1);
if (jobTime == 1 || jobTime == mLastJobTime) {
@@ -156,9 +170,7 @@
for (String _package : packages) {
jobs_to_add.add(new Remover(_package));
}
- if (intent.getBooleanExtra(WITH_RESTART_UI_KEY, false)) {
- jobs_to_add.add(new UiResetJob());
- }
+ if (shouldRestartUi(packages)) jobs_to_add.add(new UiResetJob());
} else if (TextUtils.equals(command, COMMAND_VALUE_RESTART_UI)) {
jobs_to_add.add(new UiResetJob());
} else if (TextUtils.equals(command, COMMAND_VALUE_CONFIGURATION_SHIM)) {
@@ -180,6 +192,44 @@
String fileName = intent.getStringExtra(AUDIO_FILENAME);
jobs_to_add.add(new SoundsJob(pid, fileName));
jobs_to_add.add(new UiResetJob());
+ } else if (TextUtils.equals(command, COMMAND_VALUE_ENABLE)) {
+ List<String> packages = intent.getStringArrayListExtra(ENABLE_LIST_KEY);
+ for (String _package : packages) {
+ jobs_to_add.add(new Enabler(_package));
+ }
+ if (shouldRestartUi(packages)) jobs_to_add.add(new UiResetJob());
+ } else if (TextUtils.equals(command, COMMAND_VALUE_DISABLE)) {
+ List<String> packages = intent.getStringArrayListExtra(DISABLE_LIST_KEY);
+ for (String _package : packages) {
+ jobs_to_add.add(new Disabler(_package));
+ }
+ if (shouldRestartUi(packages)) jobs_to_add.add(new UiResetJob());
+ } else if (TextUtils.equals(command, COMMAND_VALUE_PRIORITY)) {
+ List<String> packages = intent.getStringArrayListExtra(PRIORITY_LIST_KEY);
+ jobs_to_add.add(new PriorityJob(packages));
+ if (shouldRestartUi(packages)) jobs_to_add.add(new UiResetJob());
+ } else if (TextUtils.equals(command, COMMAND_VALUE_COPY)) {
+ String source = intent.getStringExtra(SOURCE_FILE_KEY);
+ String destination = intent.getStringExtra(DESTINATION_FILE_KEY);
+ jobs_to_add.add(new CopyJob(source, destination));
+ } else if (TextUtils.equals(command, COMMAND_VALUE_MOVE)) {
+ String source = intent.getStringExtra(SOURCE_FILE_KEY);
+ String destination = intent.getStringExtra(DESTINATION_FILE_KEY);
+ jobs_to_add.add(new MoveJob(source, destination));
+ } else if (TextUtils.equals(command, COMMAND_VALUE_DELETE)) {
+ String dir = intent.getStringExtra(SOURCE_FILE_KEY);
+ if (intent.getBooleanExtra(WITH_DELETE_PARENT_KEY, true)) {
+ jobs_to_add.add(new DeleteJob(dir));
+ } else {
+ for (File child : new File(dir).listFiles()) {
+ jobs_to_add.add(new DeleteJob(child.getAbsolutePath()));
+ }
+ }
+ } else if (TextUtils.equals(command, COMMAND_VALUE_PROFILE)) {
+ List<String> enable = intent.getStringArrayListExtra(ENABLE_LIST_KEY);
+ List<String> disable = intent.getStringArrayListExtra(DISABLE_LIST_KEY);
+ String profile = intent.getStringExtra(PROFILE_NAME_KEY);
+ jobs_to_add.add(new ProfileJob(profile, disable, enable));
}
if (jobs_to_add.size() > 0) {
@@ -233,7 +283,8 @@
private void install(String path, IPackageInstallObserver2 observer) {
try {
- getPM().installPackageAsUser(path, observer, PackageManager.INSTALL_REPLACE_EXISTING,
+ getPM().installPackageAsUser(path, observer,
+ PackageManager.INSTALL_REPLACE_EXISTING,
null,
UserHandle.USER_SYSTEM);
} catch (Exception e) {
@@ -241,22 +292,17 @@
}
}
- private void uninstall(String packageName) {
+ private void uninstall(String packageName, IPackageDeleteObserver observer) {
try {
- final LocalIntentReceiver receiver = new LocalIntentReceiver();
- getPM().getPackageInstaller().uninstall(packageName, null /* callerPackageName */, 0,
- receiver.getIntentSender(), UserHandle.USER_SYSTEM);
- final Intent result = receiver.getResult();
- final int status = result.getIntExtra(PackageInstaller.EXTRA_STATUS,
- PackageInstaller.STATUS_FAILURE);
+ getPM().deletePackageAsUser(packageName, observer, 0, UserHandle.USER_SYSTEM);
} catch (Exception e) {
e.printStackTrace();
}
}
- private void disableOverlay(String packageName) {
+ private void switchOverlay(String packageName, boolean enable) {
try {
- getOMS().setEnabled(packageName, false, UserHandle.USER_SYSTEM, false);
+ getOMS().setEnabled(packageName, enable, UserHandle.USER_SYSTEM, false);
} catch (RemoteException e) {
e.printStackTrace();
}
@@ -265,14 +311,25 @@
private boolean isOverlayEnabled(String packageName) {
boolean enabled = false;
try {
- OverlayInfo info = getOMS().getOverlayInfo(packageName, UserHandle.USER_ALL);
- enabled = info.isEnabled();
+ OverlayInfo info = getOMS().getOverlayInfo(packageName, UserHandle.USER_SYSTEM);
+ if (info != null) {
+ enabled = info.isEnabled();
+ } else {
+ log("info is null");
+ }
} catch (RemoteException e) {
e.printStackTrace();
}
return enabled;
}
+ private boolean shouldRestartUi(List<String> overlays) {
+ for (String o : overlays) {
+ if (o.startsWith("com.android.systemui")) return true;
+ }
+ return false;
+ }
+
private void copyFonts(String pid, String zipFileName) {
// prepare local cache dir for font package assembly
log("Copy Fonts - Package ID = " + pid + " filename = " + zipFileName);
@@ -328,23 +385,26 @@
IOUtils.createFontDirIfNotExists();
IOUtils.copyFolder(cacheDir.getAbsolutePath(), IOUtils.SYSTEM_THEME_FONT_PATH);
- // set permissions on font files and config xml
- File themeFonts = new File(IOUtils.SYSTEM_THEME_FONT_PATH);
- for (File f : themeFonts.listFiles()) {
- FileUtils.setPermissions(f,
- FileUtils.S_IRWXU | FileUtils.S_IRGRP | FileUtils.S_IRWXO, -1, -1);
- }
-
// let system know it's time for a font change
- SystemProperties.set("sys.refresh_theme", "1");
- float fontSize = Float.valueOf(Settings.System.getString(
- getContentResolver(), Settings.System.FONT_SCALE));
- Settings.System.putString(getContentResolver(),
- Settings.System.FONT_SCALE, String.valueOf(fontSize + 0.0000001));
+ refreshFonts();
}
private void clearFonts() {
IOUtils.deleteThemedFonts();
+ refreshFonts();
+ }
+
+ private void refreshFonts() {
+ // set permissions on font files and config xml
+ File themeFonts = new File(IOUtils.SYSTEM_THEME_FONT_PATH);
+ if (themeFonts.exists()) {
+ // Set permissions
+ IOUtils.setPermissionsRecursive(themeFonts,
+ FileUtils.S_IRWXU | FileUtils.S_IRGRP | FileUtils.S_IRWXO,
+ FileUtils.S_IRWXU | FileUtils.S_IRWXG | FileUtils.S_IROTH | FileUtils.S_IXOTH);
+ }
+
+ // let system know it's time for a font change
SystemProperties.set("sys.refresh_theme", "1");
Typeface.recreateDefaults();
float fontSize = Float.valueOf(Settings.System.getString(
@@ -395,56 +455,29 @@
File effect_tick_ogg = new File(getCacheDir(), "/SoundsCache/ui/Effect_Tick.ogg");
if (effect_tick_ogg.exists()) {
IOUtils.bufferedCopy(effect_tick_ogg, new File(IOUtils.SYSTEM_THEME_UI_SOUNDS_PATH + File.separator + "Effect_Tick.ogg"));
- SoundUtils.setUIAudible(this, effect_tick_ogg, new File
- ("/data/system/theme/audio/ui/Effect_Tick.ogg"), RingtoneManager
- .TYPE_RINGTONE, "Effect_Tick");
} else if (effect_tick_mp3.exists()) {
IOUtils.bufferedCopy(effect_tick_mp3, new File(IOUtils.SYSTEM_THEME_UI_SOUNDS_PATH + File.separator + "Effect_Tick.mp3"));
- SoundUtils.setUIAudible(this, effect_tick_mp3, new File
- ("/data/system/theme/audio/ui/Effect_Tick.mp3"), RingtoneManager
- .TYPE_RINGTONE, "Effect_Tick");
- } else {
- SoundUtils.setDefaultUISounds(getContentResolver(), "lock_sound", "Lock.ogg");
}
File new_lock_mp3 = new File(getCacheDir(), "/SoundsCache/ui/Lock.mp3");
File new_lock_ogg = new File(getCacheDir(), "/SoundsCache/ui/Lock.ogg");
if (new_lock_ogg.exists()) {
IOUtils.bufferedCopy(new_lock_ogg, new File(IOUtils.SYSTEM_THEME_UI_SOUNDS_PATH + File.separator + "Lock.ogg"));
- SoundUtils.setUISounds(getContentResolver(), "lock_sound", "/data/system/theme/audio/ui/Lock.ogg");
} else if (new_lock_mp3.exists()) {
IOUtils.bufferedCopy(new_lock_mp3, new File(IOUtils.SYSTEM_THEME_UI_SOUNDS_PATH + File.separator + "Lock.mp3"));
- SoundUtils.setUISounds(getContentResolver(), "lock_sound", "/data/system/theme/audio/ui/Lock.mp3");
- } else {
- SoundUtils.setDefaultUISounds(getContentResolver(), "lock_sound", "Lock.ogg");
}
File new_unlock_mp3 = new File(getCacheDir(), "/SoundsCache/ui/Unlock.mp3");
File new_unlock_ogg = new File(getCacheDir(), "/SoundsCache/ui/Unlock.ogg");
if (new_unlock_ogg.exists()) {
IOUtils.bufferedCopy(new_unlock_ogg, new File(IOUtils.SYSTEM_THEME_UI_SOUNDS_PATH + File.separator + "Unlock.ogg"));
- SoundUtils.setUISounds(getContentResolver(), "unlock_sound", "/data/system/theme/audio/ui/Unlock.ogg");
} else if (new_unlock_mp3.exists()) {
IOUtils.bufferedCopy(new_unlock_mp3, new File(IOUtils.SYSTEM_THEME_UI_SOUNDS_PATH + File.separator + "Unlock.mp3"));
- SoundUtils.setUISounds(getContentResolver(), "unlock_sound", "/data/system/theme/audio/ui/Unlock.mp3");
- } else {
- SoundUtils.setDefaultUISounds(getContentResolver(), "unlock_sound", "Unlock.ogg");
}
File new_lowbattery_mp3 = new File(getCacheDir(), "/SoundsCache/ui/LowBattery.mp3");
File new_lowbattery_ogg = new File(getCacheDir(), "/SoundsCache/ui/LowBattery.ogg");
if (new_lowbattery_ogg.exists()) {
IOUtils.bufferedCopy(new_lowbattery_ogg, new File(IOUtils.SYSTEM_THEME_UI_SOUNDS_PATH + File.separator + "LowBattery.ogg"));
- SoundUtils.setUISounds(getContentResolver(), "low_battery_sound", "/data/system/theme/audio/ui/LowBattery.ogg");
} else if (new_lowbattery_mp3.exists()) {
IOUtils.bufferedCopy(new_lowbattery_mp3, new File(IOUtils.SYSTEM_THEME_UI_SOUNDS_PATH + File.separator + "LowBattery.mp3"));
- SoundUtils.setUISounds(getContentResolver(), "low_battery_sound", "/data/system/theme/audio/ui/LowBattery.mp3");
- } else {
- SoundUtils.setDefaultUISounds(getContentResolver(), "low_battery_sound", "LowBattery.ogg");
- }
- File uiSounds = new File(IOUtils.SYSTEM_THEME_UI_SOUNDS_PATH);
- if (uiSounds.exists() && uiSounds.isDirectory()) {
- for (File f : uiSounds.listFiles()) {
- FileUtils.setPermissions(f,
- FileUtils.S_IRWXU | FileUtils.S_IRGRP | FileUtils.S_IRWXO, -1, -1);
- }
}
}
File alarmCache = new File(getCacheDir(), "/SoundsCache/alarms/");
@@ -454,27 +487,8 @@
File new_alarm_ogg = new File(getCacheDir(), "/SoundsCache/alarms/alarm.ogg");
if (new_alarm_ogg.exists()) {
IOUtils.bufferedCopy(new_alarm_ogg, new File(IOUtils.SYSTEM_THEME_ALARM_PATH + File.separator + "alarm.ogg"));
- int metaDataId = getSubsContext().getResources().getIdentifier("content_resolver_alarm_metadata", "string", SUBSTRATUM_PACKAGE);
- SoundUtils.setAudible(this, new File("/data/system/theme/audio/alarms/alarm.ogg"),
- new File(alarmCache.getAbsolutePath(), "alarm.ogg"),
- RingtoneManager.TYPE_ALARM,
- getSubsContext().getString(metaDataId));
} else if (new_alarm_mp3.exists()) {
IOUtils.bufferedCopy(new_alarm_mp3, new File(IOUtils.SYSTEM_THEME_ALARM_PATH + File.separator + "alarm.mp3"));
- int metaDataId = getSubsContext().getResources().getIdentifier("content_resolver_alarm_metadata", "string", SUBSTRATUM_PACKAGE);
- SoundUtils.setAudible(this, new File("/data/system/theme/audio/alarms/alarm.mp3"),
- new File(alarmCache.getAbsolutePath(), "alarm.mp3"),
- RingtoneManager.TYPE_ALARM,
- getSubsContext().getString(metaDataId));
- } else {
- SoundUtils.setDefaultAudible(this, RingtoneManager.TYPE_ALARM);
- }
- File alarms = new File(IOUtils.SYSTEM_THEME_ALARM_PATH);
- if (alarms.exists() && alarms.isDirectory()) {
- for (File f : alarms.listFiles()) {
- FileUtils.setPermissions(f,
- FileUtils.S_IRWXU | FileUtils.S_IRGRP | FileUtils.S_IRWXO, -1, -1);
- }
}
}
File notifCache = new File(getCacheDir(), "/SoundsCache/notifications/");
@@ -484,27 +498,8 @@
File new_notif_ogg = new File(getCacheDir(), "/SoundsCache/notifications/notification.ogg");
if (new_notif_ogg.exists()) {
IOUtils.bufferedCopy(new_notif_ogg, new File(IOUtils.SYSTEM_THEME_NOTIFICATION_PATH + File.separator + "notification.ogg"));
- int metaDataId = getSubsContext().getResources().getIdentifier("content_resolver_notification_metadata", "string", SUBSTRATUM_PACKAGE);
- SoundUtils.setAudible(this, new File("/data/system/theme/audio/notifications/notification.ogg"),
- new File(notifCache.getAbsolutePath(), "notification.ogg"),
- RingtoneManager.TYPE_NOTIFICATION,
- getSubsContext().getString(metaDataId));
} else if (new_notif_mp3.exists()) {
IOUtils.bufferedCopy(new_notif_mp3, new File(IOUtils.SYSTEM_THEME_NOTIFICATION_PATH + File.separator + "notification.mp3"));
- int metaDataId = getSubsContext().getResources().getIdentifier("content_resolver_notification_metadata", "string", SUBSTRATUM_PACKAGE);
- SoundUtils.setAudible(this, new File("/data/system/theme/audio/notifications/notification.mp3"),
- new File(notifCache.getAbsolutePath(), "notification.mp3"),
- RingtoneManager.TYPE_NOTIFICATION,
- getSubsContext().getString(metaDataId));
- } else {
- SoundUtils.setDefaultAudible(this, RingtoneManager.TYPE_NOTIFICATION);
- }
- File notifs = new File(IOUtils.SYSTEM_THEME_NOTIFICATION_PATH);
- if (notifs.exists() && notifs.isDirectory()) {
- for (File f : notifs.listFiles()) {
- FileUtils.setPermissions(f,
- FileUtils.S_IRWXU | FileUtils.S_IRGRP | FileUtils.S_IRWXO, -1, -1);
- }
}
}
File ringtoneCache = new File(getCacheDir(), "/SoundsCache/ringtones/");
@@ -514,29 +509,13 @@
File new_ring_ogg = new File(getCacheDir(), "/SoundsCache/ringtones/ringtone.ogg");
if (new_ring_ogg.exists()) {
IOUtils.bufferedCopy(new_ring_ogg, new File(IOUtils.SYSTEM_THEME_RINGTONE_PATH + File.separator + "ringtone.ogg"));
- int metaDataId = getSubsContext().getResources().getIdentifier("content_resolver_ringtone_metadata", "string", SUBSTRATUM_PACKAGE);
- SoundUtils.setAudible(this, new File("/data/system/theme/audio/ringtones/ringtone.ogg"),
- new File(notifCache.getAbsolutePath(), "ringtone.ogg"),
- RingtoneManager.TYPE_RINGTONE,
- getSubsContext().getString(metaDataId));
} else if (new_ring_mp3.exists()) {
IOUtils.bufferedCopy(new_ring_mp3, new File(IOUtils.SYSTEM_THEME_RINGTONE_PATH + File.separator + "ringtone.mp3"));
- int metaDataId = getSubsContext().getResources().getIdentifier("content_resolver_ringtone_metadata", "string", SUBSTRATUM_PACKAGE);
- SoundUtils.setAudible(this, new File("/data/system/theme/audio/ringtones/ringtone.mp3"),
- new File(notifCache.getAbsolutePath(), "ringtone.mp3"),
- RingtoneManager.TYPE_RINGTONE,
- getSubsContext().getString(metaDataId));
- } else {
- SoundUtils.setDefaultAudible(this, RingtoneManager.TYPE_RINGTONE);
- }
- File rings = new File(IOUtils.SYSTEM_THEME_RINGTONE_PATH);
- if (rings.exists() && rings.isDirectory()) {
- for (File f : rings.listFiles()) {
- FileUtils.setPermissions(f,
- FileUtils.S_IRWXU | FileUtils.S_IRGRP | FileUtils.S_IRWXO, -1, -1);
- }
}
}
+
+ // let system know it's time for a sound change
+ refreshSounds();
}
private void clearSounds(Context ctx) {
@@ -550,6 +529,121 @@
"LowBattery.ogg");
}
+ private void refreshSounds () {
+ File soundsDir = new File(IOUtils.SYSTEM_THEME_AUDIO_PATH);
+ if (soundsDir.exists()) {
+ // Set permissions
+ IOUtils.setPermissionsRecursive(soundsDir,
+ FileUtils.S_IRWXU | FileUtils.S_IRGRP | FileUtils.S_IRWXO,
+ FileUtils.S_IRWXU | FileUtils.S_IRWXG | FileUtils.S_IROTH | FileUtils.S_IXOTH);
+
+ File uiDir = new File(IOUtils.SYSTEM_THEME_UI_SOUNDS_PATH);
+ if (uiDir.exists()) {
+ File effect_tick_mp3 = new File(uiDir, "Effect_Tick.mp3");
+ File effect_tick_ogg = new File(uiDir, "Effect_Tick.ogg");
+ if (effect_tick_mp3.exists()) {
+ SoundUtils.setUIAudible(this, effect_tick_mp3,
+ effect_tick_mp3, RingtoneManager.TYPE_RINGTONE,
+ "Effect_Tick");
+ } else if (effect_tick_ogg.exists()) {
+ SoundUtils.setUIAudible(this, effect_tick_ogg,
+ effect_tick_ogg, RingtoneManager.TYPE_RINGTONE,
+ "Effect_Tick");
+ } else {
+ SoundUtils.setDefaultUISounds(getContentResolver(),
+ "Effect_Tick",
+ "Effect_Tick.ogg");
+ }
+
+ File lock_mp3 = new File(uiDir, "Lock.mp3");
+ File lock_ogg = new File(uiDir, "Lock.ogg");
+ if (lock_mp3.exists()) {
+ SoundUtils.setUISounds(getContentResolver(), "lock_sound",
+ lock_mp3.getAbsolutePath());
+ } else if (lock_ogg.exists()) {
+ SoundUtils.setUISounds(getContentResolver(), "lock_sound",
+ lock_ogg.getAbsolutePath());
+ } else {
+ SoundUtils.setDefaultUISounds(getContentResolver(),
+ "lock_sound", "Lock.ogg");
+ }
+
+ File unlock_mp3 = new File(uiDir, "Unlock.mp3");
+ File unlock_ogg = new File(uiDir, "Unlock.ogg");
+ if (unlock_mp3.exists()) {
+ SoundUtils.setUISounds(getContentResolver(), "unlock_sound",
+ unlock_mp3.getAbsolutePath());
+ } else if (unlock_ogg.exists()) {
+ SoundUtils.setUISounds(getContentResolver(), "unlock_sound",
+ unlock_ogg.getAbsolutePath());
+ } else {
+ SoundUtils.setDefaultUISounds(getContentResolver(),
+ "unlock_sound", "Unlock.ogg");
+ }
+
+ File lowbattery_mp3 = new File(uiDir, "LowBattery.mp3");
+ File lowbattery_ogg = new File(uiDir, "LowBattery.ogg");
+ if (lowbattery_mp3.exists()) {
+ SoundUtils.setUISounds(getContentResolver(), "low_battery_sound",
+ lowbattery_mp3.getAbsolutePath());
+ } else if (lowbattery_ogg.exists()) {
+ SoundUtils.setUISounds(getContentResolver(), "low_battery_sound",
+ lowbattery_ogg.getAbsolutePath());
+ } else {
+ SoundUtils.setDefaultUISounds(getContentResolver(),
+ "low_battery_sound", "LowBattery.ogg");
+ }
+ }
+
+ File notifDir = new File(IOUtils.SYSTEM_THEME_NOTIFICATION_PATH);
+ if (notifDir.exists()) {
+ int metaDataId = getSubsContext().getResources().getIdentifier(
+ "content_resolver_notification_metadata",
+ "string", SUBSTRATUM_PACKAGE);
+
+ File notification_mp3 = new File(notifDir, "notification.mp3");
+ File notification_ogg = new File(notifDir, "notification.ogg");
+ if (notification_mp3.exists()) {
+ SoundUtils.setAudible(this, notification_mp3,
+ notification_mp3,
+ RingtoneManager.TYPE_NOTIFICATION,
+ getSubsContext().getString(metaDataId));
+ } else if (notification_ogg.exists()) {
+ SoundUtils.setAudible(this, notification_ogg,
+ notification_ogg,
+ RingtoneManager.TYPE_NOTIFICATION,
+ getSubsContext().getString(metaDataId));
+ } else {
+ SoundUtils.setDefaultAudible(this,
+ RingtoneManager.TYPE_NOTIFICATION);
+ }
+ }
+
+ File ringtoneDir = new File(IOUtils.SYSTEM_THEME_RINGTONE_PATH);
+ if (ringtoneDir.exists()) {
+ int metaDataId = getSubsContext().getResources().getIdentifier(
+ "content_resolver_notification_metadata",
+ "string", SUBSTRATUM_PACKAGE);
+
+ File ringtone_mp3 = new File(ringtoneDir, "ringtone.mp3");
+ File ringtone_ogg = new File(ringtoneDir, "ringtone.ogg");
+ if (ringtone_mp3.exists()) {
+ SoundUtils.setAudible(this, ringtone_mp3,
+ ringtone_mp3,
+ RingtoneManager.TYPE_RINGTONE,
+ getSubsContext().getString(metaDataId));
+ } else if (ringtone_ogg.exists()) {
+ SoundUtils.setAudible(this, ringtone_ogg,
+ ringtone_ogg,
+ RingtoneManager.TYPE_RINGTONE,
+ getSubsContext().getString(metaDataId));
+ } else {
+ SoundUtils.setDefaultAudible(this,
+ RingtoneManager.TYPE_RINGTONE);
+ }
+ }
+ }
+ }
private void copyBootAnimation(String fileName) {
try {
clearBootAnimation();
@@ -557,8 +651,8 @@
File dest = new File(IOUtils.SYSTEM_THEME_BOOTANIMATION_PATH);
IOUtils.bufferedCopy(source, dest);
source.delete();
- FileUtils.setPermissions(IOUtils.SYSTEM_THEME_BOOTANIMATION_PATH,
- FileUtils.S_IRWXU | FileUtils.S_IRGRP | FileUtils.S_IROTH, -1, -1);
+ IOUtils.setPermissions(dest,
+ FileUtils.S_IRWXU | FileUtils.S_IRGRP | FileUtils.S_IROTH);
} catch (Exception e) {
e.printStackTrace();
}
@@ -689,7 +783,7 @@
synchronized (mJobQueue) {
job = mJobQueue.get(0);
}
- if (job != null) {
+ if (job != null && !mIsRunning) {
job.run();
}
break;
@@ -698,8 +792,10 @@
synchronized (mJobQueue) {
mJobQueue.remove(toRemove);
if (mJobQueue.size() > 0) {
+ mIsRunning = false;
this.sendEmptyMessage(MESSAGE_CHECK_QUEUE);
} else {
+ mIsRunning = false;
log("Job queue empty! All done");
mMainHandler.sendEmptyMessage(MainHandler.MSG_JOB_QUEUE_EMPTY);
}
@@ -835,7 +931,7 @@
}
}
- private class Installer implements Runnable, IPackageInstallObserver2 {
+ private class Installer implements Runnable {
String mPath;
public Installer(String path) {
@@ -843,27 +939,28 @@
}
@Override
- public IBinder asBinder() {
- return null;
- }
-
- @Override
- public void onUserActionRequired(Intent intent) throws RemoteException {
- log("Installer - user action required callback with " + mPath);
- }
-
- @Override
- public void onPackageInstalled(String basePackageName, int returnCode, String msg,
- Bundle extras) throws RemoteException {
- log("Installer - successfully installed " + basePackageName + " from " + mPath);
- Message message = mJobHandler.obtainMessage(JobHandler.MESSAGE_DEQUEUE, Installer.this);
- mJobHandler.sendMessage(message);
- }
-
- @Override
public void run() {
log("Installer - installing " + mPath);
- install(mPath, this);
+ PackageInstallObserver observer = new PackageInstallObserver(Installer.this);
+ install(mPath, observer);
+ }
+ }
+
+ private class PackageInstallObserver extends IPackageInstallObserver2.Stub {
+ Object mObject;
+
+ public PackageInstallObserver(Object _object) {
+ mObject = _object;
+ }
+
+ public void onUserActionRequired(Intent intent) throws RemoteException {
+ log("Installer - user action required callback");
+ }
+
+ public void onPackageInstalled(String packageName, int returnCode, String msg, Bundle extras) {
+ log("Installer - successfully installed " + packageName);
+ Message message = mJobHandler.obtainMessage(JobHandler.MESSAGE_DEQUEUE, mObject);
+ mJobHandler.sendMessage(message);
}
}
@@ -876,12 +973,242 @@
@Override
public void run() {
+
+ // TODO: Fix isOverlayEnabled function, for now it's causing NPE
if (isOverlayEnabled(mPackage)) {
log("Remover - disabling overlay for " + mPackage);
- disableOverlay(mPackage);
+ switchOverlay(mPackage, false);
}
+
log("Remover - uninstalling " + mPackage);
- uninstall(mPackage);
+ PackageDeleteObserver observer = new PackageDeleteObserver(Remover.this);
+ uninstall(mPackage, observer);
+ }
+ }
+
+ private class PackageDeleteObserver extends IPackageDeleteObserver.Stub {
+ Object mObject;
+
+ public PackageDeleteObserver(Object _object) {
+ mObject = _object;
+ }
+
+ public void packageDeleted(String packageName, int returnCode) {
+ log("Remover - successfully removed " + packageName);
+ Message message = mJobHandler.obtainMessage(JobHandler.MESSAGE_DEQUEUE, mObject);
+ mJobHandler.sendMessage(message);
+ }
+ }
+
+ private class Enabler implements Runnable {
+ String mPackage;
+
+ public Enabler(String _package) {
+ mPackage = _package;
+ }
+
+ @Override
+ public void run() {
+ log("Enabler - enabling overlay for " + mPackage);
+ switchOverlay(mPackage, true);
+ Message message = mJobHandler.obtainMessage(JobHandler.MESSAGE_DEQUEUE,
+ Enabler.this);
+ mJobHandler.sendMessage(message);
+ }
+ }
+
+ private class Disabler implements Runnable {
+ String mPackage;
+
+ public Disabler(String _package) {
+ mPackage = _package;
+ }
+
+ @Override
+ public void run() {
+ log("Disabler - disabling overlay for " + mPackage);
+ switchOverlay(mPackage, false);
+ Message message = mJobHandler.obtainMessage(JobHandler.MESSAGE_DEQUEUE,
+ Disabler.this);
+ mJobHandler.sendMessage(message);
+ }
+ }
+
+ private class PriorityJob implements Runnable {
+ List<String> mPackages;
+
+ public PriorityJob(List<String> _packages) {
+ mPackages = _packages;
+ }
+
+ @Override
+ public void run() {
+ log("PriorityJob - processing priority changes");
+ try {
+ int size = mPackages.size();
+ for (int i = 0; i < size-1; i++) {
+ String parentName = mPackages.get(i);
+ String packageName = mPackages.get(i+1);
+ getOMS().setPriority(packageName, parentName, UserHandle.USER_SYSTEM);
+ }
+ } catch (RemoteException e) {
+ e.printStackTrace();
+ }
+ Message message = mJobHandler.obtainMessage(JobHandler.MESSAGE_DEQUEUE,
+ PriorityJob.this);
+ mJobHandler.sendMessage(message);
+ }
+ }
+
+ private class CopyJob implements Runnable {
+ String mSource;
+ String mDestination;
+
+ public CopyJob(String _source, String _destination) {
+ mSource = _source;
+ mDestination = _destination;
+ }
+
+ @Override
+ public void run() {
+ log("CopyJob - copying " + mSource + " to " + mDestination);
+ File sourceFile = new File(mSource);
+ if (sourceFile.exists()) {
+ if (sourceFile.isFile()) {
+ IOUtils.bufferedCopy(mSource, mDestination);
+ } else {
+ IOUtils.copyFolder(mSource, mDestination);
+ }
+ } else {
+ log("CopyJob - " + mSource + " is not exist! aborting...");
+ }
+ Message message = mJobHandler.obtainMessage(JobHandler.MESSAGE_DEQUEUE,
+ CopyJob.this);
+ mJobHandler.sendMessage(message);
+ }
+ }
+
+ private class MoveJob implements Runnable {
+ String mSource;
+ String mDestination;
+
+ public MoveJob(String _source, String _destination) {
+ mSource = _source;
+ mDestination = _destination;
+ }
+
+ @Override
+ public void run() {
+ log("MoveJob - moving " + mSource + " to " + mDestination);
+ File sourceFile = new File(mSource);
+ if (sourceFile.exists()) {
+ if (sourceFile.isFile()) {
+ IOUtils.bufferedCopy(mSource, mDestination);
+ } else {
+ IOUtils.copyFolder(mSource, mDestination);
+ }
+ IOUtils.deleteRecursive(sourceFile);
+ } else {
+ log("MoveJob - " + mSource + " is not exist! aborting...");
+ }
+ Message message = mJobHandler.obtainMessage(JobHandler.MESSAGE_DEQUEUE,
+ MoveJob.this);
+ mJobHandler.sendMessage(message);
+ }
+ }
+
+ private class DeleteJob implements Runnable {
+ String mFileOrDirectory;
+
+ public DeleteJob(String _directory) {
+ mFileOrDirectory = _directory;
+ }
+
+ @Override
+ public void run() {
+ log("DeleteJob - deleting " + mFileOrDirectory);
+ File file = new File(mFileOrDirectory);
+ if (file.exists()) {
+ IOUtils.deleteRecursive(file);
+ } else {
+ log("DeleteJob - " + mFileOrDirectory + " is already deleted!");
+ }
+ Message message = mJobHandler.obtainMessage(JobHandler.MESSAGE_DEQUEUE,
+ DeleteJob.this);
+ mJobHandler.sendMessage(message);
+ }
+ }
+
+ private class ProfileJob implements Runnable {
+ String mProfileName;
+ List<String> mToBeDisabled;
+ List<String> mToBeEnabled;
+
+ public ProfileJob(String _name, List<String> _toBeDisabled, List<String> _toBeEnabled) {
+ mProfileName = _name;
+ mToBeDisabled = _toBeDisabled;
+ mToBeEnabled = _toBeEnabled;
+ }
+
+ @Override
+ public void run() {
+ boolean restartUi = false;
+ log("Applying profile...");
+
+ // Need to restart SystemUI?
+ restartUi = shouldRestartUi(mToBeEnabled) || shouldRestartUi(mToBeDisabled);
+
+ // Clear system theme folder content
+ File themeDir = new File(IOUtils.SYSTEM_THEME_PATH);
+ for (File f : themeDir.listFiles()) {
+ IOUtils.deleteRecursive(f);
+ }
+
+ // Process theme folder
+ File profileDir = new File(Environment.getExternalStorageDirectory()
+ .getAbsolutePath() + "/substratum/profiles/" +
+ mProfileName + "/theme");
+
+ if (profileDir.exists()) {
+ File profileFonts = new File(profileDir, "fonts");
+ if (profileFonts.exists()) {
+ IOUtils.copyFolder(profileFonts, new File(IOUtils.SYSTEM_THEME_FONT_PATH));
+ refreshFonts();
+ restartUi = true;
+ } else {
+ clearFonts();
+ }
+
+ File profileSounds = new File(profileDir, "audio");
+ if (profileSounds.exists()) {
+ IOUtils.copyFolder(profileSounds, new File(IOUtils.SYSTEM_THEME_AUDIO_PATH));
+ refreshSounds();
+ restartUi = true;
+ } else {
+ clearSounds(JobService.this);
+ }
+ }
+
+ // Disable all overlays installed
+ for (String overlay : mToBeDisabled) {
+ switchOverlay(overlay, false);
+ }
+
+ // Enable provided overlays
+ for (String overlay : mToBeEnabled) {
+ switchOverlay(overlay, true);
+ }
+
+ // Restart SystemUI when needed
+ if (restartUi) {
+ synchronized(mJobQueue) {
+ mJobQueue.add(new UiResetJob());
+ }
+ }
+
+ Message message = mJobHandler.obtainMessage(JobHandler.MESSAGE_DEQUEUE,
+ ProfileJob.this);
+ mJobHandler.sendMessage(message);
}
}
diff --git a/app/src/main/java/masquerade/substratum/utils/IOUtils.java b/app/src/main/java/masquerade/substratum/utils/IOUtils.java
index 092c58c..06b5260 100644
--- a/app/src/main/java/masquerade/substratum/utils/IOUtils.java
+++ b/app/src/main/java/masquerade/substratum/utils/IOUtils.java
@@ -40,8 +40,8 @@
if (!dirExists(dirPath)) {
File dir = new File(dirPath);
if (dir.mkdir()) {
- FileUtils.setPermissions(dir, FileUtils.S_IRWXU |
- FileUtils.S_IRWXG | FileUtils.S_IROTH | FileUtils.S_IXOTH, -1, -1);
+ setPermissions(dir, FileUtils.S_IRWXU | FileUtils.S_IRWXG |
+ FileUtils.S_IROTH | FileUtils.S_IXOTH);
}
}
}
@@ -77,7 +77,7 @@
e.printStackTrace();
}
}
-
+
public static void deleteThemedAudio() {
try {
deleteRecursive(new File(SYSTEM_THEME_UI_SOUNDS_PATH));
@@ -89,20 +89,28 @@
}
}
- public static void copyFolder(String source, String dest) {
- File dir = new File(source);
- File[] files = dir.listFiles();
+ public static void copyFolder(File source, File dest) {
+ if (!dest.exists()) dest.mkdirs();
+ File[] files = source.listFiles();
for (File file : files) {
try {
- String sourceFile = dir + File.separator + file.getName();
- String destinationFile = dest + File.separator + file.getName();
- bufferedCopy(new File(sourceFile), new File(destinationFile));
+ File newFile = new File(dest.getAbsolutePath() + File.separator +
+ file.getName());
+ if (file.isFile()) {
+ bufferedCopy(file, newFile);
+ } else {
+ copyFolder(file, newFile);
+ }
} catch (Exception e) {
e.printStackTrace();
}
}
}
+ public static void copyFolder(String source, String dest) {
+ copyFolder(new File(source), new File(dest));
+ }
+
public static void unzip(String source, String destination) {
try (ZipInputStream inputStream = new ZipInputStream(
new BufferedInputStream(new FileInputStream(source)))) {
@@ -167,4 +175,23 @@
fileOrDirectory.delete();
}
+ public static void setPermissions(File path, int permissions) {
+ FileUtils.setPermissions(path, permissions, -1, -1);
+ }
+
+ public static void setPermissionsRecursive(File dir, int file, int folder) {
+ if (dir.isDirectory()) {
+ for (File child : dir.listFiles()) {
+ if (child.isDirectory()) {
+ setPermissionsRecursive(child, file, folder);
+ setPermissions(child, folder);
+ } else {
+ setPermissions(child, file);
+ }
+ }
+ setPermissions(dir, folder);
+ } else {
+ setPermissions(dir, file);
+ }
+ }
}
diff --git a/app/src/main/java/masquerade/substratum/utils/SoundUtils.java b/app/src/main/java/masquerade/substratum/utils/SoundUtils.java
index 72c6052..dda38eb 100644
--- a/app/src/main/java/masquerade/substratum/utils/SoundUtils.java
+++ b/app/src/main/java/masquerade/substratum/utils/SoundUtils.java
@@ -27,7 +27,7 @@
private static final String MEDIA_CONTENT_URI = "content://media/internal/audio/media";
public static void updateGlobalSettings(ContentResolver resolver, String uri, String val) {
- Settings.Global.putStringForUser(resolver, uri, val, UserHandle.USER_ALL);
+ Settings.Global.putStringForUser(resolver, uri, val, UserHandle.USER_SYSTEM);
}
public static boolean setUISounds(ContentResolver resolver, String sound_name, String location) {