Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 80276091 authored by Will Burr's avatar Will Burr Committed by Automerger Merge Worker
Browse files

Merge "Allow profiling, dumpheap, attach-agent for sdk sandbox" into tm-dev am: d9f14a80

Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/base/+/17135815

Change-Id: I43adf1701566f52e036f2f755e0e9cdcbe449e7e
parents f67f2bc1 d9f14a80
Loading
Loading
Loading
Loading
+27 −34
Original line number Diff line number Diff line
@@ -5755,6 +5755,18 @@ public class ActivityManagerService extends IActivityManager.Stub
                owningUid, exported);
    }
    private void enforceDebuggable(ProcessRecord proc) {
        if (!Build.IS_DEBUGGABLE && !proc.isDebuggable()) {
            throw new SecurityException("Process not debuggable: " + proc.info.packageName);
        }
    }
    private void enforceDebuggable(ApplicationInfo info) {
        if (!Build.IS_DEBUGGABLE && (info.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
            throw new SecurityException("Process not debuggable: " + info.packageName);
        }
    }
    /**
     * As the only public entry point for permissions checking, this method
     * can enforce the semantic that requesting a check on a null global
@@ -6792,22 +6804,25 @@ public class ActivityManagerService extends IActivityManager.Stub
    }
    void setTrackAllocationApp(ApplicationInfo app, String processName) {
        if (!Build.IS_DEBUGGABLE) {
            if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
                throw new SecurityException("Process not debuggable: " + app.packageName);
            }
        }
        enforceDebuggable(app);
        synchronized (mProcLock) {
            mTrackAllocationApp = processName;
        }
    }
    void setProfileApp(ApplicationInfo app, String processName, ProfilerInfo profilerInfo) {
    void setProfileApp(ApplicationInfo app, String processName, ProfilerInfo profilerInfo,
            ApplicationInfo sdkSandboxClientApp) {
        synchronized (mAppProfiler.mProfilerLock) {
            if (!Build.IS_DEBUGGABLE) {
                boolean isAppDebuggable = (app.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0;
                boolean isAppProfileable = app.isProfileableByShell();
                if (sdkSandboxClientApp != null) {
                    isAppDebuggable |=
                            (sdkSandboxClientApp.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0;
                    isAppProfileable |= sdkSandboxClientApp.isProfileableByShell();
                }
                if (!isAppDebuggable && !isAppProfileable) {
                    throw new SecurityException("Process not debuggable, "
                            + "and not profileable by shell: " + app.packageName);
@@ -6818,11 +6833,7 @@ public class ActivityManagerService extends IActivityManager.Stub
    }
    void setNativeDebuggingAppLocked(ApplicationInfo app, String processName) {
        if (!Build.IS_DEBUGGABLE) {
            if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
                throw new SecurityException("Process not debuggable: " + app.packageName);
            }
        }
        enforceDebuggable(app);
        mNativeDebuggingApp = processName;
    }
@@ -15568,12 +15579,7 @@ public class ActivityManagerService extends IActivityManager.Stub
                    throw new IllegalArgumentException("Unknown process: " + process);
                }
                boolean isDebuggable = Build.IS_DEBUGGABLE;
                if (!isDebuggable) {
                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
                        throw new SecurityException("Process not debuggable: " + proc);
                    }
                }
                enforceDebuggable(proc);
                mOomAdjuster.mCachedAppOptimizer.enableFreezer(false);
@@ -15676,10 +15682,7 @@ public class ActivityManagerService extends IActivityManager.Stub
                    throw new SecurityException("No process found for calling pid "
                            + Binder.getCallingPid());
                }
                if (!Build.IS_DEBUGGABLE
                        && (proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
                    throw new SecurityException("Not running a debuggable build");
                }
                enforceDebuggable(proc);
                processName = proc.processName;
                uid = proc.uid;
                if (reportPackage != null && !proc.getPkgList().containsKey(reportPackage)) {
@@ -15890,13 +15893,7 @@ public class ActivityManagerService extends IActivityManager.Stub
            return false;
        }
        if (!Build.IS_DEBUGGABLE) {
            if ((process.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
                return false;
            }
        }
        return true;
        return Build.IS_DEBUGGABLE || process.isDebuggable();
    }
    public boolean startBinderTracking() throws RemoteException {
@@ -16850,7 +16847,7 @@ public class ActivityManagerService extends IActivityManager.Stub
                    }
                    if (profilerInfo != null) {
                        setProfileApp(aInfo.applicationInfo, aInfo.processName, profilerInfo);
                        setProfileApp(aInfo.applicationInfo, aInfo.processName, profilerInfo, null);
                    }
                    wmLock.notify();
                }
@@ -17638,11 +17635,7 @@ public class ActivityManagerService extends IActivityManager.Stub
                    throw new IllegalArgumentException("Unknown process: " + process);
                }
                if (!Build.IS_DEBUGGABLE) {
                    if ((proc.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
                        throw new SecurityException("Process not debuggable: " + proc);
                    }
                }
                enforceDebuggable(proc);
                thread.attachAgent(path);
            }
+5 −11
Original line number Diff line number Diff line
@@ -58,7 +58,6 @@ import android.content.ComponentCallbacks2;
import android.content.ContentResolver;
import android.content.Context;
import android.content.Intent;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager.NameNotFoundException;
import android.net.Uri;
import android.os.Binder;
@@ -608,13 +607,7 @@ public class AppProfiler {
        if (check != null) {
            if ((pss * 1024) >= check && profile.getThread() != null
                    && mMemWatchDumpProcName == null) {
                boolean isDebuggable = Build.IS_DEBUGGABLE;
                if (!isDebuggable) {
                    if ((proc.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
                        isDebuggable = true;
                    }
                }
                if (isDebuggable) {
                if (Build.IS_DEBUGGABLE || proc.isDebuggable()) {
                    Slog.w(TAG, "Process " + proc + " exceeded pss limit " + check + "; reporting");
                    startHeapDumpLPf(profile, false);
                } else {
@@ -1702,7 +1695,8 @@ public class AppProfiler {
        try {
            if (start) {
                stopProfilerLPf(null, 0);
                mService.setProfileApp(proc.info, proc.processName, profilerInfo);
                mService.setProfileApp(proc.info, proc.processName, profilerInfo,
                        proc.isSdkSandbox ? proc.getClientInfoForSdkSandbox() : null);
                mProfileData.setProfileProc(proc);
                mProfileType = profileType;
                ParcelFileDescriptor fd = profilerInfo.profileFd;
@@ -2075,7 +2069,7 @@ public class AppProfiler {
            if (mAppAgentMap != null && mAppAgentMap.containsKey(processName)) {
                // We need to do a debuggable check here. See setAgentApp for why the check is
                // postponed to here.
                if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
                if (app.isDebuggable()) {
                    String agent = mAppAgentMap.get(processName);
                    // Do not overwrite already requested agent.
                    if (profilerInfo == null) {
@@ -2132,7 +2126,7 @@ public class AppProfiler {
        if (preBindAgent != null) {
            thread.attachAgent(preBindAgent);
        }
        if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
        if (app.isDebuggable()) {
            thread.attachStartupAgents(app.info.dataDir);
        }
        return profilerInfo;
+13 −23
Original line number Diff line number Diff line
@@ -1718,8 +1718,16 @@ public final class ProcessList {
            int runtimeFlags = 0;

            boolean debuggableFlag = (app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0;
            if (!debuggableFlag && app.isSdkSandbox) {
                debuggableFlag = isAppForSdkSandboxDebuggable(app);
            boolean isProfileableByShell = app.info.isProfileableByShell();
            boolean isProfileable = app.info.isProfileable();

            if (app.isSdkSandbox) {
                ApplicationInfo clientInfo = app.getClientInfoForSdkSandbox();
                if (clientInfo != null) {
                    debuggableFlag |= (clientInfo.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0;
                    isProfileableByShell |= clientInfo.isProfileableByShell();
                    isProfileable |= clientInfo.isProfileable();
                }
            }

            if (debuggableFlag) {
@@ -1741,10 +1749,10 @@ public final class ProcessList {
            if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 || mService.mSafeMode) {
                runtimeFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
            }
            if ((app.info.privateFlags & ApplicationInfo.PRIVATE_FLAG_PROFILEABLE_BY_SHELL) != 0) {
            if (isProfileableByShell) {
                runtimeFlags |= Zygote.PROFILE_FROM_SHELL;
            }
            if (app.info.isProfileable()) {
            if (isProfileable) {
                runtimeFlags |= Zygote.PROFILEABLE;
            }
            if ("1".equals(SystemProperties.get("debug.checkjni"))) {
@@ -1812,7 +1820,7 @@ public final class ProcessList {
            }

            String invokeWith = null;
            if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
            if (debuggableFlag) {
                // Debuggable apps may include a wrapper script with their library directory.
                String wrapperFileName = app.info.nativeLibraryDir + "/wrap.sh";
                StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
@@ -1887,24 +1895,6 @@ public final class ProcessList {
        }
    }

    /** Return true if the client app for the SDK sandbox process is debuggable. */
    private boolean isAppForSdkSandboxDebuggable(ProcessRecord sandboxProcess) {
        // TODO (b/221004701) use client app process name
        final int appUid = Process.getAppUidForSdkSandboxUid(sandboxProcess.uid);
        IPackageManager pm = mService.getPackageManager();
        try {
            String[] packages = pm.getPackagesForUid(appUid);
            for (String aPackage : packages) {
                ApplicationInfo i = pm.getApplicationInfo(aPackage, 0, sandboxProcess.userId);
                if ((i.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
                    return true;
                }
            }
        } catch (RemoteException e) {
            // shouldn't happen
        }
        return false;
    }

    @GuardedBy("mService")
    boolean startProcessLocked(HostingRecord hostingRecord, String entryPoint, ProcessRecord app,
+24 −0
Original line number Diff line number Diff line
@@ -27,6 +27,7 @@ import android.app.ApplicationExitInfo.Reason;
import android.app.ApplicationExitInfo.SubReason;
import android.app.IApplicationThread;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManagerInternal;
import android.content.pm.ProcessInfo;
import android.content.pm.VersionedPackage;
import android.content.res.CompatibilityInfo;
@@ -865,6 +866,29 @@ class ProcessRecord implements WindowProcessListener {
        return mDebugging;
    }

    @Nullable
    public ApplicationInfo getClientInfoForSdkSandbox() {
        if (!isSdkSandbox || sdkSandboxClientAppPackage == null) {
            throw new IllegalStateException(
                    "getClientInfoForSdkSandbox called for non-sandbox process"
            );
        }
        PackageManagerInternal pm = mService.getPackageManagerInternal();
        return pm.getApplicationInfo(
                sdkSandboxClientAppPackage, /* flags */0, Process.SYSTEM_UID, userId);
    }

    public boolean isDebuggable() {
        if ((info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
            return true;
        }
        if (isSdkSandbox) {
            ApplicationInfo clientInfo = getClientInfoForSdkSandbox();
            return clientInfo != null && (clientInfo.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0;
        }
        return false;
    }

    @GuardedBy("mService")
    void setDebugging(boolean debugging) {
        mDebugging = debugging;