Add a mainline-accessible API to kill an app on sandbox death

This API can be accessed by mainline modules to kill a specific app
process when its associated sandbox dies. It takes in the IBinder value
of the corresponding IApplicationThread of the app to kill it.

REASON_DEPENDENCY_DIED and SUBREASON_SDK_SANDBOX_DIED are used in the
emitted AppProcessDied atom.

Bug: 261558210
Test: atest SdkSandboxLifecycleHostTest
Test: m statsd && statsd_testdrive 373 emits an atom with
SUBREASON_SDK_SANDBOX_DIED

Change-Id: Id37023eabaa5f734bb67bee07a0f779c355cc100
This commit is contained in:
Sanjana Sunil
2022-12-06 14:53:48 +00:00
parent f8849f8572
commit 46bb3e8a55
8 changed files with 62 additions and 0 deletions

View File

@@ -80,6 +80,7 @@ package android.content {
}
public abstract class Context {
method @NonNull public android.os.IBinder getIApplicationThreadBinder();
method @NonNull public android.os.UserHandle getUser();
field public static final String PAC_PROXY_SERVICE = "pac_proxy";
field public static final String TEST_NETWORK_SERVICE = "test_network";

View File

@@ -416,6 +416,15 @@ public final class ApplicationExitInfo implements Parcelable {
*/
public static final int SUBREASON_UNDELIVERED_BROADCAST = 26;
/**
* The process was killed because its associated SDK sandbox process (where it had loaded SDKs)
* had died; this would be set only when the reason is {@link #REASON_DEPENDENCY_DIED}.
*
* For internal use only.
* @hide
*/
public static final int SUBREASON_SDK_SANDBOX_DIED = 27;
// If there is any OEM code which involves additional app kill reasons, it should
// be categorized in {@link #REASON_OTHER}, with subreason code starting from 1000.

View File

@@ -1998,6 +1998,13 @@ class ContextImpl extends Context {
return mMainThread.getApplicationThread();
}
/** @hide */
@NonNull
@Override
public IBinder getIApplicationThreadBinder() {
return getIApplicationThread().asBinder();
}
/** @hide */
@Override
public Handler getMainThreadHandler() {

View File

@@ -7345,6 +7345,18 @@ public abstract class Context {
throw new RuntimeException("Not implemented. Must override in a subclass.");
}
/**
* Get the binder object associated with the IApplicationThread of this Context.
*
* This can be used by a mainline module to uniquely identify a specific app process.
* @hide
*/
@NonNull
@SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
public IBinder getIApplicationThreadBinder() {
throw new RuntimeException("Not implemented. Must override in a subclass.");
}
/**
* @hide
*/

View File

@@ -1247,6 +1247,14 @@ public class ContextWrapper extends Context {
return mBase.getIApplicationThread();
}
/**
* @hide
*/
@Override
public IBinder getIApplicationThreadBinder() {
return mBase.getIApplicationThreadBinder();
}
/**
* @hide
*/

View File

@@ -40,6 +40,7 @@ package com.android.server.am {
public interface ActivityManagerLocal {
method public boolean bindSdkSandboxService(@NonNull android.content.Intent, @NonNull android.content.ServiceConnection, int, @NonNull String, @NonNull String, int) throws android.os.RemoteException;
method public boolean canStartForegroundService(int, int, @NonNull String);
method public void killSdkSandboxClientAppProcess(@NonNull android.os.IBinder);
}
}

View File

@@ -23,6 +23,7 @@ import android.annotation.SystemApi;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.IBinder;
import android.os.RemoteException;
/**
@@ -94,6 +95,15 @@ public interface ActivityManagerLocal {
@Context.BindServiceFlags int flags)
throws RemoteException;
/**
* Kill an app process associated with an SDK sandbox.
*
* @param clientApplicationThreadBinder binder value of the
* {@link android.app.IApplicationThread} of a client app process associated with a
* sandbox. This is obtained using {@link Context#getIApplicationThreadBinder()}.
*/
void killSdkSandboxClientAppProcess(@NonNull IBinder clientApplicationThreadBinder);
/**
* Start a foreground service delegate.
* @param options foreground service delegate options.

View File

@@ -16939,6 +16939,20 @@ public class ActivityManagerService extends IActivityManager.Stub
mContext.getOpPackageName(), UserHandle.getUserId(clientAppUid)) != 0;
}
@Override
public void killSdkSandboxClientAppProcess(IBinder clientApplicationThreadBinder) {
synchronized (ActivityManagerService.this) {
ProcessRecord r = getRecordForAppLOSP(clientApplicationThreadBinder);
if (r != null) {
r.killLocked(
"sdk sandbox died",
ApplicationExitInfo.REASON_DEPENDENCY_DIED,
ApplicationExitInfo.SUBREASON_SDK_SANDBOX_DIED,
true);
}
}
}
@Override
public void onUserRemoved(@UserIdInt int userId) {
// Clean up any ActivityTaskManager state (by telling it the user is stopped)