diff options
11 files changed, 92 insertions, 34 deletions
diff --git a/core/java/android/os/Process.java b/core/java/android/os/Process.java index 450bfaef50d4..1130f1db6256 100644 --- a/core/java/android/os/Process.java +++ b/core/java/android/os/Process.java @@ -519,11 +519,12 @@ public class Process { * @param appDataDir null-ok the data directory of the app. * @param invokeWith null-ok the command to invoke with. * @param packageName null-ok the name of the package this process belongs to. - * + * @param disabledCompatChanges null-ok list of disabled compat changes for the process being + * started. * @param zygoteArgs Additional arguments to supply to the zygote process. * @return An object that describes the result of the attempt to start the process. * @throws RuntimeException on fatal start failure - * + * * {@hide} */ public static ProcessStartResult start(@NonNull final String processClass, @@ -538,11 +539,12 @@ public class Process { @Nullable String appDataDir, @Nullable String invokeWith, @Nullable String packageName, + @Nullable long[] disabledCompatChanges, @Nullable String[] zygoteArgs) { return ZYGOTE_PROCESS.start(processClass, niceName, uid, gid, gids, runtimeFlags, mountExternal, targetSdkVersion, seInfo, abi, instructionSet, appDataDir, invokeWith, packageName, - /*useUsapPool=*/ true, zygoteArgs); + /*useUsapPool=*/ true, disabledCompatChanges, zygoteArgs); } /** @hide */ @@ -558,11 +560,12 @@ public class Process { @Nullable String appDataDir, @Nullable String invokeWith, @Nullable String packageName, + @Nullable long[] disabledCompatChanges, @Nullable String[] zygoteArgs) { return WebViewZygote.getProcess().start(processClass, niceName, uid, gid, gids, runtimeFlags, mountExternal, targetSdkVersion, seInfo, abi, instructionSet, appDataDir, invokeWith, packageName, - /*useUsapPool=*/ false, zygoteArgs); + /*useUsapPool=*/ false, disabledCompatChanges, zygoteArgs); } /** diff --git a/core/java/android/os/ZygoteProcess.java b/core/java/android/os/ZygoteProcess.java index 3a55aff14659..c2d3eccfa3b1 100644 --- a/core/java/android/os/ZygoteProcess.java +++ b/core/java/android/os/ZygoteProcess.java @@ -306,6 +306,8 @@ public class ZygoteProcess { * @param appDataDir null-ok the data directory of the app. * @param invokeWith null-ok the command to invoke with. * @param packageName null-ok the name of the package this process belongs to. + * @param disabledCompatChanges null-ok list of disabled compat changes for the process being + * started. * @param zygoteArgs Additional arguments to supply to the zygote process. * * @return An object that describes the result of the attempt to start the process. @@ -323,6 +325,7 @@ public class ZygoteProcess { @Nullable String invokeWith, @Nullable String packageName, boolean useUsapPool, + @Nullable long[] disabledCompatChanges, @Nullable String[] zygoteArgs) { // TODO (chriswailes): Is there a better place to check this value? if (fetchUsapPoolEnabledPropWithMinInterval()) { @@ -333,7 +336,7 @@ public class ZygoteProcess { return startViaZygote(processClass, niceName, uid, gid, gids, runtimeFlags, mountExternal, targetSdkVersion, seInfo, abi, instructionSet, appDataDir, invokeWith, /*startChildZygote=*/ false, - packageName, useUsapPool, zygoteArgs); + packageName, useUsapPool, disabledCompatChanges, zygoteArgs); } catch (ZygoteStartFailedEx ex) { Log.e(LOG_TAG, "Starting VM process through Zygote failed"); @@ -534,6 +537,7 @@ public class ZygoteProcess { * @param startChildZygote Start a sub-zygote. This creates a new zygote process * that has its state cloned from this zygote process. * @param packageName null-ok the name of the package this process belongs to. + * @param disabledCompatChanges a list of disabled compat changes for the process being started. * @param extraArgs Additional arguments to supply to the zygote process. * @return An object that describes the result of the attempt to start the process. * @throws ZygoteStartFailedEx if process start failed for any reason @@ -552,6 +556,7 @@ public class ZygoteProcess { boolean startChildZygote, @Nullable String packageName, boolean useUsapPool, + @Nullable long[] disabledCompatChanges, @Nullable String[] extraArgs) throws ZygoteStartFailedEx { ArrayList<String> argsForZygote = new ArrayList<>(); @@ -623,6 +628,21 @@ public class ZygoteProcess { argsForZygote.add("--package-name=" + packageName); } + if (disabledCompatChanges != null && disabledCompatChanges.length > 0) { + final StringBuilder sb = new StringBuilder(); + sb.append("--disabled-compat-changes="); + + final int sz = disabledCompatChanges.length; + for (int i = 0; i < sz; i++) { + if (i != 0) { + sb.append(','); + } + sb.append(disabledCompatChanges[i]); + } + + argsForZygote.add(sb.toString()); + } + argsForZygote.add(processClass); if (extraArgs != null) { @@ -1170,7 +1190,8 @@ public class ZygoteProcess { gids, runtimeFlags, 0 /* mountExternal */, 0 /* targetSdkVersion */, seInfo, abi, instructionSet, null /* appDataDir */, null /* invokeWith */, true /* startChildZygote */, null /* packageName */, - false /* useUsapPool */, extraArgs); + false /* useUsapPool */, + null /* disabledCompatChanges */, extraArgs); } catch (ZygoteStartFailedEx ex) { throw new RuntimeException("Starting child-zygote through Zygote failed", ex); } diff --git a/core/java/com/android/internal/os/RuntimeInit.java b/core/java/com/android/internal/os/RuntimeInit.java index a21187165c65..fa823c4bf2f6 100644 --- a/core/java/com/android/internal/os/RuntimeInit.java +++ b/core/java/com/android/internal/os/RuntimeInit.java @@ -367,8 +367,8 @@ public class RuntimeInit { if (DEBUG) Slog.d(TAG, "Leaving RuntimeInit!"); } - protected static Runnable applicationInit(int targetSdkVersion, String[] argv, - ClassLoader classLoader) { + protected static Runnable applicationInit(int targetSdkVersion, long[] disabledCompatChanges, + String[] argv, ClassLoader classLoader) { // If the application calls System.exit(), terminate the process // immediately without running any shutdown hooks. It is not possible to // shutdown an Android application gracefully. Among other things, the @@ -377,6 +377,7 @@ public class RuntimeInit { nativeSetExitWithoutCleanup(true); VMRuntime.getRuntime().setTargetSdkVersion(targetSdkVersion); + VMRuntime.getRuntime().setDisabledCompatChanges(disabledCompatChanges); final Arguments args = new Arguments(argv); diff --git a/core/java/com/android/internal/os/WrapperInit.java b/core/java/com/android/internal/os/WrapperInit.java index f0e779694c90..790d7f7ab694 100644 --- a/core/java/com/android/internal/os/WrapperInit.java +++ b/core/java/com/android/internal/os/WrapperInit.java @@ -23,16 +23,18 @@ import android.system.Os; import android.system.OsConstants; import android.system.StructCapUserData; import android.system.StructCapUserHeader; -import android.util.TimingsTraceLog; import android.util.Slog; +import android.util.TimingsTraceLog; + import dalvik.system.VMRuntime; + +import libcore.io.IoUtils; + import java.io.DataOutputStream; import java.io.FileDescriptor; import java.io.FileOutputStream; import java.io.IOException; -import libcore.io.IoUtils; - /** * Startup class for the wrapper process. * @hide @@ -166,10 +168,10 @@ public class WrapperInit { System.arraycopy(argv, 2, removedArgs, 0, argv.length - 2); argv = removedArgs; } - // Perform the same initialization that would happen after the Zygote forks. Zygote.nativePreApplicationInit(); - return RuntimeInit.applicationInit(targetSdkVersion, argv, classLoader); + return RuntimeInit.applicationInit(targetSdkVersion, /*disabledCompatChanges*/ null, + argv, classLoader); } /** diff --git a/core/java/com/android/internal/os/Zygote.java b/core/java/com/android/internal/os/Zygote.java index 00ab45ec3537..33adec106d97 100644 --- a/core/java/com/android/internal/os/Zygote.java +++ b/core/java/com/android/internal/os/Zygote.java @@ -642,6 +642,7 @@ public final class Zygote { Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER); return ZygoteInit.zygoteInit(args.mTargetSdkVersion, + args.mDisabledCompatChanges, args.mRemainingArgs, null /* classLoader */); } finally { diff --git a/core/java/com/android/internal/os/ZygoteArguments.java b/core/java/com/android/internal/os/ZygoteArguments.java index fc55ccf4d6b7..3915ba273dfa 100644 --- a/core/java/com/android/internal/os/ZygoteArguments.java +++ b/core/java/com/android/internal/os/ZygoteArguments.java @@ -210,6 +210,12 @@ class ZygoteArguments { int mHiddenApiAccessStatslogSampleRate = -1; /** + * A set of disabled app compatibility changes for the running app. From + * --disabled-compat-changes. + */ + long[] mDisabledCompatChanges = null; + + /** * Constructs instance and parses args * * @param args zygote command-line args @@ -416,6 +422,16 @@ class ZygoteArguments { mUsapPoolStatusSpecified = true; mUsapPoolEnabled = Boolean.parseBoolean(arg.substring(arg.indexOf('=') + 1)); expectRuntimeArgs = false; + } else if (arg.startsWith("--disabled-compat-changes=")) { + if (mDisabledCompatChanges != null) { + throw new IllegalArgumentException("Duplicate arg specified"); + } + final String[] params = arg.substring(arg.indexOf('=') + 1).split(","); + final int length = params.length; + mDisabledCompatChanges = new long[length]; + for (int i = 0; i < length; i++) { + mDisabledCompatChanges[i] = Long.parseLong(params[i]); + } } else { break; } diff --git a/core/java/com/android/internal/os/ZygoteConnection.java b/core/java/com/android/internal/os/ZygoteConnection.java index b15e1efa46c8..4c37591d4a66 100644 --- a/core/java/com/android/internal/os/ZygoteConnection.java +++ b/core/java/com/android/internal/os/ZygoteConnection.java @@ -502,6 +502,7 @@ class ZygoteConnection { } else { if (!isZygote) { return ZygoteInit.zygoteInit(parsedArgs.mTargetSdkVersion, + parsedArgs.mDisabledCompatChanges, parsedArgs.mRemainingArgs, null /* classLoader */); } else { return ZygoteInit.childZygoteInit(parsedArgs.mTargetSdkVersion, diff --git a/core/java/com/android/internal/os/ZygoteInit.java b/core/java/com/android/internal/os/ZygoteInit.java index 93e61020ff19..7b77a92e3d3a 100644 --- a/core/java/com/android/internal/os/ZygoteInit.java +++ b/core/java/com/android/internal/os/ZygoteInit.java @@ -547,6 +547,7 @@ public class ZygoteInit { * Pass the remaining arguments to SystemServer. */ return ZygoteInit.zygoteInit(parsedArgs.mTargetSdkVersion, + parsedArgs.mDisabledCompatChanges, parsedArgs.mRemainingArgs, cl); } @@ -972,14 +973,16 @@ public class ZygoteInit { * * Current recognized args: * <ul> - * <li> <code> [--] <start class name> <args> + * <li> <code> [--] <start class name> <args> * </ul> * * @param targetSdkVersion target SDK version - * @param argv arg strings + * @param disabledCompatChanges set of disabled compat changes for the process (all others + * are enabled) + * @param argv arg strings */ - public static final Runnable zygoteInit(int targetSdkVersion, String[] argv, - ClassLoader classLoader) { + public static final Runnable zygoteInit(int targetSdkVersion, long[] disabledCompatChanges, + String[] argv, ClassLoader classLoader) { if (RuntimeInit.DEBUG) { Slog.d(RuntimeInit.TAG, "RuntimeInit: Starting application from zygote"); } @@ -989,7 +992,8 @@ public class ZygoteInit { RuntimeInit.commonInit(); ZygoteInit.nativeZygoteInit(); - return RuntimeInit.applicationInit(targetSdkVersion, argv, classLoader); + return RuntimeInit.applicationInit(targetSdkVersion, disabledCompatChanges, argv, + classLoader); } /** diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java index 5ffdf02ef11e..35774ed3ca6f 100644 --- a/services/core/java/com/android/server/am/ActivityManagerService.java +++ b/services/core/java/com/android/server/am/ActivityManagerService.java @@ -2411,7 +2411,8 @@ public class ActivityManagerService extends IActivityManager.Stub mConstants = hasHandlerThread ? new ActivityManagerConstants(mContext, this, mHandler) : null; final ActiveUids activeUids = new ActiveUids(this, false /* postChangesToAtm */); - mProcessList.init(this, activeUids); + mPlatformCompat = null; + mProcessList.init(this, activeUids, mPlatformCompat); mLowMemDetector = null; mOomAdjuster = new OomAdjuster(this, mProcessList, activeUids); @@ -2432,7 +2433,6 @@ public class ActivityManagerService extends IActivityManager.Stub mProcStartHandler = null; mHiddenApiBlacklist = null; mFactoryTest = FACTORY_TEST_OFF; - mPlatformCompat = null; } // Note: This method is invoked on the main thread but may need to attach various @@ -2461,7 +2461,9 @@ public class ActivityManagerService extends IActivityManager.Stub mConstants = new ActivityManagerConstants(mContext, this, mHandler); final ActiveUids activeUids = new ActiveUids(this, true /* postChangesToAtm */); - mProcessList.init(this, activeUids); + mPlatformCompat = (PlatformCompat) ServiceManager.getService( + Context.PLATFORM_COMPAT_SERVICE); + mProcessList.init(this, activeUids, mPlatformCompat); mLowMemDetector = new LowMemDetector(this); mOomAdjuster = new OomAdjuster(this, mProcessList, activeUids); @@ -2569,9 +2571,6 @@ public class ActivityManagerService extends IActivityManager.Stub mHiddenApiBlacklist = new HiddenApiSettings(mHandler, mContext); - mPlatformCompat = (PlatformCompat) ServiceManager.getService( - Context.PLATFORM_COMPAT_SERVICE); - Watchdog.getInstance().addMonitor(this); Watchdog.getInstance().addThread(mHandler); @@ -5048,9 +5047,7 @@ public class ActivityManagerService extends IActivityManager.Stub bindApplicationTimeMillis = SystemClock.elapsedRealtime(); mAtmInternal.preBindApplication(app.getWindowProcessController()); final ActiveInstrumentation instr2 = app.getActiveInstrumentation(); - long[] disabledCompatChanges = {}; if (mPlatformCompat != null) { - disabledCompatChanges = mPlatformCompat.getDisabledChanges(app.info); mPlatformCompat.resetReporting(app.info); } if (app.isolatedEntryPoint != null) { @@ -5069,7 +5066,7 @@ public class ActivityManagerService extends IActivityManager.Stub app.compat, getCommonServicesLocked(app.isolated), mCoreSettingsObserver.getCoreSettingsLocked(), buildSerial, autofillOptions, contentCaptureOptions, - disabledCompatChanges); + app.mDisabledCompatChanges); } else { thread.bindApplication(processName, appInfo, providers, null, profilerInfo, null, null, null, testMode, @@ -5079,7 +5076,7 @@ public class ActivityManagerService extends IActivityManager.Stub app.compat, getCommonServicesLocked(app.isolated), mCoreSettingsObserver.getCoreSettingsLocked(), buildSerial, autofillOptions, contentCaptureOptions, - disabledCompatChanges); + app.mDisabledCompatChanges); } if (profilerInfo != null) { profilerInfo.closeFd(); diff --git a/services/core/java/com/android/server/am/ProcessList.java b/services/core/java/com/android/server/am/ProcessList.java index a2670d8dd424..f397a3243b2a 100644 --- a/services/core/java/com/android/server/am/ProcessList.java +++ b/services/core/java/com/android/server/am/ProcessList.java @@ -96,6 +96,7 @@ import com.android.internal.util.MemInfoReader; import com.android.server.LocalServices; import com.android.server.ServiceThread; import com.android.server.Watchdog; +import com.android.server.compat.PlatformCompat; import com.android.server.pm.dex.DexManager; import com.android.server.wm.ActivityServiceConnectionsHolder; import com.android.server.wm.WindowManagerService; @@ -384,6 +385,8 @@ public final class ProcessList { final ArrayMap<AppZygote, ArrayList<ProcessRecord>> mAppZygoteProcesses = new ArrayMap<AppZygote, ArrayList<ProcessRecord>>(); + private PlatformCompat mPlatformCompat = null; + final class IsolatedUidRange { @VisibleForTesting public final int mFirstUid; @@ -565,9 +568,11 @@ public final class ProcessList { updateOomLevels(0, 0, false); } - void init(ActivityManagerService service, ActiveUids activeUids) { + void init(ActivityManagerService service, ActiveUids activeUids, + PlatformCompat platformCompat) { mService = service; mActiveUids = activeUids; + mPlatformCompat = platformCompat; if (sKillHandler == null) { sKillThread = new ServiceThread(TAG + ":kill", @@ -1657,6 +1662,10 @@ public final class ProcessList { Slog.wtf(TAG, "startProcessLocked processName:" + app.processName + " with non-zero pid:" + app.pid); } + app.mDisabledCompatChanges = null; + if (mPlatformCompat != null) { + app.mDisabledCompatChanges = mPlatformCompat.getDisabledChanges(app.info); + } final long startSeq = app.startSeq = ++mProcStartSeqCounter; app.setStartParams(uid, hostingRecord, seInfo, startTime); app.setUsingWrapper(invokeWith != null @@ -1811,8 +1820,8 @@ public final class ProcessList { startResult = startWebView(entryPoint, app.processName, uid, uid, gids, runtimeFlags, mountExternal, app.info.targetSdkVersion, seInfo, requiredAbi, instructionSet, - app.info.dataDir, null, app.info.packageName, - new String[] {PROC_START_SEQ_IDENT + app.startSeq}); + app.info.dataDir, null, app.info.packageName, app.mDisabledCompatChanges, + new String[]{PROC_START_SEQ_IDENT + app.startSeq}); } else if (hostingRecord.usesAppZygote()) { final AppZygote appZygote = createAppZygoteForProcessIfNeeded(app); @@ -1820,14 +1829,15 @@ public final class ProcessList { app.processName, uid, uid, gids, runtimeFlags, mountExternal, app.info.targetSdkVersion, seInfo, requiredAbi, instructionSet, app.info.dataDir, null, app.info.packageName, - /*useUsapPool=*/ false, - new String[] {PROC_START_SEQ_IDENT + app.startSeq}); + /*useUsapPool=*/ false, app.mDisabledCompatChanges, + new String[]{PROC_START_SEQ_IDENT + app.startSeq}); } else { startResult = Process.start(entryPoint, app.processName, uid, uid, gids, runtimeFlags, mountExternal, app.info.targetSdkVersion, seInfo, requiredAbi, instructionSet, app.info.dataDir, invokeWith, app.info.packageName, - new String[] {PROC_START_SEQ_IDENT + app.startSeq}); + app.mDisabledCompatChanges, + new String[]{PROC_START_SEQ_IDENT + app.startSeq}); } checkSlow(startTime, "startProcess: returned from zygote!"); return startResult; diff --git a/services/core/java/com/android/server/am/ProcessRecord.java b/services/core/java/com/android/server/am/ProcessRecord.java index ea3084274ae0..8c1a0d3abcd2 100644 --- a/services/core/java/com/android/server/am/ProcessRecord.java +++ b/services/core/java/com/android/server/am/ProcessRecord.java @@ -307,6 +307,8 @@ class ProcessRecord implements WindowProcessListener { long startTime; // This will be same as {@link #uid} usually except for some apps used during factory testing. int startUid; + // set of disabled compat changes for the process (all others are enabled) + long[] mDisabledCompatChanges; void setStartParams(int startUid, HostingRecord hostingRecord, String seInfo, long startTime) { |