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

Commit 50b32401 authored by Makoto Onuki's avatar Makoto Onuki
Browse files

Switch to ContextImpl

- Also start using the real SystemServiceRegistry.

- We no longer use RavenwoodContext.

Bug: 418786021
Flag: TEST_ONLY
Test: $ANDROID_BUILD_TOP/frameworks/base/ravenwood/scripts/run-ravenwood-tests.sh
Change-Id: Icf3d48e0d35a3fb29fc7419217a6590529a9a9e8
parent d0ebc270
Loading
Loading
Loading
Loading
+6 −0
Original line number Diff line number Diff line
@@ -182,6 +182,8 @@ import android.provider.DeviceConfigServiceManager;
import android.provider.Downloads;
import android.provider.FontsContract;
import android.provider.Settings;
import android.ravenwood.annotation.RavenwoodIgnore;
import android.ravenwood.annotation.RavenwoodRedirect;
import android.renderscript.RenderScriptCacheDir;
import android.se.omapi.SeFrameworkInitializer;
import android.se.omapi.SeServiceManager;
@@ -3065,6 +3067,7 @@ public final class ActivityThread extends ClientTransactionHandler
    }

    @UnsupportedAppUsage
    @RavenwoodRedirect
    public Handler getHandler() {
        return mH;
    }
@@ -3302,10 +3305,12 @@ public final class ActivityThread extends ClientTransactionHandler
    }

    @UnsupportedAppUsage
    @RavenwoodRedirect
    public Looper getLooper() {
        return mLooper;
    }

    @RavenwoodRedirect
    public Executor getExecutor() {
        return mExecutor;
    }
@@ -9231,6 +9236,7 @@ public final class ActivityThread extends ClientTransactionHandler
        return false;
    }

    @RavenwoodIgnore
    void addApplication(@NonNull Application app) {
        mAllApplications.add(app);
        VMDebug.addApplication(app.mLoadedApk.mPackageName);
+30 −1
Original line number Diff line number Diff line
@@ -16,15 +16,32 @@
package android.app;

import android.content.Context;
import android.os.Handler;
import android.os.HandlerExecutor;
import android.os.Looper;
import android.platform.test.ravenwood.RavenwoodAppDriver;

import java.util.concurrent.Executor;

/**
 * Inject Ravenwood methods to {@link ActivityThread}.
 *
 * TODO: Stop using Objensis to instantiate ActivityThread and start using more of the
 * real code, rather than handling all methods here with @RavenwoodRedirect.
 * At that point, the initialization logic should be moved from RavenwoodAppDriver to this class.
 */
public class ActivityThread_ravenwood {
public final class ActivityThread_ravenwood {
    private ActivityThread_ravenwood() {
    }

    /** Backdoor to set ActivityThread's package-private member field. */
    public static void setInstrumentation(ActivityThread at, Instrumentation inst) {
        at.mInstrumentation = inst;
    }

    private static final Handler sHandler = new Handler(Looper.getMainLooper());
    private static final HandlerExecutor sHandlerExecutor = new HandlerExecutor(sHandler);

    /** Override the corresponding ActivityThread method. */
    public static Context currentSystemContext() {
        return RavenwoodAppDriver.getInstance().getAndroidAppBridge().getSystemContext();
@@ -34,4 +51,16 @@ public class ActivityThread_ravenwood {
    public static Application currentApplication() {
        return RavenwoodAppDriver.getInstance().getApplication();
    }

    static Looper getLooper(ActivityThread at) {
        return Looper.getMainLooper();
    }

    static Handler getHandler(ActivityThread at) {
        return sHandler;
    }

    static Executor getExecutor(ActivityThread at) {
        return sHandlerExecutor;
    }
}
+3 −3
Original line number Diff line number Diff line
@@ -24,8 +24,8 @@ import android.content.Context;
 * It's more of a "reverse" redirect class.
 */
public class Application_ravenwood {
    /** Calls {@link Application#attach} */
    public static void attach(Application application, Context context) {
        application.attach(context);
    /** Backdoor to {@link Application#attach}, which is package-private */
    public static void attachBaseContext(Application application, Context baseContext) {
        application.attach(baseContext);
    }
}
+50 −15
Original line number Diff line number Diff line
@@ -91,6 +91,7 @@ import android.ravenwood.annotation.RavenwoodKeepPartialClass;
import android.ravenwood.annotation.RavenwoodRedirect;
import android.ravenwood.annotation.RavenwoodRedirectionClass;
import android.ravenwood.annotation.RavenwoodReplace;
import android.ravenwood.annotation.RavenwoodSupported.RavenwoodProvidingImplementation;
import android.system.ErrnoException;
import android.system.Os;
import android.system.OsConstants;
@@ -206,6 +207,7 @@ class ReceiverRestrictedContext extends ContextWrapper {
 */
@RavenwoodKeepPartialClass
@RavenwoodRedirectionClass("ContextImpl_ravenwood")
@RavenwoodProvidingImplementation(target = Context.class)
class ContextImpl extends Context {
    private final static String TAG = "ContextImpl";
    private final static boolean DEBUG = false;
@@ -381,16 +383,7 @@ class ContextImpl extends Context {

    // The system service cache for the system services that are cached per-ContextImpl.
    @UnsupportedAppUsage
    final Object[] mServiceCache = createServiceCache();

    @RavenwoodReplace
    private static Object[] createServiceCache() {
        return SystemServiceRegistry.createServiceCache();
    }

    private static Object[] createServiceCache$ravenwood() {
        return new Object[0];
    }
    final Object[] mServiceCache = SystemServiceRegistry.createServiceCache();

    static final int STATE_UNINITIALIZED = 0;
    static final int STATE_INITIALIZING = 1;
@@ -455,17 +448,23 @@ class ContextImpl extends Context {
    }

    @Override
    @RavenwoodKeep
    public PackageManager getPackageManager() {
        if (mPackageManager != null) {
            return mPackageManager;
        }
        // Doesn't matter if we make more than one instance, so no synchronization
        // is needed on mPackageManager.
        mPackageManager = getPackageManagerInner();
        return mPackageManager;
    }

    @RavenwoodRedirect
    private PackageManager getPackageManagerInner() {
        final IPackageManager pm = ActivityThread.getPackageManager();
        if (pm != null) {
            // Doesn't matter if we make more than one instance.
            return (mPackageManager = new ApplicationPackageManager(this, pm));
            return new ApplicationPackageManager(this, pm);
        }

        return null;
    }

@@ -512,6 +511,7 @@ class ContextImpl extends Context {
    }

    @Override
    @RavenwoodKeep
    public Resources.Theme getTheme() {
        synchronized (mThemeLock) {
            if (mTheme != null) {
@@ -520,12 +520,13 @@ class ContextImpl extends Context {

            mThemeResource = Resources.selectDefaultTheme(mThemeResource,
                    getOuterContext().getApplicationInfo().targetSdkVersion);
            initializeTheme();
            initializeTheme(); // XXX TODO: does it work??

            return mTheme;
        }
    }

    @RavenwoodKeep
    private void initializeTheme() {
        if (mTheme == null) {
            mTheme = mResources.newTheme();
@@ -584,6 +585,7 @@ class ContextImpl extends Context {
    }

    @Override
    @RavenwoodKeep
    public ApplicationInfo getApplicationInfo() {
        if (mPackageInfo != null) {
            return mPackageInfo.getApplicationInfo();
@@ -592,6 +594,7 @@ class ContextImpl extends Context {
    }

    @Override
    @RavenwoodKeep
    public String getPackageResourcePath() {
        if (mPackageInfo != null) {
            return mPackageInfo.getResDir();
@@ -791,6 +794,7 @@ class ContextImpl extends Context {
    }

    @Override
    @RavenwoodKeep
    public FileInputStream openFileInput(String name)
        throws FileNotFoundException {
        File f = makeFilename(getFilesDir(), name);
@@ -798,6 +802,7 @@ class ContextImpl extends Context {
    }

    @Override
    @RavenwoodKeep
    public FileOutputStream openFileOutput(String name, int mode) throws FileNotFoundException {
        checkMode(mode);
        final boolean append = (mode&MODE_APPEND) != 0;
@@ -821,6 +826,7 @@ class ContextImpl extends Context {
    }

    @Override
    @RavenwoodKeep
    public boolean deleteFile(String name) {
        File f = makeFilename(getFilesDir(), name);
        return f.delete();
@@ -829,15 +835,18 @@ class ContextImpl extends Context {
    /**
     * Common-path handling of app data dir creation
     */
    @RavenwoodKeep
    private static File ensurePrivateDirExists(File file) {
        return ensurePrivateDirExists(file, 0771, -1, null);
    }

    @RavenwoodKeep(comment = "xattr is ignored")
    private static File ensurePrivateCacheDirExists(File file, String xattr) {
        final int gid = UserHandle.getCacheAppGid(Process.myUid());
        return ensurePrivateDirExists(file, 02771, gid, xattr);
    }

    @RavenwoodRedirect(comment = "gid, xattr are ignored")
    private static File ensurePrivateDirExists(File file, int mode, int gid, String xattr) {
        if (!file.exists()) {
            final String path = file.getAbsolutePath();
@@ -870,6 +879,7 @@ class ContextImpl extends Context {
    }

    @Override
    @RavenwoodKeep
    public File getFilesDir() {
        synchronized (mFilesDirLock) {
            if (mFilesDir == null) {
@@ -898,6 +908,7 @@ class ContextImpl extends Context {
    }

    @Override
    @RavenwoodKeep
    public File getNoBackupFilesDir() {
        synchronized (mNoBackupFilesDirLock) {
            if (mNoBackupFilesDir == null) {
@@ -941,6 +952,7 @@ class ContextImpl extends Context {
    }

    @Override
    @RavenwoodKeep
    public File getCacheDir() {
        synchronized (mCacheDirLock) {
            if (mCacheDir == null) {
@@ -951,6 +963,7 @@ class ContextImpl extends Context {
    }

    @Override
    @RavenwoodKeep
    public File getCodeCacheDir() {
        synchronized (mCodeCacheDirLock) {
            if (mCodeCacheDir == null) {
@@ -1005,11 +1018,13 @@ class ContextImpl extends Context {
    }

    @Override
    @RavenwoodKeep
    public File getFileStreamPath(String name) {
        return makeFilename(getFilesDir(), name);
    }

    @Override
    @RavenwoodKeep
    public File getSharedPreferencesPath(String name) {
        return makeFilename(getPreferencesDir(), name + ".xml");
    }
@@ -2342,6 +2357,7 @@ class ContextImpl extends Context {
    }

    @Override
    @RavenwoodKeep
    public Object getSystemService(String name) {
        if (vmIncorrectContextUseEnabled()) {
            // Check incorrect Context usage.
@@ -2362,6 +2378,7 @@ class ContextImpl extends Context {
    }

    @Override
    @RavenwoodKeep
    public String getSystemServiceName(Class<?> serviceClass) {
        return SystemServiceRegistry.getSystemServiceName(serviceClass);
    }
@@ -2394,6 +2411,7 @@ class ContextImpl extends Context {
     * TODO(b/147647877): Fix usages and remove.
     */
    @SuppressWarnings("AndroidFrameworkClientSidePermissionCheck")
    @RavenwoodIgnore // Always false on Ravenwood.
    private static boolean isSystemOrSystemUI(Context context) {
        return ActivityThread.isSystem() || context.checkPermission(
                "android.permission.STATUS_BAR_SERVICE",
@@ -3185,16 +3203,19 @@ class ContextImpl extends Context {
    }

    @Override
    @RavenwoodKeep
    public boolean isDeviceProtectedStorage() {
        return (mFlags & Context.CONTEXT_DEVICE_PROTECTED_STORAGE) != 0;
    }

    @Override
    @RavenwoodKeep
    public boolean isCredentialProtectedStorage() {
        return (mFlags & Context.CONTEXT_CREDENTIAL_PROTECTED_STORAGE) != 0;
    }

    @Override
    @RavenwoodKeep
    public boolean canLoadUnsafeResources() {
        if (getPackageName().equals(getOpPackageName())) {
            return true;
@@ -3382,6 +3403,7 @@ class ContextImpl extends Context {
    }

    @Override
    @RavenwoodKeep
    public File getDataDir() {
        if (mPackageInfo != null) {
            File res = null;
@@ -3410,6 +3432,7 @@ class ContextImpl extends Context {
    }

    @Override
    @RavenwoodKeep
    public File getDir(String name, int mode) {
        checkMode(mode);
        name = "app_" + name;
@@ -3516,10 +3539,12 @@ class ContextImpl extends Context {
    }

    @UnsupportedAppUsage
    @RavenwoodKeep
    static ContextImpl createAppContext(ActivityThread mainThread, LoadedApk packageInfo) {
        return createAppContext(mainThread, packageInfo, null);
    }

    @RavenwoodKeep
    static ContextImpl createAppContext(ActivityThread mainThread, LoadedApk packageInfo,
            String opPackageName) {
        if (packageInfo == null) throw new IllegalArgumentException("packageInfo");
@@ -3752,11 +3777,13 @@ class ContextImpl extends Context {
    }

    @UnsupportedAppUsage
    @RavenwoodKeep
    final void setOuterContext(@NonNull Context context) {
        mOuterContext = context;
    }

    @UnsupportedAppUsage
    @RavenwoodKeep
    final Context getOuterContext() {
        return mOuterContext;
    }
@@ -3778,6 +3805,7 @@ class ContextImpl extends Context {
        }
    }

    @RavenwoodIgnore(comment = "Not simulating file permissions")
    private void checkMode(int mode) {
        if (getApplicationInfo().targetSdkVersion >= Build.VERSION_CODES.N) {
            if ((mode & MODE_WORLD_READABLE) != 0) {
@@ -3790,6 +3818,7 @@ class ContextImpl extends Context {
    }

    @SuppressWarnings("deprecation")
    @RavenwoodIgnore(comment = "Not simulating file permissions")
    static void setFilePermissionsFromMode(String name, int mode,
            int extraPermissions) {
        int perms = FileUtils.S_IRUSR|FileUtils.S_IWUSR
@@ -3808,18 +3837,24 @@ class ContextImpl extends Context {
        FileUtils.setPermissions(name, perms, -1, -1);
    }

    @RavenwoodKeep
    private File makeFilename(File base, String name) {
        if (name.indexOf(File.separatorChar) < 0) {
            final File res = new File(base, name);
            // We report as filesystem access here to give us the best shot at
            // detecting apps that will pass the path down to native code.
            BlockGuard.getVmPolicy().onPathAccess(res.getPath());
            onPathAccess(res.getPath());
            return res;
        }
        throw new IllegalArgumentException(
                "File " + name + " contains a path separator");
    }

    @RavenwoodIgnore(blockedBy = BlockGuard.class)
    private static void onPathAccess(@NonNull String path) {
        BlockGuard.getVmPolicy().onPathAccess(path);
    }

    /**
     * Ensure that given directories exist, trying to create them if missing. If
     * unable to create, they are filtered by replacing with {@code null}.
+48 −0
Original line number Diff line number Diff line
@@ -15,5 +15,53 @@
 */
package android.app;

import static java.lang.annotation.ElementType.FIELD;
import static java.lang.annotation.ElementType.METHOD;
import static java.lang.annotation.ElementType.PARAMETER;

import android.content.Context;
import android.content.pm.PackageManager;
import android.os.FileUtils;
import android.platform.test.ravenwood.RavenwoodPackageManager;

import java.io.File;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

public class ContextImpl_ravenwood {
    private static final String TAG = "ContextImpl_ravenwood";

    /** Indicates a {@link Context} is really a {@link ContextImpl}. */
    @Target({FIELD, METHOD, PARAMETER})
    @Retention(RetentionPolicy.SOURCE)
    public @interface ReallyContextImpl {
    }

    /** Backdoor to a package-private method. */
    public static ContextImpl createSystemContext(ActivityThread at) {
        return ContextImpl.createSystemContext(at);
    }

    /** Backdoor to a package-private method. */
    public static ContextImpl createAppContext(ActivityThread at, LoadedApk la) {
        return ContextImpl.createAppContext(at, la);
    }

    static PackageManager getPackageManagerInner(ContextImpl contextImpl) {
        return new RavenwoodPackageManager(contextImpl);
    }

    static File ensurePrivateDirExists(File file, int mode, int gid, String xattr) {
        if (!file.exists()) {
            final String path = file.getAbsolutePath();
            file.mkdirs();

            // setPermissions() may fail and return an error status, but we just ignore
            // it just like the real method ignores exceptions.
            // setPermissions() does a log though.
            FileUtils.setPermissions(path, mode, -1, -1);
        }
        return file;
    }
}
Loading