Revert "Move Resource creation out of ContextImpl constructor"

This reverts commit 16efc5e68d77903b84943bd9917bfd858332c183.

Caused issue with device protected settings: http://b/33066012

Change-Id: Ib485bed68ea8ac199d553b666c18d048a5624c98
(cherry picked from commit 304321ed8d0a2c74b8ceb32a55dcaa2f2c01ea57)
diff --git a/core/java/android/app/ContextImpl.java b/core/java/android/app/ContextImpl.java
index 496c05f..827e026 100644
--- a/core/java/android/app/ContextImpl.java
+++ b/core/java/android/app/ContextImpl.java
@@ -33,6 +33,7 @@
 import android.content.ReceiverCallNotAllowedException;
 import android.content.ServiceConnection;
 import android.content.SharedPreferences;
+import android.content.pm.ActivityInfo;
 import android.content.pm.ApplicationInfo;
 import android.content.pm.IPackageManager;
 import android.content.pm.PackageManager;
@@ -159,7 +160,7 @@
     private final String mOpPackageName;
 
     private final @NonNull ResourcesManager mResourcesManager;
-    private @NonNull Resources mResources;
+    private final @NonNull Resources mResources;
     private @Nullable Display mDisplay; // may be null if default display
 
     private final int mFlags;
@@ -1834,19 +1835,6 @@
         }
     }
 
-    private static Resources createResources(IBinder activityToken, LoadedApk pi, int displayId,
-            Configuration overrideConfig, CompatibilityInfo compatInfo) {
-        return ResourcesManager.getInstance().getResources(activityToken,
-                pi.getResDir(),
-                pi.getSplitResDirs(),
-                pi.getOverlayDirs(),
-                pi.getApplicationInfo().sharedLibraryFiles,
-                displayId,
-                overrideConfig,
-                compatInfo,
-                pi.getClassLoader());
-    }
-
     @Override
     public Context createApplicationContext(ApplicationInfo application, int flags)
             throws NameNotFoundException {
@@ -1854,13 +1842,8 @@
                 flags | CONTEXT_REGISTER_PACKAGE);
         if (pi != null) {
             ContextImpl c = new ContextImpl(this, mMainThread, pi, mActivityToken,
-                    new UserHandle(UserHandle.getUserId(application.uid)), flags);
-
-            final int displayId = mDisplay != null
-                    ? mDisplay.getDisplayId() : Display.DEFAULT_DISPLAY;
-
-            c.mResources = createResources(mActivityToken, pi, displayId, null,
-                    getDisplayAdjustments(displayId).getCompatibilityInfo());
+                    new UserHandle(UserHandle.getUserId(application.uid)), flags,
+                    mDisplay, null, Display.INVALID_DISPLAY);
             if (c.mResources != null) {
                 return c;
             }
@@ -1881,21 +1864,15 @@
     public Context createPackageContextAsUser(String packageName, int flags, UserHandle user)
             throws NameNotFoundException {
         if (packageName.equals("system") || packageName.equals("android")) {
-            // The system resources are loaded in every application, so we can safely copy
-            // the context without reloading Resources.
-            return new ContextImpl(this, mMainThread, mPackageInfo, mActivityToken, user, flags);
+            return new ContextImpl(this, mMainThread, mPackageInfo, mActivityToken,
+                    user, flags, mDisplay, null, Display.INVALID_DISPLAY);
         }
 
         LoadedApk pi = mMainThread.getPackageInfo(packageName, mResources.getCompatibilityInfo(),
                 flags | CONTEXT_REGISTER_PACKAGE, user.getIdentifier());
         if (pi != null) {
-            ContextImpl c = new ContextImpl(this, mMainThread, pi, mActivityToken, user, flags);
-
-            final int displayId = mDisplay != null
-                    ? mDisplay.getDisplayId() : Display.DEFAULT_DISPLAY;
-
-            c.mResources = createResources(mActivityToken, pi, displayId, null,
-                    getDisplayAdjustments(displayId).getCompatibilityInfo());
+            ContextImpl c = new ContextImpl(this, mMainThread, pi, mActivityToken,
+                    user, flags, mDisplay, null, Display.INVALID_DISPLAY);
             if (c.mResources != null) {
                 return c;
             }
@@ -1912,14 +1889,8 @@
             throw new IllegalArgumentException("overrideConfiguration must not be null");
         }
 
-        ContextImpl context = new ContextImpl(this, mMainThread, mPackageInfo, mActivityToken,
-                mUser, mFlags);
-
-        final int displayId = mDisplay != null ? mDisplay.getDisplayId() : Display.DEFAULT_DISPLAY;
-        context.mResources = createResources(mActivityToken, mPackageInfo, displayId,
-                overrideConfiguration, getDisplayAdjustments(displayId).getCompatibilityInfo());
-        context.mDisplay = mDisplay;
-        return context;
+        return new ContextImpl(this, mMainThread, mPackageInfo, mActivityToken,
+                mUser, mFlags, mDisplay, overrideConfiguration, Display.INVALID_DISPLAY);
     }
 
     @Override
@@ -1928,28 +1899,24 @@
             throw new IllegalArgumentException("display must not be null");
         }
 
-        ContextImpl context = new ContextImpl(this, mMainThread, mPackageInfo, mActivityToken,
-                mUser, mFlags);
-
-        final int displayId = display.getDisplayId();
-        context.mResources = createResources(mActivityToken, mPackageInfo, displayId, null,
-                getDisplayAdjustments(displayId).getCompatibilityInfo());
-        context.mDisplay = display;
-        return context;
+        return new ContextImpl(this, mMainThread, mPackageInfo, mActivityToken,
+                mUser, mFlags, display, null, Display.INVALID_DISPLAY);
     }
 
     @Override
     public Context createDeviceProtectedStorageContext() {
         final int flags = (mFlags & ~Context.CONTEXT_CREDENTIAL_PROTECTED_STORAGE)
                 | Context.CONTEXT_DEVICE_PROTECTED_STORAGE;
-        return new ContextImplFlagContextWrapper(this, flags);
+        return new ContextImpl(this, mMainThread, mPackageInfo, mActivityToken,
+                mUser, flags, mDisplay, null, Display.INVALID_DISPLAY);
     }
 
     @Override
     public Context createCredentialProtectedStorageContext() {
         final int flags = (mFlags & ~Context.CONTEXT_DEVICE_PROTECTED_STORAGE)
                 | Context.CONTEXT_CREDENTIAL_PROTECTED_STORAGE;
-        return new ContextImplFlagContextWrapper(this, flags);
+        return new ContextImpl(this, mMainThread, mPackageInfo, mActivityToken,
+                mUser, flags, mDisplay, null, Display.INVALID_DISPLAY);
     }
 
     @Override
@@ -2036,8 +2003,8 @@
 
     static ContextImpl createSystemContext(ActivityThread mainThread) {
         LoadedApk packageInfo = new LoadedApk(mainThread);
-        ContextImpl context = new ContextImpl(null, mainThread, packageInfo, null, null, 0);
-        context.mResources = packageInfo.getResources(mainThread);
+        ContextImpl context = new ContextImpl(null, mainThread,
+                packageInfo, null, null, 0, null, null, Display.INVALID_DISPLAY);
         context.mResources.updateConfiguration(context.mResourcesManager.getConfiguration(),
                 context.mResourcesManager.getDisplayMetrics());
         return context;
@@ -2045,35 +2012,21 @@
 
     static ContextImpl createAppContext(ActivityThread mainThread, LoadedApk packageInfo) {
         if (packageInfo == null) throw new IllegalArgumentException("packageInfo");
-        ContextImpl context = new ContextImpl(null, mainThread, packageInfo, null, null, 0);
-        context.mResources = packageInfo.getResources(mainThread);
-        return context;
+        return new ContextImpl(null, mainThread,
+                packageInfo, null, null, 0, null, null, Display.INVALID_DISPLAY);
     }
 
     static ContextImpl createActivityContext(ActivityThread mainThread,
             LoadedApk packageInfo, IBinder activityToken, int displayId,
             Configuration overrideConfiguration) {
         if (packageInfo == null) throw new IllegalArgumentException("packageInfo");
-
-        ContextImpl context = new ContextImpl(null, mainThread, packageInfo, activityToken, null,
-                0);
-
-        // Clamp display ID to DEFAULT_DISPLAY if it is INVALID_DISPLAY.
-        displayId = (displayId != Display.INVALID_DISPLAY) ? displayId : Display.DEFAULT_DISPLAY;
-
-        final CompatibilityInfo compatInfo = (displayId == Display.DEFAULT_DISPLAY)
-                ? packageInfo.getCompatibilityInfo()
-                : CompatibilityInfo.DEFAULT_COMPATIBILITY_INFO;
-
-        context.mResources = createResources(activityToken, packageInfo, displayId,
-                overrideConfiguration, compatInfo);
-        context.mDisplay = ResourcesManager.getInstance().getAdjustedDisplay(displayId,
-                context.mResources.getDisplayAdjustments());
-        return context;
+        return new ContextImpl(null, mainThread, packageInfo, activityToken, null, 0,
+                null, overrideConfiguration, displayId);
     }
 
     private ContextImpl(ContextImpl container, ActivityThread mainThread,
-            LoadedApk packageInfo, IBinder activityToken, UserHandle user, int flags) {
+            LoadedApk packageInfo, IBinder activityToken, UserHandle user, int flags,
+            Display display, Configuration overrideConfiguration, int createDisplayWithId) {
         mOuterContext = this;
 
         // If creator didn't specify which storage to use, use the default
@@ -2100,11 +2053,64 @@
         mPackageInfo = packageInfo;
         mResourcesManager = ResourcesManager.getInstance();
 
+        final int displayId = (createDisplayWithId != Display.INVALID_DISPLAY)
+                ? createDisplayWithId
+                : (display != null) ? display.getDisplayId() : Display.DEFAULT_DISPLAY;
+
+        CompatibilityInfo compatInfo = null;
+        if (container != null) {
+            compatInfo = container.getDisplayAdjustments(displayId).getCompatibilityInfo();
+        }
+        if (compatInfo == null) {
+            compatInfo = (displayId == Display.DEFAULT_DISPLAY)
+                    ? packageInfo.getCompatibilityInfo()
+                    : CompatibilityInfo.DEFAULT_COMPATIBILITY_INFO;
+        }
+
+        Resources resources = packageInfo.getResources(mainThread);
+        if (resources != null) {
+            if (displayId != Display.DEFAULT_DISPLAY
+                    || overrideConfiguration != null
+                    || (compatInfo != null && compatInfo.applicationScale
+                            != resources.getCompatibilityInfo().applicationScale)) {
+
+                if (container != null) {
+                    // This is a nested Context, so it can't be a base Activity context.
+                    // Just create a regular Resources object associated with the Activity.
+                    resources = mResourcesManager.getResources(
+                            activityToken,
+                            packageInfo.getResDir(),
+                            packageInfo.getSplitResDirs(),
+                            packageInfo.getOverlayDirs(),
+                            packageInfo.getApplicationInfo().sharedLibraryFiles,
+                            displayId,
+                            overrideConfiguration,
+                            compatInfo,
+                            packageInfo.getClassLoader());
+                } else {
+                    // This is not a nested Context, so it must be the root Activity context.
+                    // All other nested Contexts will inherit the configuration set here.
+                    resources = mResourcesManager.createBaseActivityResources(
+                            activityToken,
+                            packageInfo.getResDir(),
+                            packageInfo.getSplitResDirs(),
+                            packageInfo.getOverlayDirs(),
+                            packageInfo.getApplicationInfo().sharedLibraryFiles,
+                            displayId,
+                            overrideConfiguration,
+                            compatInfo,
+                            packageInfo.getClassLoader());
+                }
+            }
+        }
+        mResources = resources;
+
+        mDisplay = (createDisplayWithId == Display.INVALID_DISPLAY) ? display
+                : mResourcesManager.getAdjustedDisplay(displayId, mResources.getDisplayAdjustments());
+
         if (container != null) {
             mBasePackageName = container.mBasePackageName;
             mOpPackageName = container.mOpPackageName;
-            mResources = container.getResources();
-            mDisplay = container.getDisplay();
         } else {
             mBasePackageName = packageInfo.mPackageName;
             ApplicationInfo ainfo = packageInfo.getApplicationInfo();
diff --git a/core/java/android/app/ContextImplFlagContextWrapper.java b/core/java/android/app/ContextImplFlagContextWrapper.java
deleted file mode 100644
index a83f130..0000000
--- a/core/java/android/app/ContextImplFlagContextWrapper.java
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package android.app;
-
-import android.content.Context;
-import android.content.ContextWrapper;
-
-class ContextImplFlagContextWrapper extends ContextWrapper {
-    private final int mFlags;
-
-    public ContextImplFlagContextWrapper(Context base, int flags) {
-        super(base);
-        mFlags = flags;
-    }
-
-    @Override
-    public boolean isRestricted() {
-        return (mFlags & Context.CONTEXT_RESTRICTED) != 0;
-    }
-
-    @Override
-    public boolean isDeviceProtectedStorage() {
-        return (mFlags & Context.CONTEXT_DEVICE_PROTECTED_STORAGE) != 0;
-    }
-
-    @Override
-    public boolean isCredentialProtectedStorage() {
-        return (mFlags & Context.CONTEXT_CREDENTIAL_PROTECTED_STORAGE) != 0;
-    }
-}