| /* |
| * 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; |
| } |
| } |