mirror of
https://github.com/topjohnwu/Magisk.git
synced 2024-11-24 10:35:26 +00:00
Monitor package (un)install events
This commit is contained in:
parent
a573baea03
commit
29096eb5d7
@ -1,7 +1,7 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<manifest package="com.topjohnwu.magisk"
|
||||
<manifest
|
||||
package="com.topjohnwu.magisk"
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
|
||||
xmlns:tools="http://schemas.android.com/tools">
|
||||
|
||||
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
|
||||
@ -61,6 +61,14 @@
|
||||
</intent-filter>
|
||||
</receiver>
|
||||
|
||||
<receiver android:name=".receivers.PackageReceiver">
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.PACKAGE_ADDED" />
|
||||
<action android:name="android.intent.action.PACKAGE_REMOVED" />
|
||||
<data android:scheme="package" />
|
||||
</intent-filter>
|
||||
</receiver>
|
||||
|
||||
<service android:name=".services.BootupIntentService" />
|
||||
|
||||
<service
|
||||
|
@ -72,6 +72,7 @@ public class MagiskManager extends Application {
|
||||
public boolean magiskHide;
|
||||
public boolean isDarkTheme;
|
||||
public boolean updateNotification;
|
||||
public boolean suReauth;
|
||||
public int suRequestTimeout;
|
||||
public int suLogTimeout = 14;
|
||||
public int suAccessState;
|
||||
@ -129,6 +130,7 @@ public class MagiskManager extends Application {
|
||||
.putBoolean("notification", updateNotification)
|
||||
.putBoolean("hosts", new File("/magisk/.core/hosts").exists())
|
||||
.putBoolean("disable", Utils.itemExist(MAGISK_DISABLE_FILE))
|
||||
.putBoolean("su_reauth", suReauth)
|
||||
.putString("su_request_timeout", String.valueOf(suRequestTimeout))
|
||||
.putString("su_auto_response", String.valueOf(suResponseType))
|
||||
.putString("su_notification", String.valueOf(suNotificationType))
|
||||
@ -140,13 +142,18 @@ public class MagiskManager extends Application {
|
||||
Shell.su("PATH=$PATH:" + busybox.getParent());
|
||||
}
|
||||
|
||||
public void initSUConfig() {
|
||||
suRequestTimeout = Utils.getPrefsInt(prefs, "su_request_timeout", 10);
|
||||
suResponseType = Utils.getPrefsInt(prefs, "su_auto_response", 0);
|
||||
suNotificationType = Utils.getPrefsInt(prefs, "su_notification", 1);
|
||||
suReauth = prefs.getBoolean("su_reauth", false);
|
||||
}
|
||||
|
||||
public void initSU() {
|
||||
// Create the app data directory, so su binary can work properly
|
||||
new File(getApplicationInfo().dataDir).mkdirs();
|
||||
|
||||
suRequestTimeout = Utils.getPrefsInt(prefs, "su_request_timeout", 10);
|
||||
suResponseType = Utils.getPrefsInt(prefs, "su_auto_response", 0);
|
||||
suNotificationType = Utils.getPrefsInt(prefs, "su_notification", 1);
|
||||
initSUConfig();
|
||||
|
||||
List<String> ret = Shell.sh("su -v");
|
||||
if (Utils.isValidShellResponse(ret)) {
|
||||
|
@ -72,7 +72,7 @@ public class PolicyAdapter extends RecyclerView.Adapter<PolicyAdapter.ViewHolder
|
||||
String message = v.getContext().getString(
|
||||
isChecked ? R.string.su_snack_grant : R.string.su_snack_deny, policy.appName);
|
||||
SnackbarMaker.make(holder.itemView, message, Snackbar.LENGTH_SHORT).show();
|
||||
dbHelper.addPolicy(policy);
|
||||
dbHelper.updatePolicy(policy);
|
||||
}
|
||||
});
|
||||
holder.notificationSwitch.setOnCheckedChangeListener((v, isChecked) -> {
|
||||
@ -82,7 +82,7 @@ public class PolicyAdapter extends RecyclerView.Adapter<PolicyAdapter.ViewHolder
|
||||
String message = v.getContext().getString(
|
||||
isChecked ? R.string.su_snack_notif_on : R.string.su_snack_notif_off, policy.appName);
|
||||
SnackbarMaker.make(holder.itemView, message, Snackbar.LENGTH_SHORT).show();
|
||||
dbHelper.addPolicy(policy);
|
||||
dbHelper.updatePolicy(policy);
|
||||
}
|
||||
});
|
||||
holder.loggingSwitch.setOnCheckedChangeListener((v, isChecked) -> {
|
||||
@ -92,7 +92,7 @@ public class PolicyAdapter extends RecyclerView.Adapter<PolicyAdapter.ViewHolder
|
||||
String message = v.getContext().getString(
|
||||
isChecked ? R.string.su_snack_log_on : R.string.su_snack_log_off, policy.appName);
|
||||
SnackbarMaker.make(holder.itemView, message, Snackbar.LENGTH_SHORT).show();
|
||||
dbHelper.addPolicy(policy);
|
||||
dbHelper.updatePolicy(policy);
|
||||
}
|
||||
});
|
||||
holder.delete.setOnClickListener(v -> new AlertDialogBuilder(v.getContext())
|
||||
@ -104,7 +104,7 @@ public class PolicyAdapter extends RecyclerView.Adapter<PolicyAdapter.ViewHolder
|
||||
notifyItemRangeChanged(position, policyList.size());
|
||||
SnackbarMaker.make(holder.itemView, v.getContext().getString(R.string.su_snack_revoke, policy.appName),
|
||||
Snackbar.LENGTH_SHORT).show();
|
||||
dbHelper.deletePolicy(policy.uid);
|
||||
dbHelper.deletePolicy(policy);
|
||||
})
|
||||
.setNegativeButton(R.string.no_thanks, null)
|
||||
.setCancelable(true)
|
||||
@ -118,7 +118,7 @@ public class PolicyAdapter extends RecyclerView.Adapter<PolicyAdapter.ViewHolder
|
||||
|
||||
} catch (PackageManager.NameNotFoundException e) {
|
||||
policyList.remove(position);
|
||||
dbHelper.deletePolicy(policy.uid);
|
||||
dbHelper.deletePolicy(policy);
|
||||
onBindViewHolder(holder, position);
|
||||
}
|
||||
}
|
||||
|
@ -37,11 +37,11 @@ public class SuDatabaseHelper extends SQLiteOpenHelper {
|
||||
// Currently new database, no upgrading
|
||||
}
|
||||
|
||||
public boolean deletePolicy(int uid) {
|
||||
public boolean deletePolicy(Policy policy) {
|
||||
SQLiteDatabase db = getWritableDatabase();
|
||||
db.delete(TABLE_NAME, "uid=?", new String[] { String.valueOf(uid) });
|
||||
db.delete(TABLE_NAME, "package_name=?", new String[] { policy.packageName });
|
||||
db.close();
|
||||
return getPolicy(uid) == null;
|
||||
return getPolicy(policy.packageName) == null;
|
||||
}
|
||||
|
||||
public Policy getPolicy(int uid) {
|
||||
@ -56,29 +56,44 @@ public class SuDatabaseHelper extends SQLiteOpenHelper {
|
||||
return policy;
|
||||
}
|
||||
|
||||
public Policy getPolicy(String pkg) {
|
||||
Policy policy = null;
|
||||
SQLiteDatabase db = getReadableDatabase();
|
||||
try (Cursor c = db.query(TABLE_NAME, null, "package_name=?", new String[] { pkg }, null, null, null)) {
|
||||
if (c.moveToNext()) {
|
||||
policy = new Policy(c);
|
||||
}
|
||||
}
|
||||
db.close();
|
||||
return policy;
|
||||
}
|
||||
|
||||
public void addPolicy(Policy policy) {
|
||||
SQLiteDatabase db = getWritableDatabase();
|
||||
db.replace(TABLE_NAME, null, policy.getContentValues());
|
||||
db.close();
|
||||
}
|
||||
|
||||
public void updatePolicy(Policy policy) {
|
||||
SQLiteDatabase db = getWritableDatabase();
|
||||
db.update(TABLE_NAME, policy.getContentValues(), "package_name=?",
|
||||
new String[] { policy.packageName });
|
||||
db.close();
|
||||
}
|
||||
|
||||
public List<Policy> getPolicyList(PackageManager pm) {
|
||||
List<Policy> ret = new ArrayList<>();
|
||||
SQLiteDatabase db = getWritableDatabase();
|
||||
Policy policy;
|
||||
// Clear outdated policies
|
||||
db.delete(TABLE_NAME, "until > 0 and until < ?", new String[] { String.valueOf(System.currentTimeMillis()) });
|
||||
db.delete(TABLE_NAME, "until > 0 AND until < ?",
|
||||
new String[] { String.valueOf(System.currentTimeMillis()) });
|
||||
try (Cursor c = db.query(TABLE_NAME, null, null, null, null, null, "app_name ASC")) {
|
||||
while (c.moveToNext()) {
|
||||
policy = new Policy(c);
|
||||
// Package is uninstalled
|
||||
if (pm.getPackagesForUid(policy.uid) == null) {
|
||||
deletePolicy(policy.uid);
|
||||
} else {
|
||||
ret.add(policy);
|
||||
}
|
||||
}
|
||||
}
|
||||
db.close();
|
||||
return ret;
|
||||
}
|
||||
|
@ -0,0 +1,42 @@
|
||||
package com.topjohnwu.magisk.receivers;
|
||||
|
||||
import android.content.BroadcastReceiver;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
|
||||
import com.topjohnwu.magisk.MagiskManager;
|
||||
import com.topjohnwu.magisk.database.SuDatabaseHelper;
|
||||
import com.topjohnwu.magisk.superuser.Policy;
|
||||
import com.topjohnwu.magisk.utils.Logger;
|
||||
import com.topjohnwu.magisk.utils.Utils;
|
||||
|
||||
public class PackageReceiver extends BroadcastReceiver {
|
||||
@Override
|
||||
public void onReceive(Context context, Intent intent) {
|
||||
SuDatabaseHelper suDB = new SuDatabaseHelper(context);
|
||||
String pkg = intent.getData().getEncodedSchemeSpecificPart();
|
||||
Policy policy = suDB.getPolicy(pkg);
|
||||
if (policy == null)
|
||||
return;
|
||||
|
||||
MagiskManager magiskManager = Utils.getMagiskManager(context);
|
||||
magiskManager.initSUConfig();
|
||||
|
||||
switch (intent.getAction()) {
|
||||
case Intent.ACTION_PACKAGE_ADDED:
|
||||
int uid = intent.getIntExtra(Intent.EXTRA_UID, -1);
|
||||
// Update the UID if available
|
||||
if (uid > 0) {
|
||||
policy.uid = uid % 100000;
|
||||
}
|
||||
suDB.updatePolicy(policy);
|
||||
return;
|
||||
case Intent.ACTION_PACKAGE_REMOVED:
|
||||
boolean isUpdate = intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
|
||||
if (!isUpdate || magiskManager.suReauth) {
|
||||
suDB.deletePolicy(policy);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
@ -17,7 +17,7 @@ public class RequestActivity extends Activity {
|
||||
return;
|
||||
}
|
||||
|
||||
getApplicationContext().initSU();
|
||||
getApplicationContext().initSUConfig();
|
||||
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK).setClass(this, SuRequestActivity.class);
|
||||
startActivity(intent);
|
||||
finish();
|
||||
|
@ -56,7 +56,7 @@ public class SuReceiver extends BroadcastReceiver {
|
||||
}
|
||||
}
|
||||
|
||||
magiskManager.initSU();
|
||||
magiskManager.initSUConfig();
|
||||
|
||||
SuLogEntry log = new SuLogEntry(policy);
|
||||
|
||||
|
@ -89,9 +89,6 @@ public class SuRequestActivity extends Activity {
|
||||
}
|
||||
|
||||
private void showRequest() {
|
||||
|
||||
Logger.debug("Show request");
|
||||
|
||||
switch (magiskManager.suResponseType) {
|
||||
case AUTO_DENY:
|
||||
handleAction(Policy.DENY, 0);
|
||||
|
@ -161,6 +161,8 @@
|
||||
<string name="request_timeout">Request Timeout</string>
|
||||
<string name="superuser_notification">Superuser Notification</string>
|
||||
<string name="request_timeout_summary">%1$s seconds</string>
|
||||
<string name="settings_su_reauth_title">Re-authenticate after upgrade</string>
|
||||
<string name="settings_su_reauth_summary">Re-authenticate superuser permissions after an application upgrades</string>
|
||||
|
||||
<string name="multiuser_mode">Multiuser Mode</string>
|
||||
<string name="settings_owner_only">Device Owner Only</string>
|
||||
|
@ -5,15 +5,14 @@
|
||||
android:title="@string/settings_general_category">
|
||||
|
||||
<SwitchPreference
|
||||
android:defaultValue="false"
|
||||
android:key="dark_theme"
|
||||
android:title="@string/settings_dark_theme_title"
|
||||
android:summary="@string/settings_dark_theme_summary"
|
||||
android:key="dark_theme" />
|
||||
android:summary="@string/settings_dark_theme_summary" />
|
||||
|
||||
<SwitchPreference
|
||||
android:key="notification"
|
||||
android:title="@string/settings_notification_title"
|
||||
android:summary="@string/settings_notification_summary"
|
||||
android:key="notification" />
|
||||
android:summary="@string/settings_notification_summary" />
|
||||
|
||||
<Preference
|
||||
android:key="clear"
|
||||
@ -33,13 +32,11 @@
|
||||
|
||||
<SwitchPreference
|
||||
android:key="magiskhide"
|
||||
android:defaultValue="false"
|
||||
android:title="@string/magiskhide"
|
||||
android:summary="@string/settings_magiskhide_summary" />
|
||||
|
||||
<SwitchPreference
|
||||
android:key="hosts"
|
||||
android:defaultValue="false"
|
||||
android:title="@string/settings_hosts_title"
|
||||
android:summary="@string/settings_hosts_summary" />
|
||||
|
||||
@ -79,6 +76,11 @@
|
||||
android:entries="@array/su_notification"
|
||||
android:entryValues="@array/value_array" />
|
||||
|
||||
<SwitchPreference
|
||||
android:key="su_reauth"
|
||||
android:title="@string/settings_su_reauth_title"
|
||||
android:summary="@string/settings_su_reauth_summary"/>
|
||||
|
||||
</PreferenceCategory>
|
||||
|
||||
<PreferenceCategory
|
||||
|
Loading…
Reference in New Issue
Block a user