blob: 5106a78f7266b806524ef6693c3cd608bd9a1502 [file] [log] [blame]
/*
* Copyright 2019 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.settings.development.graphicsdriver;
import android.content.ContentResolver;
import android.content.Context;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
import android.content.res.Resources;
import android.os.Build;
import android.os.Handler;
import android.os.Looper;
import android.os.SystemProperties;
import android.provider.Settings;
import android.text.TextUtils;
import androidx.annotation.VisibleForTesting;
import androidx.preference.ListPreference;
import androidx.preference.Preference;
import androidx.preference.PreferenceScreen;
import com.android.settings.R;
import com.android.settings.core.BasePreferenceController;
import com.android.settingslib.core.lifecycle.LifecycleObserver;
import com.android.settingslib.core.lifecycle.events.OnStart;
import com.android.settingslib.core.lifecycle.events.OnStop;
import com.android.settingslib.development.DevelopmentSettingsEnabler;
import dalvik.system.VMRuntime;
import java.util.ArrayList;
import java.util.List;
/**
* Controller of global switch to enable updatable driver for all Apps.
*/
public class GraphicsDriverEnableForAllAppsPreferenceController extends BasePreferenceController
implements Preference.OnPreferenceChangeListener,
GraphicsDriverContentObserver.OnGraphicsDriverContentChangedListener,
LifecycleObserver, OnStart, OnStop {
public static final int UPDATABLE_DRIVER_DEFAULT = 0;
public static final int UPDATABLE_DRIVER_PRODUCTION_ALL_APPS = 1;
public static final int UPDATABLE_DRIVER_PRERELEASE_ALL_APPS = 2;
public static final int UPDATABLE_DRIVER_OFF = 3;
public static final String PROPERTY_GFX_DRIVER_PRODUCTION = "ro.gfx.driver.0";
public static final String PROPERTY_GFX_DRIVER_PRERELEASE = "ro.gfx.driver.1";
private final Context mContext;
private final ContentResolver mContentResolver;
private final String mPreferenceDefault;
private final String mPreferenceProductionDriver;
private final String mPreferencePrereleaseDriver;
@VisibleForTesting
CharSequence[] mEntryList;
@VisibleForTesting
GraphicsDriverContentObserver mGraphicsDriverContentObserver;
private ListPreference mPreference;
public GraphicsDriverEnableForAllAppsPreferenceController(Context context, String key) {
super(context, key);
mContext = context;
mContentResolver = context.getContentResolver();
final Resources resources = context.getResources();
mPreferenceDefault = resources.getString(R.string.graphics_driver_app_preference_default);
mPreferenceProductionDriver =
resources.getString(R.string.graphics_driver_app_preference_production_driver);
mPreferencePrereleaseDriver =
resources.getString(R.string.graphics_driver_app_preference_prerelease_driver);
mEntryList = constructEntryList(mContext, false);
mGraphicsDriverContentObserver =
new GraphicsDriverContentObserver(new Handler(Looper.getMainLooper()), this);
}
@Override
public int getAvailabilityStatus() {
return DevelopmentSettingsEnabler.isDevelopmentSettingsEnabled(mContext)
&& (Settings.Global.getInt(mContentResolver,
Settings.Global.UPDATABLE_DRIVER_ALL_APPS,
UPDATABLE_DRIVER_DEFAULT)
!= UPDATABLE_DRIVER_OFF)
? AVAILABLE
: CONDITIONALLY_UNAVAILABLE;
}
@Override
public void displayPreference(PreferenceScreen screen) {
super.displayPreference(screen);
mPreference = screen.findPreference(getPreferenceKey());
mPreference.setEntries(mEntryList);
mPreference.setEntryValues(mEntryList);
mPreference.setOnPreferenceChangeListener(this);
}
@Override
public void onStart() {
mGraphicsDriverContentObserver.register(mContentResolver);
}
@Override
public void onStop() {
mGraphicsDriverContentObserver.unregister(mContentResolver);
}
@Override
public void updateState(Preference preference) {
final ListPreference listPref = (ListPreference) preference;
listPref.setVisible(isAvailable());
final int currentChoice = Settings.Global.getInt(
mContentResolver, Settings.Global.UPDATABLE_DRIVER_ALL_APPS,
UPDATABLE_DRIVER_DEFAULT);
if (currentChoice == UPDATABLE_DRIVER_PRODUCTION_ALL_APPS) {
listPref.setValue(mPreferenceProductionDriver);
listPref.setSummary(mPreferenceProductionDriver);
} else if (currentChoice == UPDATABLE_DRIVER_PRERELEASE_ALL_APPS) {
listPref.setValue(mPreferencePrereleaseDriver);
listPref.setSummary(mPreferencePrereleaseDriver);
} else {
listPref.setValue(mPreferenceDefault);
listPref.setSummary(mPreferenceDefault);
}
}
@Override
public boolean onPreferenceChange(Preference preference, Object newValue) {
final ListPreference listPref = (ListPreference) preference;
final String value = newValue.toString();
final int currentChoice = Settings.Global.getInt(
mContentResolver, Settings.Global.UPDATABLE_DRIVER_ALL_APPS,
UPDATABLE_DRIVER_DEFAULT);
final int userChoice;
if (value.equals(mPreferenceProductionDriver)) {
userChoice = UPDATABLE_DRIVER_PRODUCTION_ALL_APPS;
} else if (value.equals(mPreferencePrereleaseDriver)) {
userChoice = UPDATABLE_DRIVER_PRERELEASE_ALL_APPS;
} else {
userChoice = UPDATABLE_DRIVER_DEFAULT;
}
listPref.setValue(value);
listPref.setSummary(value);
if (userChoice != currentChoice) {
Settings.Global.putInt(
mContentResolver, Settings.Global.UPDATABLE_DRIVER_ALL_APPS, userChoice);
}
return true;
}
@Override
public void onGraphicsDriverContentChanged() {
updateState(mPreference);
}
/**
* Constructs and returns a list of graphics driver choices.
*/
public static CharSequence[] constructEntryList(Context context, boolean withSystem) {
final Resources resources = context.getResources();
final String prereleaseDriverPackageName =
SystemProperties.get(PROPERTY_GFX_DRIVER_PRERELEASE);
final String productionDriverPackageName =
SystemProperties.get(PROPERTY_GFX_DRIVER_PRODUCTION);
List<CharSequence> entryList = new ArrayList<>();
entryList.add(resources.getString(R.string.graphics_driver_app_preference_default));
final PackageManager pm = context.getPackageManager();
if (!TextUtils.isEmpty(prereleaseDriverPackageName)
&& hasDriverPackage(pm, prereleaseDriverPackageName)) {
entryList.add(resources.getString(
R.string.graphics_driver_app_preference_prerelease_driver));
}
if (!TextUtils.isEmpty(productionDriverPackageName)
&& hasDriverPackage(pm, productionDriverPackageName)) {
entryList.add(resources.getString(
R.string.graphics_driver_app_preference_production_driver));
}
if (withSystem) {
entryList.add(resources.getString(R.string.graphics_driver_app_preference_system));
}
CharSequence[] filteredEntryList = new CharSequence[entryList.size()];
filteredEntryList = entryList.toArray(filteredEntryList);
return filteredEntryList;
}
private static boolean hasDriverPackage(PackageManager pm, String driverPackageName) {
final ApplicationInfo driverAppInfo;
try {
driverAppInfo = pm.getApplicationInfo(driverPackageName,
PackageManager.MATCH_SYSTEM_ONLY);
} catch (PackageManager.NameNotFoundException e) {
return false;
}
if (driverAppInfo.targetSdkVersion < Build.VERSION_CODES.O) {
return false;
}
final String abi = chooseAbi(driverAppInfo);
if (abi == null) {
return false;
}
return true;
}
private static String chooseAbi(ApplicationInfo ai) {
final String isa = VMRuntime.getCurrentInstructionSet();
if (ai.primaryCpuAbi != null
&& isa.equals(VMRuntime.getInstructionSet(ai.primaryCpuAbi))) {
return ai.primaryCpuAbi;
}
if (ai.secondaryCpuAbi != null
&& isa.equals(VMRuntime.getInstructionSet(ai.secondaryCpuAbi))) {
return ai.secondaryCpuAbi;
}
return null;
}
}