зеркало из https://github.com/AvaloniaUI/angle.git
Create Container ANGLE APK
The ANGLE APK needs to be reverted back to just being a container for the ANGLE shared object libraries, since the rest of the APK contents are in the Android source tree. Bug: angleproject:3154 Test: 'adb sync' the APK on to a device Change-Id: Id245f1e3d269c71054d9759e8ba8be0532afe659 Reviewed-on: https://chromium-review.googlesource.com/c/1474341 Commit-Queue: Tim Van Patten <timvp@google.com> Reviewed-by: Courtney Goeltzenleuchter <courtneygo@google.com>
This commit is contained in:
Родитель
1d35d511f5
Коммит
e82c857d38
8
BUILD.gn
8
BUILD.gn
|
@ -1111,18 +1111,12 @@ if (!is_component_build && is_android &&
|
|||
# Package ANGLE libraries for pre-installed system image
|
||||
angle_apk("aosp_apk") {
|
||||
package_name = "com.android.angle"
|
||||
apk_name = "AngleAosp"
|
||||
}
|
||||
|
||||
angle_apk("google_apk") {
|
||||
package_name = "com.google.android.angle"
|
||||
apk_name = "ANGLEPrebuilt"
|
||||
apk_name = "AngleLibraries"
|
||||
}
|
||||
|
||||
group("angle_apks") {
|
||||
deps = [
|
||||
":aosp_apk",
|
||||
":google_apk",
|
||||
]
|
||||
}
|
||||
|
||||
|
|
|
@ -9,9 +9,6 @@
|
|||
xmlns:tools="http://schemas.android.com/tools"
|
||||
package="{{manifest_package|default('com.android.angle')}}">
|
||||
|
||||
<uses-permission android:name="android.permission.WRITE_SECURE_SETTINGS" />
|
||||
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
|
||||
|
||||
<uses-sdk android:minSdkVersion="26"
|
||||
android:targetSdkVersion="28">
|
||||
</uses-sdk>
|
||||
|
@ -21,11 +18,7 @@
|
|||
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">
|
||||
<activity android:name=".MainActivity">
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.MAIN"/>
|
||||
<category android:name="android.intent.category.INFO"/>
|
||||
|
@ -36,29 +29,7 @@
|
|||
<action android:name="android.app.action.ANGLE_FOR_ANDROID" />
|
||||
<category android:name="android.intent.category.DEFAULT" />
|
||||
</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>
|
||||
|
||||
<receiver android:name="com.android.angle.common.Receiver"
|
||||
android:directBootAware="true">
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.LOCKED_BOOT_COMPLETED" />
|
||||
<action android:name="android.intent.action.MY_PACKAGE_REPLACED" />
|
||||
</intent-filter>
|
||||
</receiver>
|
||||
|
||||
</application>
|
||||
</manifest>
|
||||
|
|
|
@ -32,12 +32,7 @@ template("angle_apk") {
|
|||
|
||||
android_resources("${invoker.package_name}_resources") {
|
||||
resource_dirs = [ "android/res" ]
|
||||
|
||||
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",
|
||||
]
|
||||
custom_package = "${invoker.package_name}"
|
||||
}
|
||||
|
||||
android_assets("${invoker.package_name}_assets") {
|
||||
|
@ -54,9 +49,6 @@ 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",
|
||||
]
|
||||
if (symbol_level != 0) {
|
||||
deps += [ ":compressed_symbols" ]
|
||||
|
@ -77,9 +69,10 @@ template("angle_apk") {
|
|||
}
|
||||
if (angle_enable_vulkan_validation_layers) {
|
||||
foreach(_layer, vulkan_validation_layers) {
|
||||
secondary_abi_shared_libraries +=
|
||||
[ "${angle_root}/third_party/vulkan-validation-layers:${_layer}" +
|
||||
"($android_secondary_abi_toolchain)" ]
|
||||
secondary_abi_shared_libraries += [
|
||||
"${angle_root}/third_party/vulkan-validation-layers:${_layer}" +
|
||||
"($android_secondary_abi_toolchain)",
|
||||
]
|
||||
}
|
||||
}
|
||||
} else {
|
||||
|
@ -88,8 +81,7 @@ template("angle_apk") {
|
|||
"root_out_dir")
|
||||
secondary_abi_loadable_modules = []
|
||||
foreach(_library, angle_libraries) {
|
||||
secondary_abi_loadable_modules +=
|
||||
[ "${_secondary_out_dir}/lib.compressed/lib${_library}${angle_libs_suffix}.so" ]
|
||||
secondary_abi_loadable_modules += [ "${_secondary_out_dir}/lib.compressed/lib${_library}${angle_libs_suffix}.so" ]
|
||||
}
|
||||
if (angle_enable_vulkan_validation_layers) {
|
||||
foreach(_layer, vulkan_validation_layers) {
|
||||
|
@ -115,9 +107,7 @@ template("angle_apk") {
|
|||
} else {
|
||||
loadable_modules = []
|
||||
foreach(_library, angle_libraries) {
|
||||
loadable_modules += [
|
||||
"${root_out_dir}/lib.compressed/lib${_library}${angle_libs_suffix}.so",
|
||||
]
|
||||
loadable_modules += [ "${root_out_dir}/lib.compressed/lib${_library}${angle_libs_suffix}.so" ]
|
||||
}
|
||||
if (angle_enable_vulkan_validation_layers) {
|
||||
foreach(_layer, vulkan_validation_layers) {
|
||||
|
@ -126,18 +116,5 @@ template("angle_apk") {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
# 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" ]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,18 +0,0 @@
|
|||
<?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>
|
|
@ -1,34 +0,0 @@
|
|||
<?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>
|
|
@ -1,10 +0,0 @@
|
|||
<?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>
|
|
@ -1,18 +0,0 @@
|
|||
<?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>
|
|
@ -1,14 +0,0 @@
|
|||
<?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_show_angle_in_use_dialog_box">show_angle_in_use_dialog_box</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>
|
||||
<string name="global_settings_angle_whitelist">angle_whitelist</string>
|
||||
</resources>
|
|
@ -1,14 +0,0 @@
|
|||
<?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_angle_in_use_dialog">angle_in_use_dialog_box</string>
|
||||
<string name="pref_key_select_opengl_driver_category">select_opengl_driver_category</string>
|
||||
<string name="pref_key_installed_pkgs">installed_pkgs</string>
|
||||
</resources>
|
|
@ -1,36 +0,0 @@
|
|||
<?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="use_angle_for_all_apps">Use ANGLE for all apps</string>
|
||||
|
||||
<!-- This is the label for a toggle button.
|
||||
When the toggle is enabled, we will show a dialog box indicating that ANGLE is in use.
|
||||
This is also used as a Quick Settings tile label. -->
|
||||
<string name="show_angle_in_use_dialog_box">Show dialog box when ANGLE is loaded</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>
|
|
@ -1,38 +0,0 @@
|
|||
<?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/use_angle_for_all_apps"
|
||||
android:summary="@string/global_settings_driver_all_angle"
|
||||
android:defaultValue="false"
|
||||
android:enabled="false"/>
|
||||
|
||||
<android.support.v14.preference.SwitchPreference
|
||||
android:key="@string/pref_key_angle_in_use_dialog"
|
||||
android:title="@string/show_angle_in_use_dialog_box"
|
||||
android:summary="@string/global_settings_show_angle_in_use_dialog_box"
|
||||
android:defaultValue="false"
|
||||
android:enabled="true"/>
|
||||
</PreferenceCategory>
|
||||
|
||||
<PreferenceCategory
|
||||
android:key="@string/pref_key_select_opengl_driver_category"
|
||||
android:title="@string/select_opengl_driver_title">
|
||||
|
||||
</PreferenceCategory>
|
||||
|
||||
</android.support.v7.preference.PreferenceScreen>
|
|
@ -9,16 +9,11 @@ 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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,272 +0,0 @@
|
|||
/*
|
||||
* 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;
|
||||
}
|
||||
}
|
||||
|
||||
Boolean getShowAngleInUseDialogBox()
|
||||
{
|
||||
ContentResolver contentResolver = mContext.getContentResolver();
|
||||
try
|
||||
{
|
||||
int showAngleInUseDialogBox = Settings.Global.getInt(contentResolver,
|
||||
mContext.getString(R.string.global_settings_show_angle_in_use_dialog_box));
|
||||
return (showAngleInUseDialogBox == 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);
|
||||
}
|
||||
|
||||
static void updateShowAngleInUseDialog(Context context, Boolean showAngleInUseDialog)
|
||||
{
|
||||
ContentResolver contentResolver = context.getContentResolver();
|
||||
Settings.Global.putInt(contentResolver,
|
||||
context.getString(R.string.global_settings_show_angle_in_use_dialog_box),
|
||||
showAngleInUseDialog ? 1 : 0);
|
||||
}
|
||||
|
||||
static void updateAngleWhitelist(Context context, String packageNames)
|
||||
{
|
||||
ContentResolver contentResolver = context.getContentResolver();
|
||||
Settings.Global.putString(contentResolver,
|
||||
context.getString(R.string.global_settings_angle_whitelist), packageNames);
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
|
@ -1,291 +0,0 @@
|
|||
/*
|
||||
* 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 SwitchPreference mShowAngleInUseDialogSwitchPref;
|
||||
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 showAngleInUseDialogKey =
|
||||
getContext().getString(R.string.pref_key_angle_in_use_dialog);
|
||||
Boolean showAngleInUseDialogBox = mPrefs.getBoolean(showAngleInUseDialogKey, false);
|
||||
mShowAngleInUseDialogSwitchPref =
|
||||
(SwitchPreference) findPreference(showAngleInUseDialogKey);
|
||||
mShowAngleInUseDialogSwitchPref.setChecked(mGlobalSettings.getShowAngleInUseDialogBox());
|
||||
mShowAngleInUseDialogSwitchPref.setOnPreferenceClickListener(
|
||||
new Preference.OnPreferenceClickListener() {
|
||||
@Override
|
||||
public boolean onPreferenceClick(Preference preference)
|
||||
{
|
||||
Receiver.updateShowAngleInUseDialogBox(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();
|
||||
}
|
||||
}
|
|
@ -1,132 +0,0 @@
|
|||
/*
|
||||
* 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;
|
||||
|
||||
import java.io.InputStream;
|
||||
import java.io.IOException;
|
||||
|
||||
import org.json.JSONObject;
|
||||
import org.json.JSONArray;
|
||||
import org.json.JSONException;
|
||||
|
||||
public class Receiver extends BroadcastReceiver
|
||||
{
|
||||
|
||||
private final static String TAG = "AngleReceiver";
|
||||
private final static String ANGLE_RULES_FILE = "a4a_rules.json";
|
||||
|
||||
@Override
|
||||
public void onReceive(Context context, Intent intent)
|
||||
{
|
||||
Log.v(TAG, "Received intent, updating ANGLE whitelist...");
|
||||
|
||||
String jsonStr = loadRules(context);
|
||||
|
||||
String packageNames = parsePackageNames(jsonStr);
|
||||
|
||||
// Update the ANGLE whitelist
|
||||
if (packageNames != null) {
|
||||
GlobalSettings.updateAngleWhitelist(context, packageNames);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Open the rules file and pull all the JSON into a string
|
||||
*/
|
||||
private String loadRules(Context context)
|
||||
{
|
||||
String jsonStr = null;
|
||||
|
||||
try {
|
||||
InputStream rulesStream = context.getAssets().open(ANGLE_RULES_FILE);
|
||||
int size = rulesStream.available();
|
||||
byte[] buffer = new byte[size];
|
||||
rulesStream.read(buffer);
|
||||
rulesStream.close();
|
||||
jsonStr = new String(buffer, "UTF-8");
|
||||
|
||||
} catch (IOException ioe) {
|
||||
Log.e(TAG, "Failed to open " + ANGLE_RULES_FILE + ": ", ioe);
|
||||
}
|
||||
|
||||
return jsonStr;
|
||||
}
|
||||
|
||||
/*
|
||||
* Extract all app package names from the json file and return them comma separated
|
||||
*/
|
||||
private String parsePackageNames(String rulesJSON)
|
||||
{
|
||||
String packageNames = "";
|
||||
|
||||
try {
|
||||
JSONObject jsonObj = new JSONObject(rulesJSON);
|
||||
JSONArray rules = jsonObj.getJSONArray("Rules");
|
||||
if (rules == null) {
|
||||
Log.e(TAG, "No Rules in " + ANGLE_RULES_FILE);
|
||||
return null;
|
||||
}
|
||||
for (int i = 0; i < rules.length(); i++) {
|
||||
JSONObject rule = rules.getJSONObject(i);
|
||||
JSONArray apps = rule.optJSONArray("Applications");
|
||||
if (apps == null) {
|
||||
Log.v(TAG, "Skipping Rules entry with no Applications");
|
||||
continue;
|
||||
}
|
||||
for (int j = 0; j < apps.length(); j++) {
|
||||
JSONObject app = apps.optJSONObject(j);
|
||||
String appName = app.optString("AppName");
|
||||
if ((appName == null) || appName.isEmpty()) {
|
||||
Log.e(TAG, "Invalid AppName: '" + appName + "'");
|
||||
}
|
||||
if (packageNames.isEmpty()) {
|
||||
packageNames += appName;
|
||||
} else {
|
||||
packageNames += "," + appName;
|
||||
}
|
||||
}
|
||||
}
|
||||
Log.v(TAG, "Parsed the following package names from " +
|
||||
ANGLE_RULES_FILE + ": " + packageNames);
|
||||
} catch (JSONException je) {
|
||||
Log.e(TAG, "Error when parsing angle JSON: ", je);
|
||||
return null;
|
||||
}
|
||||
|
||||
return packageNames;
|
||||
}
|
||||
|
||||
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, "All PKGs use ANGLE set to: " + allUseAngle);
|
||||
}
|
||||
|
||||
static void updateShowAngleInUseDialogBox(Context context)
|
||||
{
|
||||
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
|
||||
String showAngleInUseDialogBoxKey =
|
||||
context.getString(R.string.pref_key_angle_in_use_dialog);
|
||||
boolean showAngleInUseDialogBox = prefs.getBoolean(showAngleInUseDialogBoxKey, false);
|
||||
|
||||
GlobalSettings.updateShowAngleInUseDialog(context, showAngleInUseDialogBox);
|
||||
|
||||
Log.v(TAG, "Show 'ANGLE In Use' dialog box set to: " + showAngleInUseDialogBox);
|
||||
}
|
||||
}
|
|
@ -1,25 +0,0 @@
|
|||
/*
|
||||
* 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);
|
||||
}
|
||||
}
|
Загрузка…
Ссылка в новой задаче