Skip to content

Commit

Permalink
[app/services] misc for noroot support
Browse files Browse the repository at this point in the history
  • Loading branch information
Tornaco committed Apr 1, 2022
1 parent f8ff438 commit 41bf3d1
Show file tree
Hide file tree
Showing 12 changed files with 267 additions and 52 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package github.tornaco.android.thanos.core;

import github.tornaco.android.thanos.core.IThanos;


import android.content.IntentFilter;

interface IThanosProvider {
IThanos getThanos();
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,127 @@
/*
* This file is auto-generated. DO NOT MODIFY.
*/
package github.tornaco.android.thanos.core;
public interface IThanosProvider extends android.os.IInterface
{
/** Default implementation for IThanosProvider. */
public static class Default implements github.tornaco.android.thanos.core.IThanosProvider
{
@Override public github.tornaco.android.thanos.core.IThanos getThanos() throws android.os.RemoteException
{
return null;
}
@Override
public android.os.IBinder asBinder() {
return null;
}
}
/** Local-side IPC implementation stub class. */
public static abstract class Stub extends android.os.Binder implements github.tornaco.android.thanos.core.IThanosProvider
{
private static final java.lang.String DESCRIPTOR = "github.tornaco.android.thanos.core.IThanosProvider";
/** Construct the stub at attach it to the interface. */
public Stub()
{
this.attachInterface(this, DESCRIPTOR);
}
/**
* Cast an IBinder object into an github.tornaco.android.thanos.core.IThanosProvider interface,
* generating a proxy if needed.
*/
public static github.tornaco.android.thanos.core.IThanosProvider asInterface(android.os.IBinder obj)
{
if ((obj==null)) {
return null;
}
android.os.IInterface iin = obj.queryLocalInterface(DESCRIPTOR);
if (((iin!=null)&&(iin instanceof github.tornaco.android.thanos.core.IThanosProvider))) {
return ((github.tornaco.android.thanos.core.IThanosProvider)iin);
}
return new github.tornaco.android.thanos.core.IThanosProvider.Stub.Proxy(obj);
}
@Override public android.os.IBinder asBinder()
{
return this;
}
@Override public boolean onTransact(int code, android.os.Parcel data, android.os.Parcel reply, int flags) throws android.os.RemoteException
{
java.lang.String descriptor = DESCRIPTOR;
switch (code)
{
case INTERFACE_TRANSACTION:
{
reply.writeString(descriptor);
return true;
}
case TRANSACTION_getThanos:
{
data.enforceInterface(descriptor);
github.tornaco.android.thanos.core.IThanos _result = this.getThanos();
reply.writeNoException();
reply.writeStrongBinder((((_result!=null))?(_result.asBinder()):(null)));
return true;
}
default:
{
return super.onTransact(code, data, reply, flags);
}
}
}
private static class Proxy implements github.tornaco.android.thanos.core.IThanosProvider
{
private android.os.IBinder mRemote;
Proxy(android.os.IBinder remote)
{
mRemote = remote;
}
@Override public android.os.IBinder asBinder()
{
return mRemote;
}
public java.lang.String getInterfaceDescriptor()
{
return DESCRIPTOR;
}
@Override public github.tornaco.android.thanos.core.IThanos getThanos() throws android.os.RemoteException
{
android.os.Parcel _data = android.os.Parcel.obtain();
android.os.Parcel _reply = android.os.Parcel.obtain();
github.tornaco.android.thanos.core.IThanos _result;
try {
_data.writeInterfaceToken(DESCRIPTOR);
boolean _status = mRemote.transact(Stub.TRANSACTION_getThanos, _data, _reply, 0);
if (!_status && getDefaultImpl() != null) {
return getDefaultImpl().getThanos();
}
_reply.readException();
_result = github.tornaco.android.thanos.core.IThanos.Stub.asInterface(_reply.readStrongBinder());
}
finally {
_reply.recycle();
_data.recycle();
}
return _result;
}
public static github.tornaco.android.thanos.core.IThanosProvider sDefaultImpl;
}
static final int TRANSACTION_getThanos = (android.os.IBinder.FIRST_CALL_TRANSACTION + 0);
public static boolean setDefaultImpl(github.tornaco.android.thanos.core.IThanosProvider impl) {
// Only one user of this interface can use this function
// at a time. This is a heuristic to detect if two different
// users in the same process use this function.
if (Stub.Proxy.sDefaultImpl != null) {
throw new IllegalStateException("setDefaultImpl() called twice");
}
if (impl != null) {
Stub.Proxy.sDefaultImpl = impl;
return true;
}
return false;
}
public static github.tornaco.android.thanos.core.IThanosProvider getDefaultImpl() {
return Stub.Proxy.sDefaultImpl;
}
}
public github.tornaco.android.thanos.core.IThanos getThanos() throws android.os.RemoteException;
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@
import android.os.Parcel;
import android.os.RemoteException;
import android.os.ServiceManager;
import android.util.Log;

import com.elvishew.xlog.XLog;

Expand All @@ -18,6 +17,7 @@ public class ThanosManagerNative {
private static IThanos localService;

public static void setLocalService(IThanos localService) {
XLog.w("ThanosManagerNative, setLocalService: " + localService);
ThanosManagerNative.localService = localService;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -235,6 +235,10 @@ public static boolean isSystemCall(long uid) {
|| (uid > UserHandle.PER_USER_RANGE && (uid % UserHandle.PER_USER_RANGE == 1000));
}

public static boolean isShell(int uid) {
return uid == 2000;
}

public static boolean isSharedUserIdSystem(String sharedUid) {
return ObjectsUtils.equals(sharedUid, github.tornaco.android.thanos.core.pm.PackageManager.sharedUserIdOfSystem());
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

import android.os.Bundle;

import androidx.annotation.NonNull;
import androidx.preference.Preference;
import androidx.preference.SwitchPreferenceCompat;

import github.tornaco.android.thanos.BasePreferenceFragmentCompat;
Expand Down Expand Up @@ -78,14 +80,15 @@ protected void onBindPreferences() {
AppPreference.setProcessManagerV2Enabled(requireContext(), checked);
return true;
});
}

@Override
public void onStart() {
super.onStart();

if (ServiceBindings.INSTANCE.checkPermission(1)) {
ServiceBindings.INSTANCE.bindUserService();
}
findPreference(getString(R.string.key_rootless_support)).setOnPreferenceClickListener(new Preference.OnPreferenceClickListener() {
@Override
public boolean onPreferenceClick(@NonNull Preference preference) {
if (ServiceBindings.INSTANCE.checkPermission(1)) {
ServiceBindings.INSTANCE.bindUserService();
}
return false;
}
});
}
}
1 change: 1 addition & 0 deletions android/app/src/main/res/values/pref_keys.xml
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
<string name="key_enable_power_save" translatable="false">key_enable_power_save</string>
<string name="key_enable_battery_drain_app_reminging" translatable="false">key_enable_battery_drain_app_reminging</string>
<string name="key_process_manage_ui_v2" translatable="false">key_process_manage_ui_v2</string>
<string name="key_rootless_support" translatable="false">key_rootless_support</string>

<string name="key_about" translatable="false">key_about</string>
<string name="key_build_info_server" translatable="false">key_build_info_server</string>
Expand Down
5 changes: 5 additions & 0 deletions android/app/src/main/res/xml/dev_settings_pref.xml
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,11 @@
app:persistent="false"
app:title="New Process manager UI" />

<Preference
app:key="@string/key_rootless_support"
app:persistent="false"
app:title="NoRoot support" />

<SwitchPreferenceCompat
app:key="@string/key_enable_global_white_list"
app:persistent="false"
Expand Down
2 changes: 1 addition & 1 deletion android/internal/Thanox-Internal
1 change: 1 addition & 0 deletions android/modules/module_noroot_support/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,7 @@ dependencies {
implementation(project(":modules:module_common"))
implementation(project(":modules:module_compose_common"))
implementation(project(":android_framework:base"))
implementation(project(":android_framework:services"))

compileOnly(project(":annotation_processors:permission-requester-annotation"))
annotationProcessor(project(":annotation_processors:permission-requester-compiler"))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,8 @@ import android.content.pm.PackageManager.PERMISSION_GRANTED
import android.os.IBinder
import com.elvishew.xlog.XLog
import github.tornaco.android.thanos.BuildProp
import github.tornaco.android.thanos.core.plus.ICallback
import github.tornaco.android.thanos.core.plus.RR
import github.tornaco.android.thanos.core.IThanosProvider
import github.tornaco.android.thanos.core.app.ThanosManagerNative
import rikka.shizuku.Shizuku

object ServiceBindings {
Expand All @@ -36,7 +36,7 @@ object ServiceBindings {
}

private val userServiceArgs = Shizuku.UserServiceArgs(
ComponentName(BuildProp.THANOS_APP_PKG_NAME, UserService::class.java.name)
ComponentName(BuildProp.THANOS_APP_PKG_NAME, ThanosProviderService::class.java.name)
).daemon(false)
.processNameSuffix("noroot_service")
.debuggable(BuildProp.THANOS_BUILD_DEBUG)
Expand All @@ -49,8 +49,8 @@ object ServiceBindings {
val res = StringBuilder()
res.append("onServiceConnected: ").append(componentName.className).append('\n')
if (binder != null && binder.pingBinder()) {
val service: ICallback = ICallback.Stub.asInterface(binder)
service.onRes(RR(0, "Hello", "World"))
val service: IThanosProvider = IThanosProvider.Stub.asInterface(binder)
ThanosManagerNative.setLocalService(service.thanos)
} else {
XLog.e("ServiceBindings, Invalid binder received")
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
/*
* (C) Copyright 2022 Thanox
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/

package github.tornaco.thanos.android.noroot;


import android.content.BroadcastReceiver;
import android.content.ContentResolver;
import android.content.Context;
import android.content.ContextWrapper;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Binder;
import android.os.Handler;
import android.os.Process;

import androidx.annotation.Nullable;

import com.elvishew.xlog.XLog;

import github.tornaco.android.thanos.core.IThanos;
import github.tornaco.android.thanos.core.IThanosProvider;
import github.tornaco.android.thanos.core.app.ThanosManagerNative;
import github.tornaco.android.thanos.services.BootStrap;

public class ThanosProviderService extends IThanosProvider.Stub {
public ThanosProviderService() {
}

@Override
public IThanos getThanos() {
if (ThanosManagerNative.getLocalService() == null) {
installThanosService();
}
return ThanosManagerNative.getLocalService();
}

private void installThanosService() {
XLog.w("installThanosService: " + " --- p" + Process.myPid() + " u" + Process.myUid());
XLog.w("installThanosService, currentApplication: " + BootStrap.currentApplication());
long ident = Binder.clearCallingIdentity();
try {
BootStrap.main("Shizuku", new String[0]);
BootStrap.start(new ShellProcessContext(BootStrap.currentApplication()));
BootStrap.ready();
} catch (Throwable e) {
XLog.e("********* ThanosProviderService#installThanosService *********", e);
}
Binder.restoreCallingIdentity(ident);
}

static class ShellProcessContext extends ContextWrapper {
public ShellProcessContext(Context base) {
super(base);
}

@Override
public Intent registerReceiver(@Nullable BroadcastReceiver receiver, IntentFilter filter) {
XLog.w("ShellProcessContext, drop registerReceiver call..." + receiver);
return new Intent();
}

@Override
public Intent registerReceiver(@Nullable BroadcastReceiver receiver, IntentFilter filter, int flags) {
XLog.w("ShellProcessContext, drop registerReceiver call..." + receiver);
return new Intent();
}

@Override
public Intent registerReceiver(@Nullable BroadcastReceiver receiver, IntentFilter filter, @Nullable String broadcastPermission, @Nullable Handler scheduler) {
XLog.w("ShellProcessContext, drop registerReceiver call..." + receiver);
return new Intent();
}

@Override
public Intent registerReceiver(@Nullable BroadcastReceiver receiver, IntentFilter filter, @Nullable String broadcastPermission, @Nullable Handler scheduler, int flags) {
XLog.w("ShellProcessContext, drop registerReceiver call..." + receiver);
return new Intent();
}

@Override
public ContentResolver getContentResolver() {
XLog.w("ShellProcessContext, drop getContentResolver call...");
return null;
}
}
}
Loading

0 comments on commit 41bf3d1

Please sign in to comment.