diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index d3863ebb9..9ba7c0f60 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -76,6 +76,7 @@
android:name="a.h"
android:directBootAware="true">
+
diff --git a/app/src/main/java/com/topjohnwu/magisk/extensions/XAndroid.kt b/app/src/main/java/com/topjohnwu/magisk/extensions/XAndroid.kt
index 4a893ab8b..29120d6f8 100644
--- a/app/src/main/java/com/topjohnwu/magisk/extensions/XAndroid.kt
+++ b/app/src/main/java/com/topjohnwu/magisk/extensions/XAndroid.kt
@@ -20,13 +20,15 @@ import androidx.annotation.ColorRes
import androidx.annotation.DrawableRes
import androidx.core.content.ContextCompat
import androidx.core.net.toUri
+import com.topjohnwu.magisk.Const
import com.topjohnwu.magisk.utils.DynamicClassLoader
import com.topjohnwu.magisk.utils.FileProvider
import com.topjohnwu.magisk.utils.Utils
import com.topjohnwu.magisk.utils.currentLocale
+import com.topjohnwu.superuser.Shell
import java.io.File
import java.io.FileNotFoundException
-import java.util.*
+import java.lang.reflect.Array as JArray
val packageName: String get() = get().packageName
@@ -97,33 +99,38 @@ fun Context.readUri(uri: Uri) =
fun Intent.startActivity(context: Context) = context.startActivity(this)
-fun Intent.toCommand(args: MutableList) {
- if (action != null) {
+fun Intent.startActivityWithRoot() {
+ val args = mutableListOf("am", "start", "--user", Const.USER_ID.toString())
+ val cmd = toCommand(args).joinToString(" ")
+ Shell.su(cmd).submit()
+}
+
+fun Intent.toCommand(args: MutableList = mutableListOf()): MutableList {
+ action?.also {
args.add("-a")
- args.add(action!!)
+ args.add(it)
}
- if (component != null) {
+ component?.also {
args.add("-n")
- args.add(component!!.flattenToString())
+ args.add(it.flattenToString())
}
- if (data != null) {
+ data?.also {
args.add("-d")
- args.add(dataString!!)
+ args.add(it.toString())
}
- if (categories != null) {
- for (cat in categories) {
+ categories?.also {
+ for (cat in it) {
args.add("-c")
args.add(cat)
}
}
- if (type != null) {
+ type?.also {
args.add("-t")
- args.add(type!!)
+ args.add(it)
}
- val extras = extras
- if (extras != null) {
- loop@ for (key in extras.keySet()) {
- val v = extras.get(key) ?: continue
+ extras?.also {
+ loop@ for (key in it.keySet()) {
+ val v = it[key] ?: continue
var value: Any = v
val arg: String
when {
@@ -137,9 +144,8 @@ fun Intent.toCommand(args: MutableList) {
arg = "--ecn"
value = v.flattenToString()
}
- v is ArrayList<*> -> {
- if (v.size <= 0)
- /* Impossible to know the type due to type erasure */
+ v is List<*> -> {
+ if (v.isEmpty())
continue@loop
arg = if (v[0] is Int)
@@ -175,9 +181,9 @@ fun Intent.toCommand(args: MutableList) {
continue@loop /* Unsupported */
val sb = StringBuilder()
- val len = java.lang.reflect.Array.getLength(v)
+ val len = JArray.getLength(v)
for (i in 0 until len) {
- sb.append(java.lang.reflect.Array.get(v, i)!!.toString().replace(",", "\\,"))
+ sb.append(JArray.get(v, i)!!.toString().replace(",", "\\,"))
sb.append(',')
}
// Remove trailing comma
@@ -194,6 +200,7 @@ fun Intent.toCommand(args: MutableList) {
}
args.add("-f")
args.add(flags.toString())
+ return args
}
fun File.provide(context: Context = get()): Uri {
diff --git a/app/src/main/java/com/topjohnwu/magisk/model/receiver/GeneralReceiver.kt b/app/src/main/java/com/topjohnwu/magisk/model/receiver/GeneralReceiver.kt
index f9c591304..6a0ca9a4f 100644
--- a/app/src/main/java/com/topjohnwu/magisk/model/receiver/GeneralReceiver.kt
+++ b/app/src/main/java/com/topjohnwu/magisk/model/receiver/GeneralReceiver.kt
@@ -2,14 +2,14 @@ package com.topjohnwu.magisk.model.receiver
import android.content.ContextWrapper
import android.content.Intent
-import com.topjohnwu.magisk.Config
-import com.topjohnwu.magisk.Const
-import com.topjohnwu.magisk.Info
+import android.os.Build.VERSION.SDK_INT
+import com.topjohnwu.magisk.*
import com.topjohnwu.magisk.base.BaseReceiver
import com.topjohnwu.magisk.data.database.PolicyDao
import com.topjohnwu.magisk.data.database.base.su
import com.topjohnwu.magisk.extensions.reboot
-import com.topjohnwu.magisk.intent
+import com.topjohnwu.magisk.extensions.startActivity
+import com.topjohnwu.magisk.extensions.startActivityWithRoot
import com.topjohnwu.magisk.model.download.DownloadService
import com.topjohnwu.magisk.model.entity.ManagerJson
import com.topjohnwu.magisk.model.entity.internal.Configuration
@@ -20,6 +20,7 @@ import com.topjohnwu.magisk.view.Notifications
import com.topjohnwu.magisk.view.Shortcuts
import com.topjohnwu.superuser.Shell
import org.koin.core.inject
+import timber.log.Timber
open class GeneralReceiver : BaseReceiver() {
@@ -38,6 +39,17 @@ open class GeneralReceiver : BaseReceiver() {
override fun onReceive(context: ContextWrapper, intent: Intent?) {
intent ?: return
+
+ // Debug messages
+ if (BuildConfig.DEBUG) {
+ Timber.d(intent.action)
+ intent.extras?.let { bundle ->
+ bundle.keySet().forEach {
+ Timber.d("[%s]=[%s]", it, bundle[it])
+ }
+ }
+ }
+
when (intent.action ?: return) {
Intent.ACTION_REBOOT, Intent.ACTION_BOOT_COMPLETED -> {
val action = intent.getStringExtra("action")
@@ -56,11 +68,19 @@ open class GeneralReceiver : BaseReceiver() {
.putExtra("socket", intent.getStringExtra("socket"))
.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
.addFlags(Intent.FLAG_ACTIVITY_MULTIPLE_TASK)
- context.startActivity(i)
+ if (SDK_INT >= 29) {
+ // Android Q does not allow starting activity from background
+ i.startActivityWithRoot()
+ } else {
+ i.startActivity(context)
+ }
+ }
+ LOG -> SuLogger.handleLogs(context, intent)
+ NOTIFY -> SuLogger.handleNotify(context, intent)
+ TEST -> {
+ val mode = intent.getIntExtra("mode", 1 shl 1)
+ Shell.su("magisk --connect-mode $mode").submit()
}
- LOG -> SuLogger.handleLogs(intent)
- NOTIFY -> SuLogger.handleNotify(intent)
- TEST -> Shell.su("magisk --use-broadcast").submit()
}
}
Intent.ACTION_PACKAGE_REPLACED ->
diff --git a/app/src/main/java/com/topjohnwu/magisk/ui/surequest/SuRequestActivity.kt b/app/src/main/java/com/topjohnwu/magisk/ui/surequest/SuRequestActivity.kt
index b55e108c2..4ce2a60be 100644
--- a/app/src/main/java/com/topjohnwu/magisk/ui/surequest/SuRequestActivity.kt
+++ b/app/src/main/java/com/topjohnwu/magisk/ui/surequest/SuRequestActivity.kt
@@ -3,7 +3,6 @@ package com.topjohnwu.magisk.ui.surequest
import android.content.pm.ActivityInfo
import android.os.Build
import android.os.Bundle
-import android.text.TextUtils
import android.view.Window
import com.topjohnwu.magisk.R
import com.topjohnwu.magisk.base.BaseActivity
@@ -31,19 +30,17 @@ open class SuRequestActivity : BaseActivity {
+ if (!viewModel.handleRequest(intent))
+ finish()
+ return
+ }
+ GeneralReceiver.LOG -> SuLogger.handleLogs(this, intent)
+ GeneralReceiver.NOTIFY -> SuLogger.handleNotify(this, intent)
}
- if (TextUtils.equals(action, GeneralReceiver.LOG))
- SuLogger.handleLogs(intent)
- else if (TextUtils.equals(action, GeneralReceiver.NOTIFY))
- SuLogger.handleNotify(intent)
-
finish()
}
diff --git a/app/src/main/java/com/topjohnwu/magisk/utils/SuLogger.kt b/app/src/main/java/com/topjohnwu/magisk/utils/SuLogger.kt
index b6134d584..98b201235 100644
--- a/app/src/main/java/com/topjohnwu/magisk/utils/SuLogger.kt
+++ b/app/src/main/java/com/topjohnwu/magisk/utils/SuLogger.kt
@@ -2,14 +2,13 @@ package com.topjohnwu.magisk.utils
import android.content.Context
import android.content.Intent
-import android.content.pm.PackageManager
import android.os.Process
import android.widget.Toast
import com.topjohnwu.magisk.Config
import com.topjohnwu.magisk.R
import com.topjohnwu.magisk.data.database.PolicyDao
import com.topjohnwu.magisk.data.repository.LogRepository
-import com.topjohnwu.magisk.extensions.inject
+import com.topjohnwu.magisk.extensions.get
import com.topjohnwu.magisk.model.entity.MagiskPolicy
import com.topjohnwu.magisk.model.entity.toLog
import com.topjohnwu.magisk.model.entity.toPolicy
@@ -17,15 +16,13 @@ import java.util.*
object SuLogger {
- private val context: Context by inject()
-
- fun handleLogs(intent: Intent) {
+ fun handleLogs(context: Context, intent: Intent) {
val fromUid = intent.getIntExtra("from.uid", -1)
if (fromUid < 0) return
if (fromUid == Process.myUid()) return
- val pm: PackageManager by inject()
+ val pm = context.packageManager
val notify: Boolean
val data = intent.extras
@@ -36,7 +33,7 @@ object SuLogger {
}.getOrElse { return }
} else {
// Doesn't report whether notify or not, check database ourselves
- val policyDB: PolicyDao by inject()
+ val policyDB = get()
val policy = policyDB.fetch(fromUid).blockingGet() ?: return
notify = policy.notification
policy
@@ -46,7 +43,7 @@ object SuLogger {
return
if (notify)
- handleNotify(policy)
+ handleNotify(context, policy)
val toUid = intent.getIntExtra("to.uid", -1)
if (toUid < 0) return
@@ -62,11 +59,11 @@ object SuLogger {
date = Date()
)
- val logRepo: LogRepository by inject()
+ val logRepo = get()
logRepo.put(log).blockingGet()?.printStackTrace()
}
- private fun handleNotify(policy: MagiskPolicy) {
+ private fun handleNotify(context: Context, policy: MagiskPolicy) {
if (policy.notification && Config.suNotification == Config.Value.NOTIFICATION_TOAST) {
Utils.toast(
context.getString(
@@ -80,16 +77,16 @@ object SuLogger {
}
}
- fun handleNotify(intent: Intent) {
+ fun handleNotify(context: Context, intent: Intent) {
val fromUid = intent.getIntExtra("from.uid", -1)
if (fromUid < 0) return
if (fromUid == Process.myUid()) return
runCatching {
- val packageManager: PackageManager by inject()
- val policy = fromUid.toPolicy(packageManager)
+ val pm = context.packageManager
+ val policy = fromUid.toPolicy(pm)
.copy(policy = intent.getIntExtra("policy", -1))
if (policy.policy >= 0)
- handleNotify(policy)
+ handleNotify(context, policy)
}
}
}
diff --git a/native/jni/core/daemon.cpp b/native/jni/core/daemon.cpp
index 41dc7d97c..f13f05d3e 100644
--- a/native/jni/core/daemon.cpp
+++ b/native/jni/core/daemon.cpp
@@ -54,6 +54,7 @@ static void *request_handler(void *args) {
case BOOT_COMPLETE:
case SQLITE_CMD:
case BROADCAST_ACK:
+ case BROADCAST_TEST:
if (credential.uid != 0) {
write_int(client, ROOT_REQUIRED);
close(client);
@@ -91,9 +92,10 @@ static void *request_handler(void *args) {
exec_sql(client);
break;
case BROADCAST_ACK:
- LOGD("* Use broadcasts for su logging and notify\n");
- CONNECT_BROADCAST = true;
- close(client);
+ broadcast_ack(client);
+ break;
+ case BROADCAST_TEST:
+ broadcast_test(client);
break;
case REMOVE_MODULES:
if (credential.uid == UID_SHELL || credential.uid == UID_ROOT) {
diff --git a/native/jni/core/db.cpp b/native/jni/core/db.cpp
index 701f62c41..bd451b64d 100644
--- a/native/jni/core/db.cpp
+++ b/native/jni/core/db.cpp
@@ -219,7 +219,6 @@ int get_db_strings(db_strings &str, int key) {
char *err;
auto string_cb = [&](db_row &row) -> bool {
str[row["key"]] = row["value"];
- LOGD("magiskdb: query %s=[%s]\n", row["key"].data(), row["value"].data());
return true;
};
if (key >= 0) {
@@ -273,6 +272,7 @@ int validate_manager(string &alt_pkg, int userid, struct stat *st) {
}
void exec_sql(int client) {
+ run_finally f([=]{ close(client); });
char *sql = read_string(client);
char *err = db_exec(sql, [&](db_row &row) -> bool {
string out;
@@ -289,9 +289,6 @@ void exec_sql(int client) {
return true;
});
free(sql);
- db_err_cmd(err,
- write_int(client, 0);
- return;
- );
- close(client);
+ write_int(client, 0);
+ db_err_cmd(err, return; );
}
diff --git a/native/jni/core/magisk.cpp b/native/jni/core/magisk.cpp
index a93ea1eaa..821e53be1 100644
--- a/native/jni/core/magisk.cpp
+++ b/native/jni/core/magisk.cpp
@@ -9,7 +9,6 @@
#include
#include
#include
-#include
#include
using namespace std::literals;
@@ -36,7 +35,8 @@ Advanced Options (Internal APIs):
--clone-attr SRC DEST clone permission, owner, and selinux context
--clone SRC DEST clone SRC to DEST
--sqlite SQL exec SQL commands to Magisk database
- --use-broadcast use broadcast for su logging and notify
+ --connect-mode [MODE] get/set connect mode for su request and notify
+ --broadcast-test manually trigger broadcast tests
Supported init triggers:
post-fs-data, service, boot-complete
@@ -79,12 +79,10 @@ int magisk_main(int argc, char *argv[]) {
restore_rootcon();
restorecon();
return 0;
- } else if (argv[1] == "--clone-attr"sv) {
- if (argc < 4) usage();
+ } else if (argc >= 4 && argv[1] == "--clone-attr"sv) {;
clone_attr(argv[2], argv[3]);
return 0;
- } else if (argv[1] == "--clone"sv) {
- if (argc < 4) usage();
+ } else if (argc >= 4 && argv[1] == "--clone"sv) {
cp_afc(argv[2], argv[3]);
return 0;
} else if (argv[1] == "--daemon"sv) {
@@ -103,7 +101,7 @@ int magisk_main(int argc, char *argv[]) {
int fd = connect_daemon(true);
write_int(fd, BOOT_COMPLETE);
return read_int(fd);
- } else if (argv[1] == "--sqlite"sv) {
+ } else if (argc >= 3 && argv[1] == "--sqlite"sv) {
int fd = connect_daemon();
write_int(fd, SQLITE_CMD);
write_string(fd, argv[2]);
@@ -115,14 +113,23 @@ int magisk_main(int argc, char *argv[]) {
printf("%s\n", res);
free(res);
}
- } else if (argv[1] == "--use-broadcast"sv) {
+ } else if (argv[1] == "--connect-mode"sv) {
int fd = connect_daemon();
write_int(fd, BROADCAST_ACK);
- return 0;
+ if (argc >= 3) {
+ write_int(fd, parse_int(argv[2]));
+ } else {
+ write_int(fd, -1);
+ }
+ return read_int(fd);
} else if (argv[1] == "--remove-modules"sv) {
int fd = connect_daemon();
write_int(fd, REMOVE_MODULES);
return read_int(fd);
+ } else if (argv[1] == "--broadcast-test"sv) {
+ int fd = connect_daemon();
+ write_int(fd, BROADCAST_TEST);
+ return read_int(fd);
}
#if 0
/* Entry point for testing stuffs */
diff --git a/native/jni/include/daemon.h b/native/jni/include/daemon.h
index 92e1b5b62..0f6956b0e 100644
--- a/native/jni/include/daemon.h
+++ b/native/jni/include/daemon.h
@@ -19,6 +19,7 @@ enum {
SQLITE_CMD,
BROADCAST_ACK,
REMOVE_MODULES,
+ BROADCAST_TEST,
};
// Return codes for daemon
@@ -84,10 +85,13 @@ void magiskhide_handler(int client);
*************/
void su_daemon_handler(int client, struct ucred *credential);
-void broadcast_test();
+void broadcast_test(int client = -1);
+void broadcast_ack(int client);
+
+/*********************
+ * Daemon Global Vars
+ *********************/
extern int SDK_INT;
extern bool RECOVERY_MODE;
-extern bool CONNECT_BROADCAST;
-
#define APP_DATA_DIR (SDK_INT >= 24 ? "/data/user_de" : "/data/user")
diff --git a/native/jni/su/connect.cpp b/native/jni/su/connect.cpp
index f59155863..f83cf2c9c 100644
--- a/native/jni/su/connect.cpp
+++ b/native/jni/su/connect.cpp
@@ -7,12 +7,20 @@
#include
#include
+#include
#include "su.h"
using namespace std;
-bool CONNECT_BROADCAST;
+enum connect_mode {
+ UNINITIALIZED = 0,
+ MODE_ACTIVITY,
+ MODE_BROADCAST_COMPONENT,
+ MODE_BROADCAST_PACKAGE
+};
+
+static connect_mode current_mode = UNINITIALIZED;
#define START_ACTIVITY \
"/system/bin/app_process", "/system/bin", "com.android.commands.am.Am", \
@@ -25,9 +33,28 @@ bool CONNECT_BROADCAST;
"broadcast", "-n", nullptr, "--user", nullptr, "-f", "0x00000020", \
"-a", "android.intent.action.REBOOT", "--es", "action"
+#define START_BROADCAST_PKG \
+"/system/bin/app_process", "/system/bin", "com.android.commands.am.Am", \
+"broadcast", "-p", nullptr, "--user", nullptr, "-f", "0x00000020", \
+"-a", "android.intent.action.REBOOT", "--es", "action"
+
// 0x00000020 = FLAG_INCLUDE_STOPPED_PACKAGES
-static inline const char *get_command(const su_request *to) {
+#define am_app_info(info, ...) \
+if (current_mode == MODE_BROADCAST_PACKAGE) { \
+ const char *cmd[] = { START_BROADCAST_PKG, __VA_ARGS__, nullptr }; \
+ exec_am_cmd(cmd, info); \
+} else if (current_mode == MODE_BROADCAST_COMPONENT) { \
+ const char *cmd[] = { START_BROADCAST, __VA_ARGS__, nullptr }; \
+ exec_am_cmd(cmd, info); \
+} else { \
+ const char *cmd[] = { START_ACTIVITY, __VA_ARGS__, nullptr }; \
+ exec_am_cmd(cmd, info); \
+}
+
+#define am_app(...) am_app_info(ctx.info.get(), __VA_ARGS__)
+
+static const char *get_command(const su_request *to) {
if (to->command[0])
return to->command;
if (to->shell[0])
@@ -35,14 +62,14 @@ static inline const char *get_command(const su_request *to) {
return DEFAULT_SHELL;
}
-static inline void get_user(char *user, const su_info *info) {
+static void get_user(char *user, const su_info *info) {
sprintf(user, "%d",
info->cfg[SU_MULTIUSER_MODE] == MULTIUSER_MODE_USER
? info->uid / 100000
: 0);
}
-static inline void get_uid(char *uid, const su_info *info) {
+static void get_uid(char *uid, const su_info *info) {
sprintf(uid, "%d",
info->cfg[SU_MULTIUSER_MODE] == MULTIUSER_MODE_OWNER_MANAGED
? info->uid % 100000
@@ -50,13 +77,25 @@ static inline void get_uid(char *uid, const su_info *info) {
}
static void exec_am_cmd(const char **args, const su_info *info) {
- char component[128];
- sprintf(component, "%s/%s", info->str[SU_MANAGER].data(), args[3][0] == 'b' ? "a.h" : "a.m");
+ char target[128];
+ if (args[3][0] == 'b') {
+ // Broadcast
+ if (args[4][1] == 'p') {
+ // Broadcast to package (receiver can be obfuscated)
+ strcpy(target, info->str[SU_MANAGER].data());
+ } else {
+ // a.h is the broadcast receiver
+ sprintf(target, "%s/a.h", info->str[SU_MANAGER].data());
+ }
+ } else {
+ // a.m is the activity
+ sprintf(target, "%s/a.m", info->str[SU_MANAGER].data());
+ }
char user[8];
get_user(user, info);
- /* Fill in dynamic arguments */
- args[5] = component;
+ // Fill in non static arguments
+ args[5] = target;
args[7] = user;
exec_t exec {
@@ -79,8 +118,7 @@ static void exec_am_cmd(const char **args, const su_info *info) {
"--ei", "pid", pid, \
"--ei", "policy", policy, \
"--es", "command", get_command(&ctx.req), \
-"--ez", "notify", ctx.info->access.notify ? "true" : "false", \
-nullptr
+"--ez", "notify", ctx.info->access.notify ? "true" : "false"
void app_log(const su_context &ctx) {
char fromUid[8];
@@ -95,20 +133,13 @@ void app_log(const su_context &ctx) {
char policy[2];
sprintf(policy, "%d", ctx.info->access.policy);
- if (CONNECT_BROADCAST) {
- const char *cmd[] = { START_BROADCAST, LOG_BODY };
- exec_am_cmd(cmd, ctx.info.get());
- } else {
- const char *cmd[] = { START_ACTIVITY, LOG_BODY };
- exec_am_cmd(cmd, ctx.info.get());
- }
+ am_app(LOG_BODY)
}
#define NOTIFY_BODY \
"notify", \
"--ei", "from.uid", fromUid, \
-"--ei", "policy", policy, \
-nullptr
+"--ei", "policy", policy
void app_notify(const su_context &ctx) {
char fromUid[8];
@@ -117,33 +148,59 @@ void app_notify(const su_context &ctx) {
char policy[2];
sprintf(policy, "%d", ctx.info->access.policy);
- if (CONNECT_BROADCAST) {
- const char *cmd[] = { START_BROADCAST, NOTIFY_BODY };
- exec_am_cmd(cmd, ctx.info.get());
- } else {
- const char *cmd[] = { START_ACTIVITY, NOTIFY_BODY };
- exec_am_cmd(cmd, ctx.info.get());
+ am_app(NOTIFY_BODY)
+}
+
+#define SOCKET_BODY \
+"request", \
+"--es", "socket", socket
+
+void app_socket(const char *socket, const shared_ptr &info) {
+ am_app_info(info.get(), SOCKET_BODY)
+}
+
+#define TEST_BODY \
+"test", "--ei", "mode", mode, nullptr
+
+void broadcast_test(int client) {
+ if (client >= 0) {
+ // Make it not uninitialized
+ current_mode = MODE_ACTIVITY;
+ write_int(client, 0);
+ close(client);
}
-}
-
-void app_connect(const char *socket, const shared_ptr &info) {
- const char *cmd[] = {
- START_ACTIVITY, "request",
- "--es", "socket", socket,
- nullptr
- };
- exec_am_cmd(cmd, info.get());
-}
-
-void broadcast_test() {
su_info info;
get_db_settings(info.cfg);
get_db_strings(info.str);
validate_manager(info.str[SU_MANAGER], 0, &info.mgr_st);
- const char *cmd[] = { START_BROADCAST, "test", nullptr };
- exec_am_cmd(cmd, &info);
+ char mode[2];
+ {
+ sprintf(mode, "%d", MODE_BROADCAST_PACKAGE);
+ const char *cmd[] = { START_BROADCAST_PKG, TEST_BODY };
+ exec_am_cmd(cmd, &info);
+ }
+ {
+ sprintf(mode, "%d", MODE_BROADCAST_COMPONENT);
+ const char *cmd[] = { START_BROADCAST, TEST_BODY };
+ exec_am_cmd(cmd, &info);
+ }
+}
+
+void broadcast_ack(int client) {
+ int mode = read_int(client);
+ if (mode < 0) {
+ // Return connection mode to client
+ write_int(client, current_mode);
+ } else {
+ if (mode > current_mode) {
+ LOGD("* Use connect mode [%d] for su request and notify\n", mode);
+ current_mode = static_cast(mode);
+ }
+ write_int(client, 0);
+ }
+ close(client);
}
void socket_send_request(int fd, const shared_ptr &info) {
diff --git a/native/jni/su/su.h b/native/jni/su/su.h
index c496e5bbf..2c18fc5c8 100644
--- a/native/jni/su/su.h
+++ b/native/jni/su/su.h
@@ -68,5 +68,5 @@ struct su_context {
void app_log(const su_context &ctx);
void app_notify(const su_context &ctx);
-void app_connect(const char *socket, const std::shared_ptr &info);
+void app_socket(const char *socket, const std::shared_ptr &info);
void socket_send_request(int fd, const std::shared_ptr &info);
diff --git a/native/jni/su/su_daemon.cpp b/native/jni/su/su_daemon.cpp
index 5debb5cd5..660ca1175 100644
--- a/native/jni/su/su_daemon.cpp
+++ b/native/jni/su/su_daemon.cpp
@@ -144,7 +144,7 @@ static shared_ptr get_su_info(unsigned uid) {
int sockfd = create_rand_socket(&addr);
// Connect manager
- app_connect(addr.sun_path + 1, info);
+ app_socket(addr.sun_path + 1, info);
int fd = socket_accept(sockfd, 60);
if (fd < 0) {
info->access.policy = DENY;