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

Commit ddc43911 authored by Tim Van Patten's avatar Tim Van Patten
Browse files

ANGLE In Use Dialog Box

When ANGLE is enabled for an app, show a dialog box to the user to
indicate that ANGLE is in use.   This is useful because there are
not (or at least shouldn't be) any visual indication that a different
OpenGL driver is in use.

Bug: 120489005
Test: atest CtsAngleIntegrationHostTestCases
Test: Load an app with ANGLE enabled and verify dialog box is shown.
Test: Load an app without ANGLE and verify dialog box is not shown.
Change-Id: I5e87ec96582d43666cfcca2266b46ce98b859a32
parent 33adf0df
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
@@ -65,6 +65,7 @@ import android.net.Uri;
import android.os.BadParcelableException;
import android.os.Build;
import android.os.Bundle;
import android.os.GraphicsEnvironment;
import android.os.Handler;
import android.os.IBinder;
import android.os.Looper;
@@ -7708,6 +7709,8 @@ public class Activity extends ContextThemeWrapper
            }
        }

        GraphicsEnvironment.getInstance().showAngleInUseDialogBox(this);

        mActivityTransitionState.enterReady(this);
        dispatchActivityPostStarted();
    }
+109 −29
Original line number Diff line number Diff line
@@ -16,6 +16,7 @@

package android.os;

import android.content.ContentResolver;
import android.content.Context;
import android.content.Intent;
import android.content.pm.ApplicationInfo;
@@ -30,6 +31,7 @@ import android.opengl.EGL14;
import android.provider.Settings;
import android.util.Base64;
import android.util.Log;
import android.widget.Toast;

import com.android.framework.protobuf.InvalidProtocolBufferException;

@@ -222,9 +224,17 @@ public class GraphicsEnvironment {
    }


    private static List<String> getGlobalSettingsString(Bundle bundle, String globalSetting) {
        List<String> valueList = null;
        final String settingsValue = bundle.getString(globalSetting);
    private static List<String> getGlobalSettingsString(ContentResolver contentResolver,
                                                        Bundle bundle,
                                                        String globalSetting) {
        final List<String> valueList;
        final String settingsValue;

        if (bundle != null) {
            settingsValue = bundle.getString(globalSetting);
        } else {
            settingsValue = Settings.Global.getString(contentResolver, globalSetting);
        }

        if (settingsValue != null) {
            valueList = new ArrayList<>(Arrays.asList(settingsValue.split(",")));
@@ -246,17 +256,27 @@ public class GraphicsEnvironment {
        return -1;
    }

    private static String getDriverForPkg(Bundle bundle, String packageName) {
        final String allUseAngle =
    private static String getDriverForPkg(Context context, Bundle bundle, String packageName) {
        final String allUseAngle;
        if (bundle != null) {
            allUseAngle =
                    bundle.getString(Settings.Global.GLOBAL_SETTINGS_ANGLE_GL_DRIVER_ALL_ANGLE);
        } else {
            ContentResolver contentResolver = context.getContentResolver();
            allUseAngle = Settings.Global.getString(contentResolver,
                    Settings.Global.GLOBAL_SETTINGS_ANGLE_GL_DRIVER_ALL_ANGLE);
        }
        if ((allUseAngle != null) && allUseAngle.equals("1")) {
            return sDriverMap.get(OpenGlDriverChoice.ANGLE);
        }

        final List<String> globalSettingsDriverPkgs = getGlobalSettingsString(
                bundle, Settings.Global.GLOBAL_SETTINGS_ANGLE_GL_DRIVER_SELECTION_PKGS);
        final List<String> globalSettingsDriverValues = getGlobalSettingsString(
                bundle, Settings.Global.GLOBAL_SETTINGS_ANGLE_GL_DRIVER_SELECTION_VALUES);
        final ContentResolver contentResolver = context.getContentResolver();
        final List<String> globalSettingsDriverPkgs =
                getGlobalSettingsString(contentResolver, bundle,
                        Settings.Global.GLOBAL_SETTINGS_ANGLE_GL_DRIVER_SELECTION_PKGS);
        final List<String> globalSettingsDriverValues =
                getGlobalSettingsString(contentResolver, bundle,
                        Settings.Global.GLOBAL_SETTINGS_ANGLE_GL_DRIVER_SELECTION_VALUES);

        // Make sure we have a good package name
        if ((packageName == null) || (packageName.isEmpty())) {
@@ -308,7 +328,7 @@ public class GraphicsEnvironment {
     * True: Temporary rules file was loaded.
     * False: Temporary rules file was *not* loaded.
     */
    private boolean setupAngleWithTempRulesFile(Context context,
    private static boolean setupAngleWithTempRulesFile(Context context,
                                                String packageName,
                                                String paths,
                                                String devOptIn) {
@@ -372,7 +392,7 @@ public class GraphicsEnvironment {
     * True: APK rules file was loaded.
     * False: APK rules file was *not* loaded.
     */
    private boolean setupAngleRulesApk(String anglePkgName,
    private static boolean setupAngleRulesApk(String anglePkgName,
            ApplicationInfo angleInfo,
            PackageManager pm,
            String packageName,
@@ -405,23 +425,32 @@ public class GraphicsEnvironment {
    /**
     * Pull ANGLE whitelist from GlobalSettings and compare against current package
     */
    private boolean checkAngleWhitelist(Bundle bundle, String packageName) {
    private static boolean checkAngleWhitelist(Context context, Bundle bundle, String packageName) {
        final ContentResolver contentResolver = context.getContentResolver();
        final List<String> angleWhitelist =
                getGlobalSettingsString(bundle, Settings.Global.GLOBAL_SETTINGS_ANGLE_WHITELIST);
                getGlobalSettingsString(contentResolver, bundle,
                    Settings.Global.GLOBAL_SETTINGS_ANGLE_WHITELIST);

        return angleWhitelist.contains(packageName);
    }

    /**
     * Pass ANGLE details down to trigger enable logic
     *
     * @param context
     * @param bundle
     * @param packageName
     * @return true: ANGLE setup successfully
     *         false: ANGLE not setup (not on whitelist, ANGLE not present, etc.)
     */
    public void setupAngle(Context context, Bundle bundle, PackageManager pm, String packageName) {
    public boolean setupAngle(Context context, Bundle bundle, PackageManager pm,
            String packageName) {
        if (packageName.isEmpty()) {
            Log.v(TAG, "No package name available yet, skipping ANGLE setup");
            return;
            return false;
        }

        final String devOptIn = getDriverForPkg(bundle, packageName);
        final String devOptIn = getDriverForPkg(context, bundle, packageName);
        if (DEBUG) {
            Log.v(TAG, "ANGLE Developer option for '" + packageName + "' "
                    + "set to: '" + devOptIn + "'");
@@ -439,11 +468,11 @@ public class GraphicsEnvironment {
        // load a driver, GraphicsEnv::shouldUseAngle() has seen the package name before
        // and can confidently answer yes/no based on the previously set developer
        // option value.
        final boolean whitelisted = checkAngleWhitelist(bundle, packageName);
        final boolean whitelisted = checkAngleWhitelist(context, bundle, packageName);
        final boolean defaulted = devOptIn.equals(sDriverMap.get(OpenGlDriverChoice.DEFAULT));
        final boolean rulesCheck = (whitelisted || !defaulted);
        if (!rulesCheck) {
            return;
            return false;
        }

        if (whitelisted) {
@@ -456,7 +485,7 @@ public class GraphicsEnvironment {
        final String anglePkgName = getAnglePackageName(pm);
        if (anglePkgName.isEmpty()) {
            Log.e(TAG, "Failed to find ANGLE package.");
            return;
            return false;
        }

        final ApplicationInfo angleInfo;
@@ -464,7 +493,7 @@ public class GraphicsEnvironment {
            angleInfo = pm.getApplicationInfo(anglePkgName, PackageManager.MATCH_SYSTEM_ONLY);
        } catch (PackageManager.NameNotFoundException e) {
            Log.w(TAG, "ANGLE package '" + anglePkgName + "' not installed");
            return;
            return false;
        }

        final String abi = chooseAbi(angleInfo);
@@ -480,12 +509,62 @@ public class GraphicsEnvironment {

        if (setupAngleWithTempRulesFile(context, packageName, paths, devOptIn)) {
            // We setup ANGLE with a temp rules file, so we're done here.
            return;
            return true;
        }

        if (setupAngleRulesApk(anglePkgName, angleInfo, pm, packageName, paths, devOptIn)) {
            // We setup ANGLE with rules from the APK, so we're done here.
            return;
            return true;
        }

        return false;
    }

    /**
     * Determine if the "ANGLE In Use" dialog box should be shown.
     */
    private boolean shouldShowAngleInUseDialogBox(Context context) {
        try {
            ContentResolver contentResolver = context.getContentResolver();
            final int showDialogBox = Settings.Global.getInt(contentResolver,
                    Settings.Global.GLOBAL_SETTINGS_SHOW_ANGLE_IN_USE_DIALOG_BOX);

            return (showDialogBox == 1);
        } catch (Settings.SettingNotFoundException | SecurityException e) {
            // Do nothing and move on
        }

        // No setting, so assume false
        return false;
    }

    /**
     * Determine if ANGLE should be used.
     */
    private boolean shouldUseAngle(Context context, String packageName) {
        // Need to make sure we are evaluating ANGLE usage for the correct circumstances
        if (!setupAngle(context, null, context.getPackageManager(), packageName)) {
            Log.v(TAG, "Package '" + packageName + "' should use not ANGLE");
            return false;
        }

        final boolean useAngle = getShouldUseAngle(packageName);
        Log.v(TAG, "Package '" + packageName + "' should use ANGLE = '" + useAngle + "'");

        return useAngle;
    }

    /**
     * Show the ANGLE in Use Dialog Box
     * @param context
     */
    public void showAngleInUseDialogBox(Context context) {
        final String packageName = context.getPackageName();

        if (shouldShowAngleInUseDialogBox(context) && shouldUseAngle(context, packageName)) {
            final String toastMsg = packageName + " is using ANGLE";
            final Toast toast = Toast.makeText(context, toastMsg, Toast.LENGTH_LONG);
            toast.show();
        }
    }

@@ -541,19 +620,19 @@ public class GraphicsEnvironment {

        if (gameDriverAllApps != 1) {
            // GAME_DRIVER_OPT_OUT_APPS has higher priority than GAME_DRIVER_OPT_IN_APPS
            if (getGlobalSettingsString(coreSettings, Settings.Global.GAME_DRIVER_OPT_OUT_APPS)
                            .contains(packageName)) {
            if (getGlobalSettingsString(null, coreSettings,
                    Settings.Global.GAME_DRIVER_OPT_OUT_APPS).contains(packageName)) {
                if (DEBUG) {
                    Log.w(TAG, packageName + " opts out from Game Driver.");
                }
                return false;
            }
            final boolean isOptIn =
                    getGlobalSettingsString(coreSettings, Settings.Global.GAME_DRIVER_OPT_IN_APPS)
                            .contains(packageName);
                    getGlobalSettingsString(null, coreSettings,
                            Settings.Global.GAME_DRIVER_OPT_IN_APPS).contains(packageName);
            if (!isOptIn
                    && !getGlobalSettingsString(coreSettings, Settings.Global.GAME_DRIVER_WHITELIST)
                                .contains(packageName)) {
                    && !getGlobalSettingsString(null, coreSettings,
                    Settings.Global.GAME_DRIVER_WHITELIST).contains(packageName)) {
                if (DEBUG) {
                    Log.w(TAG, packageName + " is not on the whitelist.");
                }
@@ -660,4 +739,5 @@ public class GraphicsEnvironment {
            long driverVersionCode, String appPackageName);
    private static native void setAngleInfo(String path, String appPackage, String devOptIn,
            FileDescriptor rulesFd, long rulesOffset, long rulesLength);
    private static native boolean getShouldUseAngle(String packageName);
}
+8 −0
Original line number Diff line number Diff line
@@ -12317,6 +12317,14 @@ public final class Settings {
        public static final String GLOBAL_SETTINGS_ANGLE_WHITELIST =
                "angle_whitelist";
        /**
         * Show the "ANGLE In Use" dialog box to the user when ANGLE is the OpenGL driver.
         * The value is a boolean (1 or 0).
         * @hide
         */
        public static final String GLOBAL_SETTINGS_SHOW_ANGLE_IN_USE_DIALOG_BOX =
                "show_angle_in_use_dialog_box";
        /**
         * Game Driver global preference for all Apps.
         * 0 = Default
+6 −0
Original line number Diff line number Diff line
@@ -55,6 +55,11 @@ void setAngleInfo_native(JNIEnv* env, jobject clazz, jstring path, jstring appNa
            devOptInChars.c_str(), rulesFd_native, rulesOffset, rulesLength);
}

bool shouldUseAngle_native(JNIEnv* env, jobject clazz, jstring appName) {
    ScopedUtfChars appNameChars(env, appName);
    return android::GraphicsEnv::getInstance().shouldUseAngle(appNameChars.c_str());
}

void setLayerPaths_native(JNIEnv* env, jobject clazz, jobject classLoader, jstring layerPaths) {
    android::NativeLoaderNamespace* appNamespace = android::FindNativeLoaderNamespaceByClassLoader(
        env, classLoader);
@@ -81,6 +86,7 @@ const JNINativeMethod g_methods[] = {
    { "setDriverPath", "(Ljava/lang/String;)V", reinterpret_cast<void*>(setDriverPath) },
    { "setGpuStats", "(Ljava/lang/String;Ljava/lang/String;JLjava/lang/String;)V", reinterpret_cast<void*>(setGpuStats_native) },
    { "setAngleInfo", "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/io/FileDescriptor;JJ)V", reinterpret_cast<void*>(setAngleInfo_native) },
    { "getShouldUseAngle", "(Ljava/lang/String;)Z", reinterpret_cast<void*>(shouldUseAngle_native) },
    { "setLayerPaths", "(Ljava/lang/ClassLoader;Ljava/lang/String;)V", reinterpret_cast<void*>(setLayerPaths_native) },
    { "setDebugLayers", "(Ljava/lang/String;)V", reinterpret_cast<void*>(setDebugLayers_native) },
    { "setDebugLayersGLES", "(Ljava/lang/String;)V", reinterpret_cast<void*>(setDebugLayersGLES_native) },
+2 −0
Original line number Diff line number Diff line
@@ -451,6 +451,8 @@ message GlobalSettingsProto {
        // Game Driver - List of blacklists, each blacklist is a blacklist for
        // a specific Game Driver version
        optional SettingProto game_driver_blacklists = 14;
        // ANGLE - Show a dialog box when ANGLE is selected for the currently running PKG
        optional SettingProto show_angle_in_use_dialog = 15;
    }
    optional Gpu gpu = 59;

Loading