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

Commit b3199f4c authored by Peiyong Lin's avatar Peiyong Lin
Browse files

Allow per-app opt in to use system ANGLE.

Previously the per-app opt in only works for ANGLE apk, this patch
refactors the logic to allow per-app opt in to work for system ANGLE.
This patch checks whether system ANGLE is supported and if it presents,
uses it if the ANGLE apk setup fails.

With this patch, the per-app opt in will function this way:

1) When full ANGLE apk is installed
Regardless of whether system ANGLE is present, the "angle" option will
use ANGLE apk, the "native" option will switch to native GLES drivers
specified by ro.hardware.egl, the "default" option will use whatever the
default graphics driver is loaded.

2) When full ANGLE apk is not installed and system ANGLE is present
The "angle" option will use system ANGLE, the "native" option will
switch to native GLES drivers specified by ro.hardware.egl, the
"default" option will use whatever the default graphics driver is
loaded.

3) When full ANGLE apk is not installed and system ANGLE doesn't exist
The per-app option will not function at all.

Minor: clean up unused and unnecessary variables.
Minor: Avoid sending toast when ANGLE apk doesn't present

Bug: b/283858001
Test: test with camera
Test: atest CtsAngleIntegrationHostTestCases
Change-Id: I83b3c2ccbe7cb38f71418afde4254f48153ab6b3
parent 1160317c
Loading
Loading
Loading
Loading
+67 −21
Original line number Diff line number Diff line
@@ -116,6 +116,8 @@ public class GraphicsEnvironment {
    private static final String ANGLE_GL_DRIVER_CHOICE_ANGLE = "angle";
    private static final String ANGLE_GL_DRIVER_CHOICE_NATIVE = "native";

    private static final String PROPERTY_RO_ANGLE_SUPPORTED = "ro.gfx.angle.supported";

    private ClassLoader mClassLoader;
    private String mLibrarySearchPaths;
    private String mLibraryPermittedPaths;
@@ -501,10 +503,12 @@ public class GraphicsEnvironment {
        final List<ResolveInfo> resolveInfos =
                pm.queryIntentActivities(intent, PackageManager.MATCH_SYSTEM_ONLY);
        if (resolveInfos.size() != 1) {
            Log.e(TAG, "Invalid number of ANGLE packages. Required: 1, Found: "
            Log.v(TAG, "Invalid number of ANGLE packages. Required: 1, Found: "
                    + resolveInfos.size());
            if (DEBUG) {
                for (ResolveInfo resolveInfo : resolveInfos) {
                Log.e(TAG, "Found ANGLE package: " + resolveInfo.activityInfo.packageName);
                    Log.d(TAG, "Found ANGLE package: " + resolveInfo.activityInfo.packageName);
                }
            }
            return "";
        }
@@ -539,26 +543,42 @@ public class GraphicsEnvironment {
    }

    /**
     * Determine whether ANGLE should be used, set it up if so, and pass ANGLE details down to
     * the C++ GraphicsEnv class.
     * Determine whether ANGLE should be used, attempt to set up from apk first, if ANGLE can be
     * set up from apk, pass ANGLE details down to the C++ GraphicsEnv class via
     * GraphicsEnv::setAngleInfo(). If apk setup fails, attempt to set up to use system ANGLE.
     * Return false if both fail.
     *
     * If ANGLE will be used, GraphicsEnv::setAngleInfo() will be called to enable ANGLE to be
     * properly used.
     *
     * @param context
     * @param bundle
     * @param pm
     * @param context - Context of the application.
     * @param bundle - Bundle of the application.
     * @param packageManager - PackageManager of the application process.
     * @param packageName - package name of the application.
     * @return true: ANGLE setup successfully
     *         false: ANGLE not setup (not on allowlist, ANGLE not present, etc.)
     * @return true: can set up to use ANGLE successfully.
     *         false: can not set up to use ANGLE (not on allowlist, ANGLE not present, etc.)
     */
    private boolean setupAngle(Context context, Bundle bundle, PackageManager pm,
    private boolean setupAngle(Context context, Bundle bundle, PackageManager packageManager,
            String packageName) {

        if (!shouldUseAngle(context, bundle, packageName)) {
            return false;
        }

        return setupAngleFromApk(context, bundle, packageManager, packageName)
                || setupAngleFromSystem(context, bundle, packageName);
    }

    /**
     * Attempt to set up ANGLE from the packaged apk, if the apk can be found, pass ANGLE details to
     * the C++ GraphicsEnv class.
     *
     * @param context - Context of the application.
     * @param bundle - Bundle of the application.
     * @param packageManager - PackageManager of the application process.
     * @param packageName - package name of the application.
     * @return true: can set up to use ANGLE apk.
     *         false: can not set up to use ANGLE apk (ANGLE apk not present, etc.)
     */
    private boolean setupAngleFromApk(Context context, Bundle bundle, PackageManager packageManager,
            String packageName) {
        ApplicationInfo angleInfo = null;

        // If the developer has specified a debug package over ADB, attempt to find it
@@ -567,7 +587,7 @@ public class GraphicsEnvironment {
            Log.v(TAG, "ANGLE debug package enabled: " + anglePkgName);
            try {
                // Note the debug package does not have to be pre-installed
                angleInfo = pm.getApplicationInfo(anglePkgName, 0);
                angleInfo = packageManager.getApplicationInfo(anglePkgName, 0);
            } catch (PackageManager.NameNotFoundException e) {
                // If the debug package is specified but not found, abort.
                Log.v(TAG, "ANGLE debug package '" + anglePkgName + "' not installed");
@@ -577,7 +597,7 @@ public class GraphicsEnvironment {

        // Otherwise, check to see if ANGLE is properly installed
        if (angleInfo == null) {
            anglePkgName = getAnglePackageName(pm);
            anglePkgName = getAnglePackageName(packageManager);
            if (TextUtils.isEmpty(anglePkgName)) {
                Log.v(TAG, "Failed to find ANGLE package.");
                return false;
@@ -586,7 +606,7 @@ public class GraphicsEnvironment {
            Log.v(TAG, "ANGLE package enabled: " + anglePkgName);
            try {
                // Production ANGLE libraries must be pre-installed as a system app
                angleInfo = pm.getApplicationInfo(anglePkgName,
                angleInfo = packageManager.getApplicationInfo(anglePkgName,
                        PackageManager.MATCH_SYSTEM_ONLY);
            } catch (PackageManager.NameNotFoundException e) {
                Log.v(TAG, "ANGLE package '" + anglePkgName + "' not installed");
@@ -610,8 +630,32 @@ public class GraphicsEnvironment {
        // If we make it to here, ANGLE will be used.  Call setAngleInfo() with the package name,
        // and features to use.
        final String[] features = getAngleEglFeatures(context, bundle);
        setAngleInfo(paths, packageName, ANGLE_GL_DRIVER_CHOICE_ANGLE, features);
        setAngleInfo(paths, false, packageName, features);

        return true;
    }

    /**
     * Attempt to set up ANGLE from system, if the apk can be found, pass ANGLE details to
     * the C++ GraphicsEnv class.
     *
     * @param context - Context of the application.
     * @param bundle - Bundle of the application.
     * @param packageName - package name of the application.
     * @return true: can set up to use system ANGLE.
     *         false: can not set up to use system ANGLE because it doesn't exist.
     */
    private boolean setupAngleFromSystem(Context context, Bundle bundle, String packageName) {
        final boolean systemAngleSupported = SystemProperties
                                             .getBoolean(PROPERTY_RO_ANGLE_SUPPORTED, false);
        if (!systemAngleSupported) {
            return false;
        }

        // If we make it to here, ANGLE will be used.  Call setAngleInfo() with the package name,
        // and features to use.
        final String[] features = getAngleEglFeatures(context, bundle);
        setAngleInfo("", true, packageName, features);
        return true;
    }

@@ -651,7 +695,9 @@ public class GraphicsEnvironment {

        final Intent intent = new Intent(ACTION_ANGLE_FOR_ANDROID_TOAST_MESSAGE);
        final String anglePkg = getAnglePackageName(context.getPackageManager());
        intent.setPackage(anglePkg);
        if (anglePkg.isEmpty()) {
            return;
        }

        context.sendOrderedBroadcast(intent, null, new BroadcastReceiver() {
            @Override
@@ -890,8 +936,8 @@ public class GraphicsEnvironment {
    private static native void setDriverPathAndSphalLibraries(String path, String sphalLibraries);
    private static native void setGpuStats(String driverPackageName, String driverVersionName,
            long driverVersionCode, long driverBuildTime, String appPackageName, int vulkanVersion);
    private static native void setAngleInfo(String path, String packageName,
            String devOptIn, String[] features);
    private static native void setAngleInfo(String path, boolean useSystemAngle, String packageName,
            String[] features);
    private static native boolean setInjectLayersPrSetDumpable();
    private static native void nativeToggleAngleAsSystemDriver(boolean enabled);

+8 −9
Original line number Diff line number Diff line
@@ -16,11 +16,12 @@

#define LOG_TAG "GraphicsEnvironment"

#include <vector>

#include <graphicsenv/GraphicsEnv.h>
#include <nativehelper/ScopedUtfChars.h>
#include <nativeloader/native_loader.h>

#include <vector>

#include "core_jni_helpers.h"

namespace {
@@ -49,11 +50,10 @@ void setGpuStats_native(JNIEnv* env, jobject clazz, jstring driverPackageName,
                                                    appPackageNameChars.c_str(), vulkanVersion);
}

void setAngleInfo_native(JNIEnv* env, jobject clazz, jstring path, jstring packageName,
                         jstring devOptIn, jobjectArray featuresObj) {
void setAngleInfo_native(JNIEnv* env, jobject clazz, jstring path, jboolean useSystemAngle,
                         jstring packageName, jobjectArray featuresObj) {
    ScopedUtfChars pathChars(env, path);
    ScopedUtfChars packageNameChars(env, packageName);
    ScopedUtfChars devOptInChars(env, devOptIn);

    std::vector<std::string> features;
    if (featuresObj != nullptr) {
@@ -73,8 +73,8 @@ void setAngleInfo_native(JNIEnv* env, jobject clazz, jstring path, jstring packa
        }
    }

    android::GraphicsEnv::getInstance().setAngleInfo(pathChars.c_str(), packageNameChars.c_str(),
                                                     devOptInChars.c_str(), features);
    android::GraphicsEnv::getInstance().setAngleInfo(pathChars.c_str(), useSystemAngle,
                                                     packageNameChars.c_str(), features);
}

void setLayerPaths_native(JNIEnv* env, jobject clazz, jobject classLoader, jstring layerPaths) {
@@ -118,8 +118,7 @@ const JNINativeMethod g_methods[] = {
         reinterpret_cast<void*>(setGpuStats_native)},
        {"setInjectLayersPrSetDumpable", "()Z",
         reinterpret_cast<void*>(setInjectLayersPrSetDumpable_native)},
        {"setAngleInfo",
         "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;[Ljava/lang/String;)V",
        {"setAngleInfo", "(Ljava/lang/String;ZLjava/lang/String;[Ljava/lang/String;)V",
         reinterpret_cast<void*>(setAngleInfo_native)},
        {"setLayerPaths", "(Ljava/lang/ClassLoader;Ljava/lang/String;)V",
         reinterpret_cast<void*>(setLayerPaths_native)},