[core] Send IApplicationThread to daemon

This commit is contained in:
LoveSy 2021-05-21 01:53:09 +08:00 committed by LoveSy
parent 97190be928
commit 4e40cf9802
16 changed files with 224 additions and 184 deletions

View File

@ -5,6 +5,5 @@ import org.lsposed.lspd.service.ILSPApplicationService;
interface ILSPosedService { interface ILSPosedService {
ILSPApplicationService requestApplicationService(int uid, int pid, String processName, IBinder heartBeat) = 1; ILSPApplicationService requestApplicationService(int uid, int pid, String processName, IBinder heartBeat) = 1;
oneway void dispatchPackageChanged(in Intent intent) = 2; oneway void dispatchSystemServerContext(in IBinder activityThread, in IBinder activityToken) = 4;
oneway void dispatchBootCompleted(in Intent intent) = 3;
} }

View File

@ -21,8 +21,10 @@ package org.lsposed.lspd.service;
import android.app.IActivityManager; import android.app.IActivityManager;
import android.app.IApplicationThread; import android.app.IApplicationThread;
import android.app.IServiceConnection;
import android.content.IIntentReceiver; import android.content.IIntentReceiver;
import android.content.Intent; import android.content.Intent;
import android.content.IntentFilter;
import android.os.Build; import android.os.Build;
import android.os.Bundle; import android.os.Bundle;
import android.os.IBinder; import android.os.IBinder;
@ -34,8 +36,9 @@ import static org.lsposed.lspd.service.ServiceManager.TAG;
public class ActivityManagerService { public class ActivityManagerService {
private static IActivityManager am = null; private static IActivityManager am = null;
private static IBinder binder = null; private static IBinder binder = null;
private static IApplicationThread thread = null;
private static IBinder token = null;
private static final IBinder.DeathRecipient deathRecipient = new IBinder.DeathRecipient() { private static final IBinder.DeathRecipient deathRecipient = new IBinder.DeathRecipient() {
@Override @Override
@ -44,6 +47,8 @@ public class ActivityManagerService {
binder.unlinkToDeath(this, 0); binder.unlinkToDeath(this, 0);
binder = null; binder = null;
am = null; am = null;
thread = null;
token = null;
} }
}; };
@ -61,16 +66,16 @@ public class ActivityManagerService {
return am; return am;
} }
public static int broadcastIntentWithFeature(IApplicationThread caller, String callingFeatureId, public static int broadcastIntentWithFeature(String callingFeatureId,
Intent intent, String resolvedType, IIntentReceiver resultTo, int resultCode, Intent intent, String resolvedType, IIntentReceiver resultTo, int resultCode,
String resultData, Bundle map, String[] requiredPermissions, String resultData, Bundle map, String[] requiredPermissions,
int appOp, Bundle options, boolean serialized, boolean sticky, int userId) throws RemoteException { int appOp, Bundle options, boolean serialized, boolean sticky, int userId) throws RemoteException {
IActivityManager am = getActivityManager(); IActivityManager am = getActivityManager();
if (am == null) return -1; if (am == null || thread == null) return -1;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
return am.broadcastIntentWithFeature(caller, callingFeatureId, intent, resolvedType, resultTo, resultCode, resultData, map, requiredPermissions, appOp, options, serialized, sticky, userId); return am.broadcastIntentWithFeature(thread, callingFeatureId, intent, resolvedType, resultTo, resultCode, resultData, map, requiredPermissions, appOp, options, serialized, sticky, userId);
} else { } else {
return am.broadcastIntent(caller, intent, resolvedType, resultTo, resultCode, resultData, map, requiredPermissions, appOp, options, serialized, sticky, userId); return am.broadcastIntent(thread, intent, resolvedType, resultTo, resultCode, resultData, map, requiredPermissions, appOp, options, serialized, sticky, userId);
} }
} }
@ -85,4 +90,36 @@ public class ActivityManagerService {
if (am == null) return false; if (am == null) return false;
return am.startUserInBackground(userId); return am.startUserInBackground(userId);
} }
public static Intent registerReceiver(String callerPackage,
String callingFeatureId, IIntentReceiver receiver, IntentFilter filter,
String requiredPermission, int userId, int flags) throws RemoteException {
IActivityManager am = getActivityManager();
if (am == null || thread == null) return null;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
return am.registerReceiverWithFeature(thread, callerPackage, callingFeatureId, receiver, filter, requiredPermission, userId, flags);
} else {
return am.registerReceiver(thread, callerPackage, receiver, filter, requiredPermission, userId, flags);
}
}
public static int bindService(Intent service,
String resolvedType, IServiceConnection connection, int flags,
String callingPackage, int userId) {
IActivityManager am = getActivityManager();
if (am == null || thread == null) return -1;
return am.bindService(thread, token, service, resolvedType, connection, flags, callingPackage, userId);
}
public static boolean unbindService(IServiceConnection connection) {
IActivityManager am = getActivityManager();
if (am == null) return false;
return am.unbindService(connection);
}
public static void onSystemServerContext(IApplicationThread thread, IBinder token) {
ActivityManagerService.thread = thread;
ActivityManagerService.token = token;
}
} }

View File

@ -1,45 +0,0 @@
package org.lsposed.lspd.service;
import android.annotation.SuppressLint;
import android.app.ActivityThread;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Handler;
import android.os.HandlerThread;
import java.lang.reflect.Method;
import org.lsposed.lspd.util.Utils;
public class BootReceiver {
public static void register(BroadcastReceiver receiver) {
ActivityThread activityThread = ActivityThread.currentActivityThread();
if (activityThread == null) {
Utils.logW("ActivityThread is null");
return;
}
Context context = activityThread.getSystemContext();
if (context == null) {
Utils.logW("context is null");
return;
}
IntentFilter intentFilter = new IntentFilter();
intentFilter.addAction(Intent.ACTION_LOCKED_BOOT_COMPLETED);
HandlerThread thread = new HandlerThread("lspd-BootReceiver");
thread.start();
Handler handler = new Handler(thread.getLooper());
try {
@SuppressLint("DiscouragedPrivateApi")
Method method = Context.class.getDeclaredMethod("registerReceiver", BroadcastReceiver.class, IntentFilter.class, String.class, Handler.class);
method.invoke(context, receiver, intentFilter, null, handler);
Utils.logI("registered package receiver");
} catch (Throwable e) {
Utils.logW("registerReceiver failed", e);
}
}
}

View File

@ -19,9 +19,15 @@
package org.lsposed.lspd.service; package org.lsposed.lspd.service;
import static android.content.Context.BIND_AUTO_CREATE;
import android.app.ActivityThread;
import android.app.IApplicationThread;
import android.content.BroadcastReceiver; import android.content.BroadcastReceiver;
import android.content.ComponentName;
import android.content.Context; import android.content.Context;
import android.content.Intent; import android.content.Intent;
import android.content.ServiceConnection;
import android.os.Binder; import android.os.Binder;
import android.os.IBinder; import android.os.IBinder;
import android.os.Parcel; import android.os.Parcel;
@ -46,6 +52,7 @@ import java.util.ArrayList;
import java.util.Map; import java.util.Map;
import static hidden.HiddenApiBridge.Binder_allowBlocking; import static hidden.HiddenApiBridge.Binder_allowBlocking;
import static hidden.HiddenApiBridge.Context_getActivityToken;
import static org.lsposed.lspd.service.ServiceManager.TAG; import static org.lsposed.lspd.service.ServiceManager.TAG;
public class BridgeService { public class BridgeService {
@ -191,32 +198,7 @@ public class BridgeService {
} }
var token = Binder.clearCallingIdentity(); var token = Binder.clearCallingIdentity();
if (serviceBinder == null) { if (serviceBinder != null) {
PackageReceiver.register(new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
if (service == null) {
Log.e(TAG, "Service is dead, missing package changed: " + intent);
return;
}
try {
service.dispatchPackageChanged(intent);
} catch (RemoteException e) {
Log.e(TAG, Log.getStackTraceString(e));
}
}
});
BootReceiver.register(new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
try {
service.dispatchBootCompleted(intent);
} catch (RemoteException e) {
Log.e(TAG, Log.getStackTraceString(e));
}
}
});
} else {
serviceBinder.unlinkToDeath(serviceRecipient, 0); serviceBinder.unlinkToDeath(serviceRecipient, 0);
} }
Binder.restoreCallingIdentity(token); Binder.restoreCallingIdentity(token);
@ -228,7 +210,13 @@ public class BridgeService {
} catch (Throwable e) { } catch (Throwable e) {
Log.e(TAG, "service link to death: ", e); Log.e(TAG, "service link to death: ", e);
} }
try {
IApplicationThread at = ActivityThread.currentActivityThread().getApplicationThread();
Context ct = ActivityThread.currentActivityThread().getSystemContext();
service.dispatchSystemServerContext(at.asBinder(), Context_getActivityToken(ct));
} catch (Throwable e) {
Log.e(TAG, "dispatch context: ", e);
}
Log.i(TAG, "binder received"); Log.i(TAG, "binder received");
} }

View File

@ -19,13 +19,13 @@
package org.lsposed.lspd.service; package org.lsposed.lspd.service;
import android.os.Binder;
import android.os.IBinder; import android.os.IBinder;
import android.os.ParcelFileDescriptor; import android.os.ParcelFileDescriptor;
import android.os.RemoteException; import android.os.RemoteException;
import android.util.Log; import android.util.Log;
import android.util.Pair; import android.util.Pair;
import java.util.Map;
import java.util.Set; import java.util.Set;
import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentHashMap;
@ -34,7 +34,7 @@ import static org.lsposed.lspd.service.ServiceManager.TAG;
public class LSPApplicationService extends ILSPApplicationService.Stub { public class LSPApplicationService extends ILSPApplicationService.Stub {
// <uid, pid> // <uid, pid>
private final static Set<Pair<Integer, Integer>> cache = ConcurrentHashMap.newKeySet(); private final static Set<Pair<Integer, Integer>> cache = ConcurrentHashMap.newKeySet();
private final static Set<IBinder> handles = ConcurrentHashMap.newKeySet(); private final static Map<Integer, IBinder> handles = new ConcurrentHashMap<>();
private final static Set<IBinder.DeathRecipient> recipients = ConcurrentHashMap.newKeySet(); private final static Set<IBinder.DeathRecipient> recipients = ConcurrentHashMap.newKeySet();
public boolean registerHeartBeat(int uid, int pid, IBinder handle) { public boolean registerHeartBeat(int uid, int pid, IBinder handle) {
@ -44,14 +44,14 @@ public class LSPApplicationService extends ILSPApplicationService.Stub {
public void binderDied() { public void binderDied() {
Log.d(TAG, "pid=" + pid + " uid=" + uid + " is dead."); Log.d(TAG, "pid=" + pid + " uid=" + uid + " is dead.");
cache.remove(new Pair<>(uid, pid)); cache.remove(new Pair<>(uid, pid));
handles.remove(handle); handles.remove(pid, handle);
handle.unlinkToDeath(this, 0); handle.unlinkToDeath(this, 0);
recipients.remove(this); recipients.remove(this);
} }
}; };
recipients.add(recipient); recipients.add(recipient);
handle.linkToDeath(recipient, 0); handle.linkToDeath(recipient, 0);
handles.add(handle); handles.put(pid, handle);
cache.add(new Pair<>(uid, pid)); cache.add(new Pair<>(uid, pid));
return true; return true;
} catch (RemoteException e) { } catch (RemoteException e) {
@ -69,7 +69,7 @@ public class LSPApplicationService extends ILSPApplicationService.Stub {
@Override @Override
public String[] getModulesList(String processName) throws RemoteException { public String[] getModulesList(String processName) throws RemoteException {
ensureRegistered(); ensureRegistered();
int callingUid = Binder.getCallingUid(); int callingUid = getCallingUid();
if (callingUid == 1000 && processName.equals("android")) { if (callingUid == 1000 && processName.equals("android")) {
return ConfigManager.getInstance().getModulesPathForSystemServer(); return ConfigManager.getInstance().getModulesPathForSystemServer();
} }
@ -79,7 +79,7 @@ public class LSPApplicationService extends ILSPApplicationService.Stub {
@Override @Override
public String getPrefsPath(String packageName) throws RemoteException { public String getPrefsPath(String packageName) throws RemoteException {
ensureRegistered(); ensureRegistered();
return ConfigManager.getInstance().getPrefsPath(packageName, Binder.getCallingUid()); return ConfigManager.getInstance().getPrefsPath(packageName, getCallingUid());
} }
@Override @Override
@ -91,17 +91,21 @@ public class LSPApplicationService extends ILSPApplicationService.Stub {
@Override @Override
public IBinder requestModuleBinder() throws RemoteException { public IBinder requestModuleBinder() throws RemoteException {
ensureRegistered(); ensureRegistered();
if (ConfigManager.getInstance().isModule(Binder.getCallingUid())) { if (ConfigManager.getInstance().isModule(getCallingUid())) {
ConfigManager.getInstance().ensureModulePrefsPermission(Binder.getCallingUid()); ConfigManager.getInstance().ensureModulePrefsPermission(getCallingUid());
return ServiceManager.getModuleService(); return ServiceManager.getModuleService();
} else return null; }
return null;
} }
@Override @Override
public IBinder requestManagerBinder() throws RemoteException { public IBinder requestManagerBinder() throws RemoteException {
ensureRegistered(); ensureRegistered();
if (ConfigManager.getInstance().isManager(Binder.getCallingUid())) if (ConfigManager.getInstance().isManager(getCallingUid())) {
return ServiceManager.getManagerService(); var service = ServiceManager.getManagerService();
service.new ManagerGuard(handles.get(getCallingPid()));
return service;
}
return null; return null;
} }
@ -110,7 +114,7 @@ public class LSPApplicationService extends ILSPApplicationService.Stub {
} }
private void ensureRegistered() throws RemoteException { private void ensureRegistered() throws RemoteException {
if (!hasRegister(Binder.getCallingUid(), Binder.getCallingPid())) if (!hasRegister(getCallingUid(), getCallingPid()))
throw new RemoteException("Not registered"); throw new RemoteException("Not registered");
} }
} }

View File

@ -19,12 +19,16 @@
package org.lsposed.lspd.service; package org.lsposed.lspd.service;
import android.app.IApplicationThread;
import android.content.ComponentName; import android.content.ComponentName;
import android.content.IIntentReceiver;
import android.content.Intent; import android.content.Intent;
import android.content.IntentFilter;
import android.content.pm.ApplicationInfo; import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager; import android.content.pm.PackageManager;
import android.net.Uri; import android.net.Uri;
import android.os.Binder; import android.os.Binder;
import android.os.Bundle;
import android.os.IBinder; import android.os.IBinder;
import android.os.RemoteException; import android.os.RemoteException;
import android.util.Log; import android.util.Log;
@ -67,9 +71,8 @@ public class LSPosedService extends ILSPosedService.Stub {
* However, PACKAGE_REMOVED will be triggered by `pm hide`, so we use UID_REMOVED instead. * However, PACKAGE_REMOVED will be triggered by `pm hide`, so we use UID_REMOVED instead.
*/ */
@Override synchronized public void dispatchPackageChanged(Intent intent) {
public void dispatchPackageChanged(Intent intent) throws RemoteException { if (intent == null) return;
if (Binder.getCallingUid() != 1000 || intent == null) return;
int uid = intent.getIntExtra(Intent.EXTRA_UID, AID_NOBODY); int uid = intent.getIntExtra(Intent.EXTRA_UID, AID_NOBODY);
if (uid == AID_NOBODY || uid <= 0) return; if (uid == AID_NOBODY || uid <= 0) return;
int userId = intent.getIntExtra("android.intent.extra.user_handle", USER_NULL); int userId = intent.getIntExtra("android.intent.extra.user_handle", USER_NULL);
@ -78,7 +81,13 @@ public class LSPosedService extends ILSPosedService.Stub {
Uri uri = intent.getData(); Uri uri = intent.getData();
String moduleName = (uri != null) ? uri.getSchemeSpecificPart() : null; String moduleName = (uri != null) ? uri.getSchemeSpecificPart() : null;
ApplicationInfo applicationInfo = moduleName != null ? PackageService.getApplicationInfo(moduleName, PackageManager.GET_META_DATA, 0) : null; ApplicationInfo applicationInfo = null;
if (moduleName != null) {
try {
applicationInfo = PackageService.getApplicationInfo(moduleName, PackageManager.GET_META_DATA, 0);
} catch (Throwable ignored) {
}
}
boolean isXposedModule = applicationInfo != null && boolean isXposedModule = applicationInfo != null &&
applicationInfo.metaData != null && applicationInfo.metaData != null &&
@ -137,7 +146,7 @@ public class LSPosedService extends ILSPosedService.Stub {
broadcastIntent.setComponent(ComponentName.unflattenFromString(ConfigManager.getInstance().getManagerPackageName() + "/.receivers.ServiceReceiver")); broadcastIntent.setComponent(ComponentName.unflattenFromString(ConfigManager.getInstance().getManagerPackageName() + "/.receivers.ServiceReceiver"));
try { try {
ActivityManagerService.broadcastIntentWithFeature(null, null, broadcastIntent, ActivityManagerService.broadcastIntentWithFeature(null, broadcastIntent,
null, null, 0, null, null, null, null, 0, null, null,
null, -1, null, true, false, null, -1, null, true, false,
0); 0);
@ -158,8 +167,55 @@ public class LSPosedService extends ILSPosedService.Stub {
} }
@Override synchronized public void dispatchBootCompleted(Intent intent) {
public void dispatchBootCompleted(Intent intent) throws RemoteException {
ConfigManager.getInstance().ensureManager(); ConfigManager.getInstance().ensureManager();
} }
private void registerPackageReceiver() {
try {
IntentFilter packageFilter = new IntentFilter();
packageFilter.addAction(Intent.ACTION_PACKAGE_ADDED);
packageFilter.addAction(Intent.ACTION_PACKAGE_CHANGED);
packageFilter.addAction(Intent.ACTION_PACKAGE_FULLY_REMOVED);
packageFilter.addDataScheme("package");
IntentFilter uidFilter = new IntentFilter();
uidFilter.addAction(Intent.ACTION_UID_REMOVED);
var receiver = new IIntentReceiver.Stub() {
@Override
public void performReceive(Intent intent, int resultCode, String data, Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
new Thread(() -> dispatchPackageChanged(intent)).start();
}
};
ActivityManagerService.registerReceiver("android", null, receiver, packageFilter, null, -1, 0);
ActivityManagerService.registerReceiver("android", null, receiver, uidFilter, null, -1, 0);
} catch (Throwable e) {
Log.e(TAG, "register package receiver", e);
}
}
private void registerBootReceiver() {
try {
IntentFilter intentFilter = new IntentFilter();
intentFilter.addAction(Intent.ACTION_LOCKED_BOOT_COMPLETED);
ActivityManagerService.registerReceiver("android", null, new IIntentReceiver.Stub() {
@Override
public void performReceive(Intent intent, int resultCode, String data, Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
new Thread(() -> dispatchBootCompleted(intent)).start();
}
}, intentFilter, null, 0, 0);
} catch (Throwable e) {
Log.e(TAG, "register boot receiver", e);
}
}
@Override
public void dispatchSystemServerContext(IBinder activityThread, IBinder activityToken) throws RemoteException {
ActivityManagerService.onSystemServerContext(IApplicationThread.Stub.asInterface(activityThread), activityToken);
registerBootReceiver();
registerPackageReceiver();
}
} }

View File

@ -1,85 +0,0 @@
/*
* This file is part of LSPosed.
*
* LSPosed is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* LSPosed is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with LSPosed. If not, see <https://www.gnu.org/licenses/>.
*
* Copyright (C) 2020 EdXposed Contributors
* Copyright (C) 2021 LSPosed Contributors
*/
package org.lsposed.lspd.service;
import android.annotation.SuppressLint;
import android.app.ActivityThread;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Handler;
import android.os.HandlerThread;
import android.os.UserHandle;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import org.lsposed.lspd.util.Utils;
public class PackageReceiver {
public static void register(BroadcastReceiver receiver) {
ActivityThread activityThread = ActivityThread.currentActivityThread();
if (activityThread == null) {
Utils.logW("ActivityThread is null");
return;
}
Context context = activityThread.getSystemContext();
if (context == null) {
Utils.logW("context is null");
return;
}
UserHandle userHandleAll;
try {
//noinspection JavaReflectionMemberAccess
Field field = UserHandle.class.getDeclaredField("ALL");
userHandleAll = (UserHandle) field.get(null);
} catch (Throwable e) {
Utils.logW("UserHandle.ALL", e);
return;
}
IntentFilter packageFilter = new IntentFilter();
packageFilter.addAction(Intent.ACTION_PACKAGE_ADDED);
packageFilter.addAction(Intent.ACTION_PACKAGE_CHANGED);
packageFilter.addAction(Intent.ACTION_PACKAGE_FULLY_REMOVED);
packageFilter.addDataScheme("package");
IntentFilter uidFilter = new IntentFilter();
uidFilter.addAction(Intent.ACTION_UID_REMOVED);
HandlerThread thread = new HandlerThread("lspd-PackageReceiver");
thread.start();
Handler handler = new Handler(thread.getLooper());
try {
@SuppressLint("DiscouragedPrivateApi")
Method method = Context.class.getDeclaredMethod("registerReceiverAsUser", BroadcastReceiver.class, UserHandle.class, IntentFilter.class, String.class, Handler.class);
method.invoke(context, receiver, userHandleAll, packageFilter, null, handler);
method.invoke(context, receiver, userHandleAll, uidFilter, null, handler);
Utils.logI("registered package receiver");
} catch (Throwable e) {
Utils.logW("registerReceiver failed", e);
}
}
}

View File

@ -19,6 +19,7 @@
package hidden; package hidden;
import android.content.Context;
import android.content.pm.PackageInstaller; import android.content.pm.PackageInstaller;
import android.content.res.AssetManager; import android.content.res.AssetManager;
import android.content.res.Resources; import android.content.res.Resources;
@ -46,4 +47,8 @@ public class HiddenApiBridge {
public static void PackageInstaller_SessionParams_installFlags(PackageInstaller.SessionParams params, int flags) { public static void PackageInstaller_SessionParams_installFlags(PackageInstaller.SessionParams params, int flags) {
params.installFlags = flags; params.installFlags = flags;
} }
public static IBinder Context_getActivityToken(Context ctx) {
return ctx.getActivityToken();
}
} }

View File

@ -2,12 +2,18 @@ package android.app;
import android.content.pm.ApplicationInfo; import android.content.pm.ApplicationInfo;
import android.content.res.CompatibilityInfo; import android.content.res.CompatibilityInfo;
import android.os.IBinder;
public final class ActivityThread { public final class ActivityThread {
public static ActivityThread currentActivityThread() { public static ActivityThread currentActivityThread() {
throw new UnsupportedOperationException("STUB"); throw new UnsupportedOperationException("STUB");
} }
public ApplicationThread getApplicationThread() {
throw new UnsupportedOperationException("STUB");
}
public static Application currentApplication() { public static Application currentApplication() {
throw new UnsupportedOperationException("STUB"); throw new UnsupportedOperationException("STUB");
} }
@ -27,4 +33,11 @@ public final class ActivityThread {
public ContextImpl getSystemContext() { public ContextImpl getSystemContext() {
throw new UnsupportedOperationException("STUB"); throw new UnsupportedOperationException("STUB");
} }
private class ApplicationThread extends IApplicationThread.Stub{
@Override
public IBinder asBinder() {
return null;
}
}
} }

View File

@ -21,6 +21,7 @@ package android.app;
import android.content.IIntentReceiver; import android.content.IIntentReceiver;
import android.content.Intent; import android.content.Intent;
import android.content.IntentFilter;
import android.os.Binder; import android.os.Binder;
import android.os.Bundle; import android.os.Bundle;
import android.os.IBinder; import android.os.IBinder;
@ -45,6 +46,19 @@ public interface IActivityManager extends IInterface {
boolean startUserInBackground(int userid); boolean startUserInBackground(int userid);
Intent registerReceiver(IApplicationThread caller, String callerPackage,
IIntentReceiver receiver, IntentFilter filter,
String requiredPermission, int userId, int flags);
Intent registerReceiverWithFeature(IApplicationThread caller, String callerPackage,
String callingFeatureId, IIntentReceiver receiver, IntentFilter filter,
String requiredPermission, int userId, int flags);
int bindService(IApplicationThread caller, IBinder token, Intent service,
String resolvedType, IServiceConnection connection, int flags,
String callingPackage, int userId);
boolean unbindService(IServiceConnection connection);
abstract class Stub extends Binder implements IActivityManager { abstract class Stub extends Binder implements IActivityManager {
public static IActivityManager asInterface(IBinder obj) { public static IActivityManager asInterface(IBinder obj) {

View File

@ -19,7 +19,14 @@
package android.app; package android.app;
import android.os.Binder;
import android.os.IBinder;
import android.os.IInterface; import android.os.IInterface;
public interface IApplicationThread extends IInterface { public interface IApplicationThread extends IInterface {
abstract class Stub extends Binder implements IApplicationThread {
public static IApplicationThread asInterface(IBinder obj) {
throw new UnsupportedOperationException();
}
}
} }

View File

@ -0,0 +1,22 @@
package android.app;
import android.content.ComponentName;
import android.os.Binder;
import android.os.IBinder;
import android.os.IInterface;
public interface IServiceConnection extends IInterface {
void connected(ComponentName name, IBinder service, boolean dead);
abstract class Stub extends Binder implements IServiceConnection {
public static IServiceConnection asInterface(IBinder obj) {
throw new UnsupportedOperationException();
}
@Override
public IBinder asBinder() {
throw new UnsupportedOperationException();
}
}
}

View File

@ -1,4 +1,9 @@
package android.content; package android.content;
import android.os.IBinder;
public class Context { public class Context {
public IBinder getActivityToken() {
throw new UnsupportedOperationException("STUB");
}
} }

View File

@ -19,7 +19,22 @@
package android.content; package android.content;
import android.os.Binder;
import android.os.Bundle;
import android.os.IBinder;
import android.os.IInterface; import android.os.IInterface;
public interface IIntentReceiver extends IInterface { public interface IIntentReceiver extends IInterface {
void performReceive(Intent intent, int resultCode, String data,
Bundle extras, boolean ordered, boolean sticky, int sendingUser);
abstract class Stub extends Binder implements IIntentReceiver {
public static IIntentReceiver asInterface(IBinder obj) {
throw new UnsupportedOperationException();
}
@Override
public IBinder asBinder() {
return this;
}
}
} }

View File

@ -0,0 +1,5 @@
package android.content;
public class IntentFilter {
}

@ -1 +1 @@
Subproject commit d472277c2773399148be6bf2e03ea21fd59b1dd6 Subproject commit 69da9f8d39f4f021c6f447d9db2ea80010d3921b