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

Commit 72fd8769 authored by Jared Duke's avatar Jared Duke
Browse files

Remove framework support for compiled views

This feature did not ship and is being removed. The performance benefits
were unclear and the additional complextiy was non-trivial. Remove
associated support in the framework.

Bug: 158121974
Test: m
Change-Id: I580f7616fe517ad8ef3126d1635fe978d2a1c322
parent c8f659f2
Loading
Loading
Loading
Loading
+0 −4
Original line number Diff line number Diff line
@@ -3493,10 +3493,6 @@ package android.view {
    method public boolean isSystemGroup();
  }

  public abstract class LayoutInflater {
    method public void setPrecompiledLayoutsEnabledForTesting(boolean);
  }

  public final class MotionEvent extends android.view.InputEvent implements android.os.Parcelable {
    method public int getDisplayId();
    method public void setActionButton(int);
+65 −194
Original line number Diff line number Diff line
@@ -20,11 +20,9 @@ import android.annotation.LayoutRes;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.SystemService;
import android.annotation.TestApi;
import android.annotation.UiContext;
import android.compat.annotation.UnsupportedAppUsage;
import android.content.Context;
import android.content.pm.ApplicationInfo;
import android.content.res.Resources;
import android.content.res.TypedArray;
import android.content.res.XmlResourceParser;
@@ -42,15 +40,11 @@ import android.widget.FrameLayout;

import com.android.internal.R;

import dalvik.system.PathClassLoader;

import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;

import java.io.File;
import java.io.IOException;
import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Objects;

@@ -82,12 +76,6 @@ public abstract class LayoutInflater {
    private static final String TAG = LayoutInflater.class.getSimpleName();
    private static final boolean DEBUG = false;

    private static final String COMPILED_VIEW_DEX_FILE_NAME = "/compiled_view.dex";
    /**
     * Whether or not we use the precompiled layout.
     */
    private static final String USE_PRECOMPILED_LAYOUT = "view.precompiled_layout_enabled";

    /** Empty stack trace used to avoid log spam in re-throw exceptions. */
    private static final StackTraceElement[] EMPTY_STACK_TRACE = new StackTraceElement[0];

@@ -116,13 +104,6 @@ public abstract class LayoutInflater {
    private Factory2 mPrivateFactory;
    private Filter mFilter;

    // Indicates whether we should try to inflate layouts using a precompiled layout instead of
    // inflating from the XML resource.
    private boolean mUseCompiledView;
    // This variable holds the classloader that will be used to look for precompiled layouts. The
    // The classloader includes the generated compiled_view.dex file.
    private ClassLoader mPrecompiledClassLoader;

    /**
     * This is not a public API. Two APIs are now available to alleviate the need to access
     * this directly: {@link #createView(Context, String, String, AttributeSet)} and
@@ -259,7 +240,6 @@ public abstract class LayoutInflater {
    protected LayoutInflater(Context context) {
        StrictMode.assertConfigurationContext(context, "LayoutInflater");
        mContext = context;
        initPrecompiledViews();
    }

    /**
@@ -277,7 +257,6 @@ public abstract class LayoutInflater {
        mFactory2 = original.mFactory2;
        mPrivateFactory = original.mPrivateFactory;
        setFilter(original.mFilter);
        initPrecompiledViews();
    }

    /**
@@ -419,57 +398,6 @@ public abstract class LayoutInflater {
        }
    }

    private void initPrecompiledViews() {
        // Precompiled layouts are not supported in this release.
        boolean enabled = false;
        initPrecompiledViews(enabled);
    }

    private void initPrecompiledViews(boolean enablePrecompiledViews) {
        mUseCompiledView = enablePrecompiledViews;

        if (!mUseCompiledView) {
            mPrecompiledClassLoader = null;
            return;
        }

        // Make sure the application allows code generation
        ApplicationInfo appInfo = mContext.getApplicationInfo();
        if (appInfo.isEmbeddedDexUsed() || appInfo.isPrivilegedApp()) {
            mUseCompiledView = false;
            return;
        }

        // Try to load the precompiled layout file.
        try {
            mPrecompiledClassLoader = mContext.getClassLoader();
            String dexFile = mContext.getCodeCacheDir() + COMPILED_VIEW_DEX_FILE_NAME;
            if (new File(dexFile).exists()) {
                mPrecompiledClassLoader = new PathClassLoader(dexFile, mPrecompiledClassLoader);
            } else {
                // If the precompiled layout file doesn't exist, then disable precompiled
                // layouts.
                mUseCompiledView = false;
            }
        } catch (Throwable e) {
            if (DEBUG) {
                Log.e(TAG, "Failed to initialized precompiled views layouts", e);
            }
            mUseCompiledView = false;
        }
        if (!mUseCompiledView) {
            mPrecompiledClassLoader = null;
        }
    }

    /**
     * @hide for use by CTS tests
     */
    @TestApi
    public void setPrecompiledLayoutsEnabledForTesting(boolean enablePrecompiledLayouts) {
        initPrecompiledViews(enablePrecompiledLayouts);
    }

    /**
     * Inflate a new view hierarchy from the specified xml resource. Throws
     * {@link InflateException} if there is an error.
@@ -529,10 +457,6 @@ public abstract class LayoutInflater {
                  + Integer.toHexString(resource) + ")");
        }

        View view = tryInflatePrecompiled(resource, res, root, attachToRoot);
        if (view != null) {
            return view;
        }
        XmlResourceParser parser = res.getLayout(resource);
        try {
            return inflate(parser, root, attachToRoot);
@@ -541,54 +465,6 @@ public abstract class LayoutInflater {
        }
    }

    private @Nullable
    View tryInflatePrecompiled(@LayoutRes int resource, Resources res, @Nullable ViewGroup root,
        boolean attachToRoot) {
        if (!mUseCompiledView) {
            return null;
        }

        Trace.traceBegin(Trace.TRACE_TAG_VIEW, "inflate (precompiled)");

        // Try to inflate using a precompiled layout.
        String pkg = res.getResourcePackageName(resource);
        String layout = res.getResourceEntryName(resource);

        try {
            Class clazz = Class.forName("" + pkg + ".CompiledView", false, mPrecompiledClassLoader);
            Method inflater = clazz.getMethod(layout, Context.class, int.class);
            View view = (View) inflater.invoke(null, mContext, resource);

            if (view != null && root != null) {
                // We were able to use the precompiled inflater, but now we need to do some work to
                // attach the view to the root correctly.
                XmlResourceParser parser = res.getLayout(resource);
                try {
                    AttributeSet attrs = Xml.asAttributeSet(parser);
                    advanceToRootNode(parser);
                    ViewGroup.LayoutParams params = root.generateLayoutParams(attrs);

                    if (attachToRoot) {
                        root.addView(view, params);
                    } else {
                        view.setLayoutParams(params);
                    }
                } finally {
                    parser.close();
                }
            }

            return view;
        } catch (Throwable e) {
            if (DEBUG) {
                Log.e(TAG, "Failed to use precompiled view", e);
            }
        } finally {
            Trace.traceEnd(Trace.TRACE_TAG_VIEW);
        }
        return null;
    }

    /**
     * Advances the given parser to the first START_TAG. Throws InflateException if no start tag is
     * found.
@@ -1050,7 +926,7 @@ public abstract class LayoutInflater {
     * of the general view creation logic, and thus may return {@code null} for some tags. This
     * method is used by {@link LayoutInflater#inflate} in creating {@code View} objects.
     *
     * @hide for use by precompiled layouts.
     * @hide originally for internal use by precompiled layouts, which have since been removed.
     *
     * @param parent the parent view, used to inflate layout params
     * @param name the name of the XML tag used to define the view
@@ -1217,16 +1093,12 @@ public abstract class LayoutInflater {
                + "reference. The layout ID " + value + " is not valid.");
        }

        final View precompiled = tryInflatePrecompiled(layout, context.getResources(),
            (ViewGroup) parent, /*attachToRoot=*/true);
        if (precompiled == null) {
        final XmlResourceParser childParser = context.getResources().getLayout(layout);

        try {
            final AttributeSet childAttrs = Xml.asAttributeSet(childParser);

                while ((type = childParser.next()) != XmlPullParser.START_TAG &&
                    type != XmlPullParser.END_DOCUMENT) {
            while ((type = childParser.next()) != XmlPullParser.START_TAG
                    && type != XmlPullParser.END_DOCUMENT) {
                // Empty.
            }

@@ -1242,12 +1114,11 @@ public abstract class LayoutInflater {
                // nothing special to do here.
                rInflate(childParser, parent, context, childAttrs, false);
            } else {
                    final View view = createViewFromTag(parent, childName,
                        context, childAttrs, hasThemeOverride);
                final View view =
                        createViewFromTag(parent, childName, context, childAttrs, hasThemeOverride);
                final ViewGroup group = (ViewGroup) parent;

                    final TypedArray a = context.obtainStyledAttributes(
                        attrs, R.styleable.Include);
                final TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.Include);
                final int id = a.getResourceId(R.styleable.Include_id, View.NO_ID);
                final int visibility = a.getInt(R.styleable.Include_visibility, -1);
                a.recycle();
@@ -1295,7 +1166,7 @@ public abstract class LayoutInflater {
        } finally {
            childParser.close();
        }
        }

        LayoutInflater.consumeChildElements(parser);
    }

+0 −5
Original line number Diff line number Diff line
@@ -223,11 +223,6 @@ public final class DexOptHelper {
                pkgCompilationReason = PackageManagerService.REASON_BACKGROUND_DEXOPT;
            }

            // TODO(b/251903639): Do this when ART Service is used, or remove it from here.
            if (SystemProperties.getBoolean(mPm.PRECOMPILE_LAYOUTS, false)) {
                mPm.mArtManagerService.compileLayouts(packageState, pkg);
            }

            int dexoptFlags = bootComplete ? DexoptOptions.DEXOPT_BOOT_COMPLETE : 0;

            String filter = getCompilerFilterForReason(pkgCompilationReason);
+0 −12
Original line number Diff line number Diff line
@@ -59,7 +59,6 @@ import static com.android.server.pm.PackageManagerService.DEBUG_VERIFY;
import static com.android.server.pm.PackageManagerService.MIN_INSTALLABLE_TARGET_SDK;
import static com.android.server.pm.PackageManagerService.PLATFORM_PACKAGE_NAME;
import static com.android.server.pm.PackageManagerService.POST_INSTALL;
import static com.android.server.pm.PackageManagerService.PRECOMPILE_LAYOUTS;
import static com.android.server.pm.PackageManagerService.SCAN_AS_APEX;
import static com.android.server.pm.PackageManagerService.SCAN_AS_APK_IN_APEX;
import static com.android.server.pm.PackageManagerService.SCAN_AS_FACTORY;
@@ -135,7 +134,6 @@ import android.os.Message;
import android.os.Process;
import android.os.RemoteException;
import android.os.SELinux;
import android.os.SystemProperties;
import android.os.Trace;
import android.os.UserHandle;
import android.os.UserManager;
@@ -167,7 +165,6 @@ import com.android.server.pm.Installer.LegacyDexoptDisabledException;
import com.android.server.pm.dex.ArtManagerService;
import com.android.server.pm.dex.DexManager;
import com.android.server.pm.dex.DexoptOptions;
import com.android.server.pm.dex.ViewCompiler;
import com.android.server.pm.parsing.PackageCacher;
import com.android.server.pm.parsing.PackageParser2;
import com.android.server.pm.parsing.pkg.AndroidPackageUtils;
@@ -222,7 +219,6 @@ final class InstallPackageHelper {
    private final Context mContext;
    private final PackageDexOptimizer mPackageDexOptimizer;
    private final PackageAbiHelper mPackageAbiHelper;
    private final ViewCompiler mViewCompiler;
    private final SharedLibrariesImpl mSharedLibraries;
    private final PackageManagerServiceInjector mInjector;
    private final UpdateOwnershipHelper mUpdateOwnershipHelper;
@@ -246,7 +242,6 @@ final class InstallPackageHelper {
        mContext = pm.mInjector.getContext();
        mPackageDexOptimizer = pm.mInjector.getPackageDexOptimizer();
        mPackageAbiHelper = pm.mInjector.getAbiHelper();
        mViewCompiler = pm.mInjector.getViewCompiler();
        mSharedLibraries = pm.mInjector.getSharedLibrariesImpl();
        mUpdateOwnershipHelper = pm.mInjector.getUpdateOwnershipHelper();
    }
@@ -2538,13 +2533,6 @@ final class InstallPackageHelper {
                            && !isApex;

            if (performDexopt) {
                // Compile the layout resources.
                if (SystemProperties.getBoolean(PRECOMPILE_LAYOUTS, false)) {
                    Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "compileLayouts");
                    mViewCompiler.compileLayouts(ps, pkg.getBaseApkPath());
                    Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
                }

                Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "dexopt");

                // This mirrors logic from commitReconciledScanResultLocked, where the library files
+0 −8
Original line number Diff line number Diff line
@@ -1128,14 +1128,6 @@ public class Installer extends SystemService {
        throw new InstallerException("Invalid instruction set: " + instructionSet);
    }

    public boolean compileLayouts(String apkPath, String packageName, String outDexFile, int uid) {
        try {
            return mInstalld.compileLayouts(apkPath, packageName, outDexFile, uid);
        } catch (RemoteException e) {
            return false;
        }
    }

    /**
     * Returns the visibility of the optimized artifacts.
     *
Loading