[core] Fix binder for system server
This commit is contained in:
parent
fbe39af620
commit
85e6b88bf5
|
|
@ -197,7 +197,9 @@ namespace lspd {
|
||||||
void
|
void
|
||||||
Context::OnNativeForkSystemServerPost(JNIEnv *env, jint res) {
|
Context::OnNativeForkSystemServerPost(JNIEnv *env, jint res) {
|
||||||
if (res != 0) return;
|
if (res != 0) return;
|
||||||
auto binder = Service::instance()->RequestBinder(env);
|
LoadDex(env);
|
||||||
|
Service::instance()->HookBridge(*this, env);
|
||||||
|
auto binder = Service::instance()->RequestBinderForSystemServer(env);
|
||||||
if (binder) {
|
if (binder) {
|
||||||
if (void *buf = mmap(nullptr, 1, PROT_READ | PROT_WRITE | PROT_EXEC,
|
if (void *buf = mmap(nullptr, 1, PROT_READ | PROT_WRITE | PROT_EXEC,
|
||||||
MAP_ANONYMOUS | MAP_PRIVATE, -1,
|
MAP_ANONYMOUS | MAP_PRIVATE, -1,
|
||||||
|
|
@ -208,14 +210,15 @@ namespace lspd {
|
||||||
} else {
|
} else {
|
||||||
munmap(buf, 1);
|
munmap(buf, 1);
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
skip_ = true;
|
||||||
|
LOGD("skip injecting into android because no module is hooking it");
|
||||||
}
|
}
|
||||||
LoadDex(env);
|
if (!skip_) {
|
||||||
if (!skip_ && binder) {
|
|
||||||
InstallInlineHooks();
|
InstallInlineHooks();
|
||||||
Init(env);
|
Init(env);
|
||||||
FindAndCall(env, "forkSystemServerPost", "(Landroid/os/IBinder;)V", binder);
|
FindAndCall(env, "forkSystemServerPost", "(Landroid/os/IBinder;)V", binder);
|
||||||
}
|
}
|
||||||
Service::instance()->HookBridge(*this, env);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Context::OnNativeForkAndSpecializePre(JNIEnv *env,
|
void Context::OnNativeForkAndSpecializePre(JNIEnv *env,
|
||||||
|
|
|
||||||
|
|
@ -10,7 +10,9 @@
|
||||||
#include "JNIHelper.h"
|
#include "JNIHelper.h"
|
||||||
|
|
||||||
namespace lspd {
|
namespace lspd {
|
||||||
jboolean Service::exec_transact_replace(jboolean *res, JNIEnv *env, [[maybe_unused]] jobject obj, va_list args) {
|
jboolean
|
||||||
|
Service::exec_transact_replace(jboolean *res, JNIEnv *env, [[maybe_unused]] jobject obj,
|
||||||
|
va_list args) {
|
||||||
jint code;
|
jint code;
|
||||||
|
|
||||||
va_list copy;
|
va_list copy;
|
||||||
|
|
@ -44,39 +46,40 @@ namespace lspd {
|
||||||
initialized_ = true;
|
initialized_ = true;
|
||||||
|
|
||||||
// ServiceManager
|
// ServiceManager
|
||||||
serviceManagerClass_ = env->FindClass("android/os/ServiceManager");
|
service_manager_class_ = env->FindClass("android/os/ServiceManager");
|
||||||
if (serviceManagerClass_) {
|
if (service_manager_class_) {
|
||||||
serviceManagerClass_ = (jclass) env->NewGlobalRef(serviceManagerClass_);
|
service_manager_class_ = (jclass) env->NewGlobalRef(service_manager_class_);
|
||||||
} else {
|
} else {
|
||||||
env->ExceptionClear();
|
env->ExceptionClear();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
getServiceMethod_ = env->GetStaticMethodID(serviceManagerClass_, "getService",
|
get_service_method_ = env->GetStaticMethodID(service_manager_class_, "getService",
|
||||||
"(Ljava/lang/String;)Landroid/os/IBinder;");
|
"(Ljava/lang/String;)Landroid/os/IBinder;");
|
||||||
if (!getServiceMethod_) {
|
if (!get_service_method_) {
|
||||||
env->ExceptionClear();
|
env->ExceptionClear();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// IBinder
|
// IBinder
|
||||||
jclass iBinderClass = env->FindClass("android/os/IBinder");
|
jclass ibinder_class = env->FindClass("android/os/IBinder");
|
||||||
transactMethod_ = env->GetMethodID(iBinderClass, "transact",
|
transact_method_ = env->GetMethodID(ibinder_class, "transact",
|
||||||
"(ILandroid/os/Parcel;Landroid/os/Parcel;I)Z");
|
"(ILandroid/os/Parcel;Landroid/os/Parcel;I)Z");
|
||||||
|
|
||||||
// Parcel
|
// Parcel
|
||||||
parcelClass_ = env->FindClass("android/os/Parcel");
|
parcel_class_ = env->FindClass("android/os/Parcel");
|
||||||
if (parcelClass_) parcelClass_ = (jclass) env->NewGlobalRef(parcelClass_);
|
if (parcel_class_) parcel_class_ = (jclass) env->NewGlobalRef(parcel_class_);
|
||||||
obtainMethod_ = env->GetStaticMethodID(parcelClass_, "obtain", "()Landroid/os/Parcel;");
|
obtain_method_ = env->GetStaticMethodID(parcel_class_, "obtain", "()Landroid/os/Parcel;");
|
||||||
recycleMethod_ = env->GetMethodID(parcelClass_, "recycle", "()V");
|
recycleMethod_ = env->GetMethodID(parcel_class_, "recycle", "()V");
|
||||||
writeInterfaceTokenMethod_ = env->GetMethodID(parcelClass_, "writeInterfaceToken",
|
write_interface_token_method_ = env->GetMethodID(parcel_class_, "writeInterfaceToken",
|
||||||
"(Ljava/lang/String;)V");
|
"(Ljava/lang/String;)V");
|
||||||
writeIntMethod_ = env->GetMethodID(parcelClass_, "writeInt", "(I)V");
|
write_int_method_ = env->GetMethodID(parcel_class_, "writeInt", "(I)V");
|
||||||
writeStringMethod_ = env->GetMethodID(parcelClass_, "writeString", "(Ljava/lang/String;)V");
|
// writeStringMethod_ = env->GetMethodID(parcel_class_, "writeString",
|
||||||
readExceptionMethod_ = env->GetMethodID(parcelClass_, "readException", "()V");
|
// "(Ljava/lang/String;)V");
|
||||||
readStrongBinderMethod_ = env->GetMethodID(parcelClass_, "readStrongBinder",
|
read_exception_method_ = env->GetMethodID(parcel_class_, "readException", "()V");
|
||||||
"()Landroid/os/IBinder;");
|
read_strong_binder_method_ = env->GetMethodID(parcel_class_, "readStrongBinder",
|
||||||
createStringArray_ = env->GetMethodID(parcelClass_, "createStringArray",
|
"()Landroid/os/IBinder;");
|
||||||
"()[Ljava/lang/String;");
|
// createStringArray_ = env->GetMethodID(parcel_class_, "createStringArray",
|
||||||
|
// "()[Ljava/lang/String;");
|
||||||
|
|
||||||
deadObjectExceptionClass_ = env->FindClass("android/os/DeadObjectException");
|
deadObjectExceptionClass_ = env->FindClass("android/os/DeadObjectException");
|
||||||
if (deadObjectExceptionClass_)
|
if (deadObjectExceptionClass_)
|
||||||
|
|
@ -94,16 +97,16 @@ namespace lspd {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
bridge_service_class_ = (jclass) env->NewGlobalRef(bridge_service_class_);
|
bridge_service_class_ = (jclass) env->NewGlobalRef(bridge_service_class_);
|
||||||
exec_transact_replace_methodID_ = env->GetStaticMethodID(bridge_service_class_,
|
exec_transact_replace_methodID_ = JNI_GetStaticMethodID(env, bridge_service_class_,
|
||||||
"execTransact",
|
"execTransact",
|
||||||
"(IJJI)Z");
|
"(IJJI)Z");
|
||||||
if (!exec_transact_replace_methodID_) {
|
if (!exec_transact_replace_methodID_) {
|
||||||
LOGE("execTransact class not found");
|
LOGE("execTransact class not found");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
ScopedLocalRef<jclass> binderClass(env, env->FindClass("android/os/Binder"));
|
ScopedLocalRef<jclass> binderClass(env, env->FindClass("android/os/Binder"));
|
||||||
exec_transact_backup_methodID_ = env->GetMethodID(binderClass.get(), "execTransact",
|
exec_transact_backup_methodID_ = JNI_GetMethodID(env, binderClass.get(), "execTransact",
|
||||||
"(IJJI)Z");
|
"(IJJI)Z");
|
||||||
auto set_table_override = reinterpret_cast<void (*)(
|
auto set_table_override = reinterpret_cast<void (*)(
|
||||||
JNINativeInterface *)>(DobbySymbolResolver(nullptr,
|
JNINativeInterface *)>(DobbySymbolResolver(nullptr,
|
||||||
|
|
@ -129,32 +132,31 @@ namespace lspd {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
auto bridgeServiceName = env->NewStringUTF(BRIDGE_SERVICE_NAME.data());
|
auto bridgeServiceName = env->NewStringUTF(BRIDGE_SERVICE_NAME.data());
|
||||||
auto bridgeService = JNI_CallStaticObjectMethod(env, serviceManagerClass_,
|
auto bridgeService = JNI_CallStaticObjectMethod(env, service_manager_class_,
|
||||||
getServiceMethod_, bridgeServiceName);
|
get_service_method_, bridgeServiceName);
|
||||||
if (!bridgeService) {
|
if (!bridgeService) {
|
||||||
LOGD("can't get %s", BRIDGE_SERVICE_NAME.data());
|
LOGD("can't get %s", BRIDGE_SERVICE_NAME.data());
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto data = JNI_CallStaticObjectMethod(env, parcelClass_, obtainMethod_);
|
auto data = JNI_CallStaticObjectMethod(env, parcel_class_, obtain_method_);
|
||||||
auto reply = JNI_CallStaticObjectMethod(env, parcelClass_, obtainMethod_);
|
auto reply = JNI_CallStaticObjectMethod(env, parcel_class_, obtain_method_);
|
||||||
|
|
||||||
auto descriptor = env->NewStringUTF(BRIDGE_SERVICE_DESCRIPTOR.data());
|
auto descriptor = env->NewStringUTF(BRIDGE_SERVICE_DESCRIPTOR.data());
|
||||||
JNI_CallVoidMethod(env, data, writeInterfaceTokenMethod_, descriptor);
|
JNI_CallVoidMethod(env, data, write_interface_token_method_, descriptor);
|
||||||
JNI_CallVoidMethod(env, data, writeIntMethod_, BRIDGE_ACTION_GET_BINDER);
|
JNI_CallVoidMethod(env, data, write_int_method_, BRIDGE_ACTION_GET_BINDER);
|
||||||
|
|
||||||
auto res = JNI_CallBooleanMethod(env, bridgeService, transactMethod_,
|
auto res = JNI_CallBooleanMethod(env, bridgeService, transact_method_,
|
||||||
BRIDGE_TRANSACTION_CODE,
|
BRIDGE_TRANSACTION_CODE,
|
||||||
data,
|
data,
|
||||||
reply, 0);
|
reply, 0);
|
||||||
|
|
||||||
jobject service = nullptr;
|
jobject service = nullptr;
|
||||||
if (res) {
|
if (res) {
|
||||||
env->CallVoidMethod(reply, readExceptionMethod_);
|
env->CallVoidMethod(reply, read_exception_method_);
|
||||||
if (!ClearException(env)) {
|
if (!ClearException(env)) {
|
||||||
service = JNI_CallObjectMethod(env, reply, readStrongBinderMethod_);
|
service = JNI_CallObjectMethod(env, reply, read_strong_binder_method_);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
JNI_CallVoidMethod(env, data, recycleMethod_);
|
JNI_CallVoidMethod(env, data, recycleMethod_);
|
||||||
|
|
@ -162,4 +164,17 @@ namespace lspd {
|
||||||
|
|
||||||
return service;
|
return service;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
jobject Service::RequestBinderForSystemServer(JNIEnv *env) {
|
||||||
|
auto bridgeServiceName = env->NewStringUTF(SYSTEM_SERVER_BRIDGE_SERVICE_NAME.data());
|
||||||
|
auto binder = JNI_CallStaticObjectMethod(env, service_manager_class_,
|
||||||
|
get_service_method_, bridgeServiceName);
|
||||||
|
if(!binder) {
|
||||||
|
LOGD("Fail to get binder for system server");
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
auto method = JNI_GetStaticMethodID(env, bridge_service_class_, "getApplicationServiceForSystemServer", "(Landroid/os/IBinder;)Landroid/os/IBinder;");
|
||||||
|
auto app_binder = JNI_CallStaticObjectMethod(env, bridge_service_class_, method, binder);
|
||||||
|
return app_binder;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -13,8 +13,9 @@ using namespace std::literals::string_view_literals;
|
||||||
namespace lspd {
|
namespace lspd {
|
||||||
class Service {
|
class Service {
|
||||||
constexpr static jint BRIDGE_TRANSACTION_CODE = 1598837584;
|
constexpr static jint BRIDGE_TRANSACTION_CODE = 1598837584;
|
||||||
constexpr static auto BRIDGE_SERVICE_DESCRIPTOR = "android.app.IActivityManager"sv;
|
constexpr static auto BRIDGE_SERVICE_DESCRIPTOR = "LSPosed"sv;
|
||||||
constexpr static auto BRIDGE_SERVICE_NAME = "activity"sv;
|
constexpr static auto BRIDGE_SERVICE_NAME = "activity"sv;
|
||||||
|
constexpr static auto SYSTEM_SERVER_BRIDGE_SERVICE_NAME = "serial"sv;
|
||||||
constexpr static jint BRIDGE_ACTION_GET_BINDER = 2;
|
constexpr static jint BRIDGE_ACTION_GET_BINDER = 2;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
@ -32,6 +33,8 @@ namespace lspd {
|
||||||
|
|
||||||
jobject RequestBinder(JNIEnv *env);
|
jobject RequestBinder(JNIEnv *env);
|
||||||
|
|
||||||
|
jobject RequestBinderForSystemServer(JNIEnv *env);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
inline static std::unique_ptr<Service> instance_ = std::make_unique<Service>();
|
inline static std::unique_ptr<Service> instance_ = std::make_unique<Service>();
|
||||||
bool initialized_ = false;
|
bool initialized_ = false;
|
||||||
|
|
@ -52,20 +55,18 @@ namespace lspd {
|
||||||
jclass bridge_service_class_ = nullptr;
|
jclass bridge_service_class_ = nullptr;
|
||||||
jmethodID exec_transact_replace_methodID_ = nullptr;
|
jmethodID exec_transact_replace_methodID_ = nullptr;
|
||||||
|
|
||||||
jclass serviceManagerClass_ = nullptr;
|
jclass service_manager_class_ = nullptr;
|
||||||
jmethodID getServiceMethod_ = nullptr;
|
jmethodID get_service_method_ = nullptr;
|
||||||
|
|
||||||
jmethodID transactMethod_ = nullptr;
|
jmethodID transact_method_ = nullptr;
|
||||||
|
|
||||||
jclass parcelClass_ = nullptr;
|
jclass parcel_class_ = nullptr;
|
||||||
jmethodID obtainMethod_ = nullptr;
|
jmethodID obtain_method_ = nullptr;
|
||||||
jmethodID recycleMethod_ = nullptr;
|
jmethodID recycleMethod_ = nullptr;
|
||||||
jmethodID writeInterfaceTokenMethod_ = nullptr;
|
jmethodID write_interface_token_method_ = nullptr;
|
||||||
jmethodID writeIntMethod_ = nullptr;
|
jmethodID write_int_method_ = nullptr;
|
||||||
jmethodID writeStringMethod_ = nullptr;
|
jmethodID read_exception_method_ = nullptr;
|
||||||
jmethodID readExceptionMethod_ = nullptr;
|
jmethodID read_strong_binder_method_ = nullptr;
|
||||||
jmethodID readStrongBinderMethod_ = nullptr;
|
|
||||||
jmethodID createStringArray_ = nullptr;
|
|
||||||
|
|
||||||
jclass deadObjectExceptionClass_ = nullptr;
|
jclass deadObjectExceptionClass_ = nullptr;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -104,28 +104,12 @@ public class Main implements KeepAll {
|
||||||
return getEdxpImpl().getVariant();
|
return getEdxpImpl().getVariant();
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void waitSystemService(String name) {
|
|
||||||
while (android.os.ServiceManager.getService(name) == null) {
|
|
||||||
try {
|
|
||||||
Log.i(TAG, "service " + name + " is not started, wait 1s.");
|
|
||||||
Thread.sleep(1000);
|
|
||||||
} catch (InterruptedException e) {
|
|
||||||
Log.i(TAG, Log.getStackTraceString(e));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void main(String[] args) {
|
public static void main(String[] args) {
|
||||||
for (String arg : args) {
|
for (String arg : args) {
|
||||||
if (arg.equals("--debug")) {
|
if (arg.equals("--debug")) {
|
||||||
DdmHandleAppName.setAppName("lspd", 0);
|
DdmHandleAppName.setAppName("lspd", 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
waitSystemService("package");
|
|
||||||
waitSystemService("activity");
|
|
||||||
waitSystemService(Context.USER_SERVICE);
|
|
||||||
waitSystemService(Context.APP_OPS_SERVICE);
|
|
||||||
|
|
||||||
ServiceManager.start();
|
ServiceManager.start();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -9,6 +9,7 @@ import android.os.Parcel;
|
||||||
import android.os.RemoteException;
|
import android.os.RemoteException;
|
||||||
import android.os.ServiceManager;
|
import android.os.ServiceManager;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
|
import android.os.Process;
|
||||||
|
|
||||||
import androidx.annotation.Keep;
|
import androidx.annotation.Keep;
|
||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
|
|
@ -22,7 +23,7 @@ import static io.github.lsposed.lspd.service.ServiceManager.TAG;
|
||||||
|
|
||||||
public class BridgeService {
|
public class BridgeService {
|
||||||
private static final int TRANSACTION_CODE = ('_' << 24) | ('L' << 16) | ('S' << 8) | 'P';
|
private static final int TRANSACTION_CODE = ('_' << 24) | ('L' << 16) | ('S' << 8) | 'P';
|
||||||
private static final String DESCRIPTOR = "android.app.IActivityManager";
|
private static final String DESCRIPTOR = "LSPosed";
|
||||||
private static final String SERVICE_NAME = "activity";
|
private static final String SERVICE_NAME = "activity";
|
||||||
|
|
||||||
enum ACTION {
|
enum ACTION {
|
||||||
|
|
@ -194,6 +195,7 @@ public class BridgeService {
|
||||||
data.enforceInterface(DESCRIPTOR);
|
data.enforceInterface(DESCRIPTOR);
|
||||||
|
|
||||||
ACTION action = ACTION.values()[data.readInt()];
|
ACTION action = ACTION.values()[data.readInt()];
|
||||||
|
|
||||||
Log.d(TAG, "onTransact: action=" + action + ", callingUid=" + Binder.getCallingUid() + ", callingPid=" + Binder.getCallingPid());
|
Log.d(TAG, "onTransact: action=" + action + ", callingUid=" + Binder.getCallingUid() + ", callingPid=" + Binder.getCallingPid());
|
||||||
|
|
||||||
switch (action) {
|
switch (action) {
|
||||||
|
|
@ -264,4 +266,17 @@ public class BridgeService {
|
||||||
|
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Keep
|
||||||
|
public static IBinder getApplicationServiceForSystemServer(IBinder binder) {
|
||||||
|
if (binder == null) return null;
|
||||||
|
try {
|
||||||
|
ILSPosedService service = ILSPosedService.Stub.asInterface(binder);
|
||||||
|
ILSPApplicationService applicationService = service.requestApplicationService(Process.myUid(), Process.myPid());
|
||||||
|
if (applicationService != null) applicationService.asBinder();
|
||||||
|
} catch (Throwable e) {
|
||||||
|
Log.e(TAG, Log.getStackTraceString(e));
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,6 @@ import android.os.RemoteException;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
import android.util.Pair;
|
import android.util.Pair;
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.concurrent.ConcurrentHashMap;
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
|
|
||||||
|
|
@ -22,6 +21,7 @@ public class LSPApplicationService extends ILSPApplicationService.Stub {
|
||||||
handles.add(handle);
|
handles.add(handle);
|
||||||
int uid = Binder.getCallingUid();
|
int uid = Binder.getCallingUid();
|
||||||
int pid = Binder.getCallingPid();
|
int pid = Binder.getCallingPid();
|
||||||
|
|
||||||
cache.add(new Pair<>(uid, pid));
|
cache.add(new Pair<>(uid, pid));
|
||||||
handle.linkToDeath(new DeathRecipient() {
|
handle.linkToDeath(new DeathRecipient() {
|
||||||
@Override
|
@Override
|
||||||
|
|
|
||||||
|
|
@ -11,24 +11,6 @@ import android.util.Log;
|
||||||
import static io.github.lsposed.lspd.service.ServiceManager.TAG;
|
import static io.github.lsposed.lspd.service.ServiceManager.TAG;
|
||||||
|
|
||||||
public class LSPosedService extends ILSPosedService.Stub {
|
public class LSPosedService extends ILSPosedService.Stub {
|
||||||
LSPosedService() {
|
|
||||||
BridgeService.send(this, new BridgeService.Listener() {
|
|
||||||
@Override
|
|
||||||
public void onSystemServerRestarted() {
|
|
||||||
Log.w(TAG, "system restarted...");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onResponseFromBridgeService(boolean response) {
|
|
||||||
if (response) {
|
|
||||||
Log.i(TAG, "sent service to bridge");
|
|
||||||
} else {
|
|
||||||
Log.w(TAG, "no response from bridge");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ILSPApplicationService requestApplicationService(int uid, int pid) {
|
public ILSPApplicationService requestApplicationService(int uid, int pid) {
|
||||||
if (Binder.getCallingUid() != 1000) {
|
if (Binder.getCallingUid() != 1000) {
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
package io.github.lsposed.lspd.service;
|
package io.github.lsposed.lspd.service;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
import android.os.Looper;
|
import android.os.Looper;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
|
|
||||||
|
|
@ -9,6 +10,18 @@ public class ServiceManager {
|
||||||
private static LSPApplicationService applicationService = null;
|
private static LSPApplicationService applicationService = null;
|
||||||
private static LSPManagerService managerService = null;
|
private static LSPManagerService managerService = null;
|
||||||
public static final String TAG = "LSPosedService";
|
public static final String TAG = "LSPosedService";
|
||||||
|
|
||||||
|
private static void waitSystemService(String name) {
|
||||||
|
while (android.os.ServiceManager.getService(name) == null) {
|
||||||
|
try {
|
||||||
|
Log.i(TAG, "service " + name + " is not started, wait 1s.");
|
||||||
|
Thread.sleep(1000);
|
||||||
|
} catch (InterruptedException e) {
|
||||||
|
Log.i(TAG, Log.getStackTraceString(e));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// call by ourselves
|
// call by ourselves
|
||||||
public static void start() {
|
public static void start() {
|
||||||
Log.i(TAG, "starting server...");
|
Log.i(TAG, "starting server...");
|
||||||
|
|
@ -18,6 +31,30 @@ public class ServiceManager {
|
||||||
moduleService = new LSPModuleService();
|
moduleService = new LSPModuleService();
|
||||||
applicationService = new LSPApplicationService();
|
applicationService = new LSPApplicationService();
|
||||||
managerService = new LSPManagerService();
|
managerService = new LSPManagerService();
|
||||||
|
|
||||||
|
android.os.ServiceManager.addService("serial", mainService);
|
||||||
|
|
||||||
|
waitSystemService("package");
|
||||||
|
waitSystemService("activity");
|
||||||
|
waitSystemService(Context.USER_SERVICE);
|
||||||
|
waitSystemService(Context.APP_OPS_SERVICE);
|
||||||
|
|
||||||
|
BridgeService.send(mainService, new BridgeService.Listener() {
|
||||||
|
@Override
|
||||||
|
public void onSystemServerRestarted() {
|
||||||
|
Log.w(TAG, "system restarted...");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onResponseFromBridgeService(boolean response) {
|
||||||
|
if (response) {
|
||||||
|
Log.i(TAG, "sent service to bridge");
|
||||||
|
} else {
|
||||||
|
Log.w(TAG, "no response from bridge");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
Looper.loop();
|
Looper.loop();
|
||||||
|
|
||||||
Log.i(TAG, "server exited");
|
Log.i(TAG, "server exited");
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue