Enhance ANGLE for Android Developer Options

Update ANGLE Developer Options

Update ANGLE developer options to allow selecting the OpenGL driver
(default, ANGLE, native) for each app as well as forcing ANGLE for all
apps.

Bug: angleproject:2962
Test: Verify the default/ANGLE/native values are saved and applied and
used by the loader.

Change-Id: I6737b11bc061318cf8438c8161593ca70239590f
Reviewed-on: https://chromium-review.googlesource.com/c/1354101
Reviewed-by: Yuly Novikov <ynovikov@chromium.org>
Reviewed-by: Geoff Lang <geofflang@chromium.org>
Commit-Queue: Tim Van Patten <timvp@google.com>
This commit is contained in:
Tim Van Patten
2018-11-01 17:47:10 -06:00
committed by Commit Bot
parent eae081c668
commit fdccaa3acb
20 changed files with 852 additions and 25 deletions

1
.gitignore vendored
View File

@@ -60,3 +60,4 @@ Release_Win32/
Release_x64/
TestResults.qpa
tools/clang
.idea/

View File

@@ -1,21 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
Copyright 2018 The Chromium Authors. All rights reserved. Use of this
source code is governed by a BSD-style license that can be found in the
LICENSE file.
-->
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
package="{{manifest_package|default('com.android.angle')}}">
<uses-sdk android:minSdkVersion="26"
android:targetSdkVersion="28">
</uses-sdk>
<application android:label="Android System Angle"
android:icon="@{{manifest_package|default('com.android.angle')}}:drawable/icon"
android:extractNativeLibs="false"
android:multiArch="true"
android:hasCode="false">
</application>
</manifest>

View File

@@ -50,8 +50,8 @@ angle_git_is_present = exec_script("src/commit_id.py",
angle_use_commit_id = angle_git_is_present == 1
import("src/libGLESv2.gni")
import("src/compiler.gni")
import("src/libGLESv2.gni")
# This config is exported to dependent targets (and also applied to internal
# ones).

View File

@@ -0,0 +1,47 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
Copyright 2018 The ANGLE Project Authors. All rights reserved. Use of this
source code is governed by a BSD-style license that can be found in the
LICENSE file.
-->
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
package="{{manifest_package|default('com.android.angle')}}">
<uses-permission android:name="android.permission.WRITE_SECURE_SETTINGS" />
<uses-sdk android:minSdkVersion="26"
android:targetSdkVersion="28">
</uses-sdk>
<application android:label="Android System Angle"
android:icon="@{{manifest_package|default('com.android.angle')}}:drawable/icon"
android:extractNativeLibs="false"
android:multiArch="true">
<activity android:name=".MainActivity"
android:label="@string/angle_preferences"
android:description="@string/angle_preferences_summary"
android:theme="@style/Theme.Settings"
android:launchMode="singleTask">
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.INFO"/>
</intent-filter>
<intent-filter>
<action android:name="android.service.quicksettings.action.QS_TILE_PREFERENCES" />
</intent-filter>
<!-- Mark this fragment as a dynamic setting in the development category. -->
<intent-filter>
<action android:name="com.android.settings.action.IA_SETTINGS" />
</intent-filter>
<meta-data android:name="com.android.settings.category"
android:value="com.android.settings.category.ia.development" />
<meta-data android:name="com.android.settings.summary" android:resource="@string/angle_preferences_summary" />
<meta-data android:name="com.android.settings.order" android:value="100" />
<meta-data android:name="com.android.settings.profile" android:value="primary_profile_only" />
</activity>
</application>
</manifest>

6
android/OWNERS Normal file
View File

@@ -0,0 +1,6 @@
alanward@google.com
cnorthrop@google.com
courtneygo@google.com
ianelliott@google.com
timvp@google.com
tobine@google.com

View File

@@ -7,17 +7,22 @@ import("//third_party/angle/gni/angle.gni")
template("angle_apk") {
manifest_target_name = "${target_name}__manifest"
manifest_path = "${target_gen_dir}/${target_name}/AndroidManifest.xml"
manifest_path = "${target_gen_dir}/${target_name}/android/AndroidManifest.xml"
jinja_template(manifest_target_name) {
input = "//third_party/angle/AndroidManifest.xml.jinja2"
input = "//third_party/angle/android/AndroidManifest.xml.jinja2"
output = manifest_path
variables = [ "manifest_package=${invoker.package_name}" ]
}
android_resources("${invoker.package_name}_resources") {
resource_dirs = [ "android/res" ]
custom_package = "${invoker.package_name}"
custom_package = "com.android.angle.common"
deps = [
"//third_party/android_deps:android_support_v14_preference_java",
"//third_party/android_deps:android_support_v7_preference_java",
]
}
android_assets("${invoker.package_name}_assets") {
@@ -34,6 +39,9 @@ template("angle_apk") {
deps = [
":${invoker.package_name}_assets",
":${invoker.package_name}_resources",
"//base:base_java",
"//third_party/android_deps:android_support_v14_preference_java",
"//third_party/android_deps:android_support_v7_preference_java",
]
uncompress_shared_libraries = true
@@ -54,5 +62,18 @@ template("angle_apk") {
"//third_party/angle:libGLESv2${angle_libs_suffix}",
"//third_party/angle:libfeature_support${angle_libs_suffix}",
]
# Common files required by all builds
java_files = [
"android/src/com/android/angle/common/GlobalSettings.java",
"android/src/com/android/angle/common/MainFragment.java",
"android/src/com/android/angle/common/Receiver.java",
]
if (target_name == "aosp_apk") {
java_files += [ "android/src/com/android/angle/MainActivity.java" ]
} else if (target_name == "google_apk") {
java_files += [ "android/src/com/google/android/angle/MainActivity.java" ]
}
}
}

View File

@@ -0,0 +1,18 @@
<?xml version="1.0" encoding="utf-8" ?>
<!--
Copyright 2018 The ANGLE Project Authors. All rights reserved. Use of this
source code is governed by a BSD-style license that can be found in the
LICENSE file.
-->
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_height="wrap_content"
android:layout_width="match_parent"
android:orientation="vertical">
<fragment android:name="com.android.angle.common.MainFragment"
android:id="@+id/fragment"
android:layout_height="wrap_content"
android:layout_width="match_parent"/>
</LinearLayout>

View File

@@ -0,0 +1,34 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
Copyright 2018 The ANGLE Project Authors. All rights reserved. Use of this
source code is governed by a BSD-style license that can be found in the
LICENSE file.
-->
<resources xmlns:android="http://schemas.android.com/apk/res/android">
<style name="PreferenceFragmentListSinglePane" parent="@*android:style/PreferenceFragmentList">
<item name="android:paddingStart">@dimen/settings_side_margin</item>
<item name="android:paddingEnd">@dimen/settings_side_margin</item>
<item name="android:layout_marginStart">0dp</item>
<item name="android:layout_marginEnd">0dp</item>
<item name="android:scrollbarStyle">outsideOverlay</item>
</style>
<style name="MultiSelectDialogStyle" parent="@style/Preference.Material">
<item name="negativeButtonText">@android:string/cancel</item>
<item name="positiveButtonText">@android:string/ok</item>
</style>
<style name="SettingsPreferenceFragmentStyle" parent="@style/PreferenceFragment.Material">
<item name="android:layout">@layout/preference_list_fragment</item>
</style>
<style name="PreferenceTheme" parent="@style/PreferenceThemeOverlay.v14.Material">
<item name="preferenceFragmentStyle">@style/SettingsPreferenceFragmentStyle</item>
<item name="dialogPreferenceStyle">@style/MultiSelectDialogStyle</item>
</style>
<style name="Theme.Settings" parent="@android:style/Theme.DeviceDefault.Settings" >
<item name="preferenceTheme">@style/PreferenceTheme</item>
</style>
</resources>

View File

@@ -0,0 +1,10 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
Copyright 2018 The ANGLE Project Authors. All rights reserved. Use of this
source code is governed by a BSD-style license that can be found in the
LICENSE file.
-->
<resources>
<dimen name="settings_side_margin">0dip</dimen>
</resources>

View File

@@ -0,0 +1,18 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
Copyright 2018 The ANGLE Project Authors. All rights reserved. Use of this
source code is governed by a BSD-style license that can be found in the
LICENSE file.
-->
<resources>
<string name="default_driver">default</string>
<string-array name="driver_values">
<item>@string/default_driver</item>
<item>angle</item>
<item>native</item>
</string-array>
</resources>

View File

@@ -0,0 +1,12 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
Copyright 2018 The ANGLE Project Authors. All rights reserved. Use of this
source code is governed by a BSD-style license that can be found in the
LICENSE file.
-->
<resources>
<string name="global_settings_driver_all_angle">angle_gl_driver_all_angle</string>
<string name="global_settings_driver_selection_pkgs">angle_gl_driver_selection_pkgs</string>
<string name="global_settings_driver_selection_values">angle_gl_driver_selection_values</string>
</resources>

View File

@@ -0,0 +1,13 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
Copyright 2018 The ANGLE Project Authors. All rights reserved. Use of this
source code is governed by a BSD-style license that can be found in the
LICENSE file.
-->
<resources>
<string name="pref_key_angle_flags_category">angle_flags_category</string>
<string name="pref_key_all_angle">all_pkgs_use_angle</string>
<string name="pref_key_select_opengl_driver_category">select_opengl_driver_category</string>
<string name="pref_key_installed_pkgs">installed_pkgs</string>
</resources>

View File

@@ -0,0 +1,31 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
Copyright 2018 The ANGLE Project Authors. All rights reserved. Use of this
source code is governed by a BSD-style license that can be found in the
LICENSE file.
-->
<resources>
<!-- This is the user visible name of the app and title. -->
<string name="angle_preferences">ANGLE Preferences</string>
<!-- This string is a description of what "ANGLE Preferences" is.
It is used as a subtitle or summary text to describe this ANGLE app. -->
<string name="angle_preferences_summary">Modify ANGLE settings</string>
<!-- Category title listing ANGLE flags [CHAR_LIMIT=50]-->
<string name="angle_general_title">General</string>
<!-- This is the label for a toggle button.
When the toggle is enabled, we will use ANGLE for all PKGs, regardless of any other settings.
This is also used as a Quick Settings tile label. -->
<string name="rules_file">Use ANGLE for all apps</string>
<!-- ListPreference title listing installed packages [CHAR_LIMIT=50]-->
<string name="select_opengl_driver_title">Select OpenGL Driver</string>
<!-- These are keywords that the user can use to search for this app.
'angle' should not be translated, as it is an app name. -->
<string name="keywords">angle, opengl, graphics</string>
</resources>

32
android/res/xml/main.xml Normal file
View File

@@ -0,0 +1,32 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
Copyright 2018 The ANGLE Project Authors. All rights reserved. Use of this
source code is governed by a BSD-style license that can be found in the
LICENSE file.
-->
<android.support.v7.preference.PreferenceScreen
xmlns:android="http://schemas.android.com/apk/res/android">
<PreferenceCategory
android:key="@string/pref_key_angle_flags_category"
android:title="@string/angle_general_title">
<!--TODO : Issue 2989 : boulder-graphics-team@google.com
Enable the switch once Android can boot with ANGLE enabled for everything-->
<android.support.v14.preference.SwitchPreference
android:key="@string/pref_key_all_angle"
android:title="@string/rules_file"
android:summary="@string/global_settings_driver_all_angle"
android:defaultValue="false"
android:enabled="false"/>
</PreferenceCategory>
<PreferenceCategory
android:key="@string/pref_key_select_opengl_driver_category"
android:title="@string/select_opengl_driver_title">
</PreferenceCategory>
</android.support.v7.preference.PreferenceScreen>

View File

@@ -0,0 +1,24 @@
/*
* Copyright 2018 The ANGLE Project Authors. All rights reserved.
*
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
package com.android.angle;
import android.app.Activity;
import android.os.Bundle;
import com.android.angle.common.*;
public class MainActivity extends Activity
{
private final String TAG = this.getClass().getSimpleName();
@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.fragment);
}
}

View File

@@ -0,0 +1,242 @@
/*
* Copyright 2018 The ANGLE Project Authors. All rights reserved.
*
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
package com.android.angle.common;
import android.content.ContentResolver;
import android.content.Context;
import android.content.pm.PackageInfo;
import android.provider.Settings;
import android.util.Log;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
class GlobalSettings
{
private final String TAG = this.getClass().getSimpleName();
private Context mContext;
private List<PackageInfo> mInstalledPkgs = new ArrayList<>();
private List<String> mGlobalSettingsDriverPkgs = new ArrayList<>();
private List<String> mGlobalSettingsDriverValues = new ArrayList<>();
GlobalSettings(Context context, List<PackageInfo> installedPkgs)
{
mContext = context;
setInstalledPkgs(installedPkgs);
}
Boolean getAllUseAngle()
{
ContentResolver contentResolver = mContext.getContentResolver();
try
{
int allUseAngle = Settings.Global.getInt(
contentResolver, mContext.getString(R.string.global_settings_driver_all_angle));
return (allUseAngle == 1);
}
catch (Settings.SettingNotFoundException e)
{
return false;
}
}
static void updateAllUseAngle(Context context, Boolean allUseAngle)
{
ContentResolver contentResolver = context.getContentResolver();
Settings.Global.putInt(contentResolver,
context.getString(R.string.global_settings_driver_all_angle), allUseAngle ? 1 : 0);
}
void updatePkg(String pkgName, String driver)
{
int pkgIndex = getGlobalSettingsPkgIndex(pkgName);
if (!isValidDiverValue(driver))
{
Log.e(TAG, "Attempting to update a PKG with an invalid driver: '" + driver + "'");
return;
}
String defaultDriver = mContext.getString(R.string.default_driver);
if (driver.equals(defaultDriver))
{
if (pkgIndex >= 0)
{
// We only store global settings for driver values other than the default
mGlobalSettingsDriverPkgs.remove(pkgIndex);
mGlobalSettingsDriverValues.remove(pkgIndex);
}
}
else
{
if (pkgIndex >= 0)
{
mGlobalSettingsDriverValues.set(pkgIndex, driver);
}
else
{
mGlobalSettingsDriverPkgs.add(pkgName);
mGlobalSettingsDriverValues.add(driver);
}
}
writeGlobalSettings();
}
String getDriverForPkg(String pkgName)
{
int pkgIndex = getGlobalSettingsPkgIndex(pkgName);
if (pkgIndex >= 0)
{
return mGlobalSettingsDriverValues.get(pkgIndex);
}
return null;
}
private void setInstalledPkgs(List<PackageInfo> installedPkgs)
{
mInstalledPkgs = installedPkgs;
updateGlobalSettings();
}
private void updateGlobalSettings()
{
readGlobalSettings();
validateGlobalSettings();
writeGlobalSettings();
}
private void readGlobalSettings()
{
mGlobalSettingsDriverPkgs = getGlobalSettingsString(
mContext.getString(R.string.global_settings_driver_selection_pkgs));
mGlobalSettingsDriverValues = getGlobalSettingsString(
mContext.getString(R.string.global_settings_driver_selection_values));
}
private List<String> getGlobalSettingsString(String globalSetting)
{
List<String> valueList;
ContentResolver contentResolver = mContext.getContentResolver();
String settingsValue = Settings.Global.getString(contentResolver, globalSetting);
if (settingsValue != null)
{
valueList = new ArrayList<>(Arrays.asList(settingsValue.split(",")));
}
else
{
valueList = new ArrayList<>();
}
return valueList;
}
private void writeGlobalSettings()
{
String driverPkgs = String.join(",", mGlobalSettingsDriverPkgs);
String driverValues = String.join(",", mGlobalSettingsDriverValues);
ContentResolver contentResolver = mContext.getContentResolver();
Settings.Global.putString(contentResolver,
mContext.getString(R.string.global_settings_driver_selection_pkgs), driverPkgs);
Settings.Global.putString(contentResolver,
mContext.getString(R.string.global_settings_driver_selection_values), driverValues);
}
private void validateGlobalSettings()
{
// Verify lengths
if (mGlobalSettingsDriverPkgs.size() != mGlobalSettingsDriverValues.size())
{
// The lengths don't match, so clear the values out and rebuild later.
mGlobalSettingsDriverPkgs.clear();
mGlobalSettingsDriverValues.clear();
return;
}
String defaultDriver = mContext.getString(R.string.default_driver);
// Use a temp list, since we're potentially modifying the original list.
List<String> globalSettingsDriverPkgs = new ArrayList<>(mGlobalSettingsDriverPkgs);
for (String pkgName : globalSettingsDriverPkgs)
{
// Remove any uninstalled packages.
if (!isPkgInstalled(pkgName))
{
removePkgFromGlobalSettings(pkgName);
}
// Remove any packages with invalid driver values
else if (!isValidDiverValue(getDriverForPkg(pkgName)))
{
removePkgFromGlobalSettings(pkgName);
}
// Remove any packages with the 'default' driver selected
else if (defaultDriver.equals(getDriverForPkg(pkgName)))
{
removePkgFromGlobalSettings(pkgName);
}
}
}
private void removePkgFromGlobalSettings(String pkgName)
{
int pkgIndex = getGlobalSettingsPkgIndex(pkgName);
mGlobalSettingsDriverPkgs.remove(pkgIndex);
mGlobalSettingsDriverValues.remove(pkgIndex);
}
private int getGlobalSettingsPkgIndex(String pkgName)
{
for (int pkgIndex = 0; pkgIndex < mGlobalSettingsDriverPkgs.size(); pkgIndex++)
{
if (mGlobalSettingsDriverPkgs.get(pkgIndex).equals(pkgName))
{
return pkgIndex;
}
}
return -1;
}
private Boolean isPkgInstalled(String pkgName)
{
for (PackageInfo pkg : mInstalledPkgs)
{
if (pkg.packageName.equals(pkgName))
{
return true;
}
}
return false;
}
private Boolean isValidDiverValue(String driverValue)
{
CharSequence[] drivers = mContext.getResources().getStringArray(R.array.driver_values);
for (CharSequence driver : drivers)
{
if (driverValue.equals(driver.toString()))
{
return true;
}
}
return false;
}
}

View File

@@ -0,0 +1,274 @@
/*
* Copyright 2018 The ANGLE Project Authors. All rights reserved.
*
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
package com.android.angle.common;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.SharedPreferences;
import android.content.SharedPreferences.OnSharedPreferenceChangeListener;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageInfo;
import android.os.Bundle;
import android.os.Process;
import android.support.v14.preference.PreferenceFragment;
import android.support.v14.preference.SwitchPreference;
import android.support.v7.preference.ListPreference;
import android.support.v7.preference.Preference;
import android.support.v7.preference.PreferenceCategory;
import android.support.v7.preference.PreferenceManager;
import android.util.Log;
import java.text.Collator;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
public class MainFragment extends PreferenceFragment implements OnSharedPreferenceChangeListener
{
private final String TAG = this.getClass().getSimpleName();
private static final String ACTION_REFRESH_PKGS = "com.google.android.angle.REFRESH_PKGS";
private SharedPreferences mPrefs;
private GlobalSettings mGlobalSettings;
private Receiver mRefreshReceiver;
private SwitchPreference mAllAngleSwitchPref;
private List<PackageInfo> mInstalledPkgs = new ArrayList<>();
private List<ListPreference> mDriverListPrefs = new ArrayList<>();
SharedPreferences.OnSharedPreferenceChangeListener listener =
new SharedPreferences.OnSharedPreferenceChangeListener() {
public void onSharedPreferenceChanged(SharedPreferences prefs, String key)
{
// Nothing to do yet
}
};
@Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
getInstalledPkgsList();
mPrefs = PreferenceManager.getDefaultSharedPreferences(
getActivity().getApplicationContext());
validatePreferences();
mGlobalSettings = new GlobalSettings(getContext(), mInstalledPkgs);
mergeGlobalSettings();
mRefreshReceiver = new Receiver() {
@Override
public void onReceive(Context context, Intent intent)
{
getInstalledPkgsList();
}
};
String allUseAngleKey = getContext().getString(R.string.pref_key_all_angle);
Boolean allUseAngle = mPrefs.getBoolean(allUseAngleKey, false);
mAllAngleSwitchPref = (SwitchPreference) findPreference(allUseAngleKey);
mAllAngleSwitchPref.setChecked(mGlobalSettings.getAllUseAngle());
mAllAngleSwitchPref.setOnPreferenceClickListener(
new Preference.OnPreferenceClickListener() {
@Override
public boolean onPreferenceClick(Preference preference)
{
Receiver.updateAllUseAngle(getContext());
return true;
}
});
String selectDriverCatKey =
getContext().getString(R.string.pref_key_select_opengl_driver_category);
PreferenceCategory installedPkgsCat =
(PreferenceCategory) findPreference(selectDriverCatKey);
getInstalledPkgsList();
mDriverListPrefs.clear();
for (PackageInfo packageInfo : mInstalledPkgs)
{
ListPreference listPreference = new ListPreference(getActivity());
initListPreference(packageInfo, listPreference);
installedPkgsCat.addPreference(listPreference);
}
}
@Override
public void onResume()
{
super.onResume();
getActivity().registerReceiver(mRefreshReceiver, new IntentFilter(ACTION_REFRESH_PKGS));
getPreferenceScreen().getSharedPreferences().registerOnSharedPreferenceChangeListener(
listener);
}
@Override
public void onPause()
{
getActivity().unregisterReceiver(mRefreshReceiver);
getPreferenceScreen().getSharedPreferences().unregisterOnSharedPreferenceChangeListener(
listener);
super.onPause();
}
@Override
public void onCreatePreferences(Bundle savedInstanceState, String rootKey)
{
addPreferencesFromResource(R.xml.main);
}
@Override
public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key)
{
Log.v(TAG, "Shared preference changed: key = '" + key + "'");
}
private void validatePreferences()
{
Map<String, ?> allPrefs = mPrefs.getAll();
// Remove Preference values for any uninstalled PKGs
for (String key : allPrefs.keySet())
{
// Remove any uninstalled PKGs
PackageInfo packageInfo = getPackageInfoForPackageName(key);
if (packageInfo != null)
{
removePkgPreference(key);
}
}
}
private void getInstalledPkgsList()
{
List<PackageInfo> pkgs = getActivity().getPackageManager().getInstalledPackages(0);
mInstalledPkgs.clear();
for (PackageInfo packageInfo : pkgs)
{
if (packageInfo.applicationInfo.uid == Process.SYSTEM_UID)
{
continue;
}
// Filter out apps that are system apps
if ((packageInfo.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0)
{
continue;
}
mInstalledPkgs.add(packageInfo);
}
Collections.sort(mInstalledPkgs, displayNameComparator);
}
private final Comparator<PackageInfo> displayNameComparator = new Comparator<PackageInfo>() {
public final int compare(PackageInfo a, PackageInfo b)
{
return collator.compare(getAppName(a), getAppName(b));
}
private final Collator collator = Collator.getInstance();
};
private String getAppName(PackageInfo packageInfo)
{
return packageInfo.applicationInfo.loadLabel(getActivity().getPackageManager()).toString();
}
private void initListPreference(PackageInfo packageInfo, ListPreference listPreference)
{
CharSequence[] drivers = getResources().getStringArray(R.array.driver_values);
listPreference.setEntryValues(drivers);
listPreference.setEntries(drivers);
String defaultDriver = getContext().getString(R.string.default_driver);
listPreference.setDefaultValue(defaultDriver);
String dialogTitleKey = getContext().getString(R.string.select_opengl_driver_title);
listPreference.setDialogTitle(dialogTitleKey);
listPreference.setKey(packageInfo.packageName);
listPreference.setTitle(getAppName(packageInfo));
listPreference.setSummary(mPrefs.getString(packageInfo.packageName, defaultDriver));
listPreference.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() {
@Override
public boolean onPreferenceChange(Preference preference, Object newValue)
{
ListPreference listPreference = (ListPreference) preference;
listPreference.setSummary(newValue.toString());
mGlobalSettings.updatePkg(preference.getKey(), newValue.toString());
return true;
}
});
mDriverListPrefs.add(listPreference);
}
private void removePkgPreference(String key)
{
SharedPreferences.Editor editor = mPrefs.edit();
editor.remove(key);
editor.apply();
for (ListPreference listPreference : mDriverListPrefs)
{
if (listPreference.getKey().equals(key))
{
mDriverListPrefs.remove(listPreference);
}
}
}
private PackageInfo getPackageInfoForPackageName(String pkgName)
{
PackageInfo foundPackageInfo = null;
for (PackageInfo packageInfo : mInstalledPkgs)
{
if (pkgName.equals(getAppName(packageInfo)))
{
foundPackageInfo = packageInfo;
break;
}
}
return foundPackageInfo;
}
private void mergeGlobalSettings()
{
SharedPreferences.Editor editor = mPrefs.edit();
for (PackageInfo packageInfo : mInstalledPkgs)
{
String driver = mGlobalSettings.getDriverForPkg(packageInfo.packageName);
if (driver != null)
{
editor.putString(packageInfo.packageName, driver);
}
}
editor.apply();
}
}

View File

@@ -0,0 +1,37 @@
/*
* Copyright 2018 The ANGLE Project Authors. All rights reserved.
*
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
package com.android.angle.common;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.preference.PreferenceManager;
import android.util.Log;
public class Receiver extends BroadcastReceiver
{
private final static String TAG = Receiver.class.getSimpleName();
@Override
public void onReceive(Context context, Intent intent)
{
// Nothing to do yet...
}
static void updateAllUseAngle(Context context)
{
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
String allUseAngleKey = context.getString(R.string.pref_key_all_angle);
boolean allUseAngle = prefs.getBoolean(allUseAngleKey, false);
GlobalSettings.updateAllUseAngle(context, allUseAngle);
Log.v(TAG, "Use Rules File set to: " + allUseAngle);
}
}

View File

@@ -0,0 +1,25 @@
/*
* Copyright 2018 The ANGLE Project Authors. All rights reserved.
*
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
package com.google.android.angle;
import android.app.Activity;
import android.os.Bundle;
import android.support.v7.preference.PreferenceManager;
import com.android.angle.common.*;
public class MainActivity extends Activity
{
private final String TAG = this.getClass().getSimpleName();
@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.fragment);
}
}

View File

@@ -8,6 +8,9 @@
"Rule":"Supported application(s) (e.g. Maps on Google devices)",
"UseANGLE":true,
"Applications":[
{
"AppName":"com.android.angle"
},
{
"AppName":"com.google.android.apps.internal.cubey"
},