• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2019 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 package com.android.angle.common;
17 
18 import android.content.ContentResolver;
19 import android.content.Context;
20 import android.content.pm.PackageInfo;
21 import android.provider.Settings;
22 import android.util.Log;
23 
24 import java.util.ArrayList;
25 import java.util.Arrays;
26 import java.util.List;
27 
28 class GlobalSettings
29 {
30 
31     private final String TAG = this.getClass().getSimpleName();
32 
33     private Context mContext;
34     private List<PackageInfo> mInstalledPkgs         = new ArrayList<>();
35     private List<String> mGlobalSettingsDriverPkgs   = new ArrayList<>();
36     private List<String> mGlobalSettingsDriverValues = new ArrayList<>();
37 
GlobalSettings(Context context, List<PackageInfo> installedPkgs)38     GlobalSettings(Context context, List<PackageInfo> installedPkgs)
39     {
40         mContext = context;
41 
42         setInstalledPkgs(installedPkgs);
43     }
44 
clearAllGlobalSettings(Context context)45     static void clearAllGlobalSettings(Context context)
46     {
47         // angle_gl_driver_all_angle
48         updateAllUseAngle(context, false);
49         // show_angle_in_use_dialog_box
50         updateShowAngleInUseDialog(context, false);
51         // angle_gl_driver_selection_pkgs, angle_gl_driver_selection_values
52         ContentResolver contentResolver = context.getContentResolver();
53         Settings.Global.putString(contentResolver,
54                 context.getString(R.string.global_settings_driver_selection_pkgs), "\"\"");
55         Settings.Global.putString(contentResolver,
56                 context.getString(R.string.global_settings_driver_selection_values), "\"\"");
57 
58         // For completeness, we'll clear the angle_debug_package, but we don't allow setting
59         // it via the APK (currently)
60         Settings.Global.putString(contentResolver,
61                 context.getString(R.string.global_settings_angle_debug_package), "");
62 
63         // Skip angle_allowlist; not updatable via Developer Options
64     }
65 
getAllUseAngle()66     Boolean getAllUseAngle()
67     {
68         ContentResolver contentResolver = mContext.getContentResolver();
69         try
70         {
71             int allUseAngle = Settings.Global.getInt(
72                     contentResolver, mContext.getString(R.string.global_settings_driver_all_angle));
73             return (allUseAngle == 1);
74         }
75         catch (Settings.SettingNotFoundException e)
76         {
77             return false;
78         }
79     }
80 
getShowAngleInUseDialogBox()81     Boolean getShowAngleInUseDialogBox()
82     {
83         ContentResolver contentResolver = mContext.getContentResolver();
84         try
85         {
86             int showAngleInUseDialogBox = Settings.Global.getInt(contentResolver,
87                     mContext.getString(R.string.global_settings_show_angle_in_use_dialog_box));
88             return (showAngleInUseDialogBox == 1);
89         }
90         catch (Settings.SettingNotFoundException e)
91         {
92             return false;
93         }
94     }
95 
updateAllUseAngle(Context context, Boolean allUseAngle)96     static void updateAllUseAngle(Context context, Boolean allUseAngle)
97     {
98         ContentResolver contentResolver = context.getContentResolver();
99         Settings.Global.putInt(contentResolver,
100                 context.getString(R.string.global_settings_driver_all_angle), allUseAngle ? 1 : 0);
101     }
102 
updateShowAngleInUseDialog(Context context, Boolean showAngleInUseDialog)103     static void updateShowAngleInUseDialog(Context context, Boolean showAngleInUseDialog)
104     {
105         ContentResolver contentResolver = context.getContentResolver();
106         Settings.Global.putInt(contentResolver,
107                 context.getString(R.string.global_settings_show_angle_in_use_dialog_box),
108                 showAngleInUseDialog ? 1 : 0);
109     }
110 
updateAngleAllowlist(Context context, String packageNames)111     static void updateAngleAllowlist(Context context, String packageNames)
112     {
113         ContentResolver contentResolver = context.getContentResolver();
114         Settings.Global.putString(contentResolver,
115                 context.getString(R.string.global_settings_angle_allowlist), packageNames);
116     }
117 
updatePkg(String pkgName, String driver)118     void updatePkg(String pkgName, String driver)
119     {
120         int pkgIndex = getGlobalSettingsPkgIndex(pkgName);
121 
122         if (!isValidDiverValue(driver))
123         {
124             Log.e(TAG, "Attempting to update a PKG with an invalid driver: '" + driver + "'");
125             return;
126         }
127 
128         String defaultDriver = mContext.getString(R.string.default_driver);
129         if (driver.equals(defaultDriver))
130         {
131             if (pkgIndex >= 0)
132             {
133                 // We only store global settings for driver values other than the default
134                 mGlobalSettingsDriverPkgs.remove(pkgIndex);
135                 mGlobalSettingsDriverValues.remove(pkgIndex);
136             }
137         }
138         else
139         {
140             if (pkgIndex >= 0)
141             {
142                 mGlobalSettingsDriverValues.set(pkgIndex, driver);
143             }
144             else
145             {
146                 mGlobalSettingsDriverPkgs.add(pkgName);
147                 mGlobalSettingsDriverValues.add(driver);
148             }
149         }
150 
151         writeGlobalSettings();
152     }
153 
getDriverForPkg(String pkgName)154     String getDriverForPkg(String pkgName)
155     {
156         int pkgIndex = getGlobalSettingsPkgIndex(pkgName);
157 
158         if (pkgIndex >= 0)
159         {
160             return mGlobalSettingsDriverValues.get(pkgIndex);
161         }
162 
163         return null;
164     }
165 
setInstalledPkgs(List<PackageInfo> installedPkgs)166     void setInstalledPkgs(List<PackageInfo> installedPkgs)
167     {
168         mInstalledPkgs = installedPkgs;
169 
170         updateGlobalSettings();
171     }
172 
updateGlobalSettings()173     private void updateGlobalSettings()
174     {
175         readGlobalSettings();
176 
177         validateGlobalSettings();
178 
179         writeGlobalSettings();
180     }
181 
readGlobalSettings()182     private void readGlobalSettings()
183     {
184         mGlobalSettingsDriverPkgs = getGlobalSettingsString(
185                 mContext.getString(R.string.global_settings_driver_selection_pkgs));
186         mGlobalSettingsDriverValues = getGlobalSettingsString(
187                 mContext.getString(R.string.global_settings_driver_selection_values));
188     }
189 
getGlobalSettingsString(String globalSetting)190     private List<String> getGlobalSettingsString(String globalSetting)
191     {
192         List<String> valueList;
193         ContentResolver contentResolver = mContext.getContentResolver();
194         String settingsValue            = Settings.Global.getString(contentResolver, globalSetting);
195 
196         if (settingsValue != null)
197         {
198             valueList = new ArrayList<>(Arrays.asList(settingsValue.split(",")));
199         }
200         else
201         {
202             valueList = new ArrayList<>();
203         }
204 
205         return valueList;
206     }
207 
writeGlobalSettings()208     private void writeGlobalSettings()
209     {
210         String driverPkgs   = String.join(",", mGlobalSettingsDriverPkgs);
211         String driverValues = String.join(",", mGlobalSettingsDriverValues);
212 
213         ContentResolver contentResolver = mContext.getContentResolver();
214         Settings.Global.putString(contentResolver,
215                 mContext.getString(R.string.global_settings_driver_selection_pkgs), driverPkgs);
216         Settings.Global.putString(contentResolver,
217                 mContext.getString(R.string.global_settings_driver_selection_values), driverValues);
218     }
219 
validateGlobalSettings()220     private void validateGlobalSettings()
221     {
222         // Verify lengths
223         if (mGlobalSettingsDriverPkgs.size() != mGlobalSettingsDriverValues.size())
224         {
225             // The lengths don't match, so clear the values out and rebuild later.
226             mGlobalSettingsDriverPkgs.clear();
227             mGlobalSettingsDriverValues.clear();
228             return;
229         }
230 
231         String defaultDriver = mContext.getString(R.string.default_driver);
232         // Use a temp list, since we're potentially modifying the original list.
233         List<String> globalSettingsDriverPkgs = new ArrayList<>(mGlobalSettingsDriverPkgs);
234         for (String pkgName : globalSettingsDriverPkgs)
235         {
236             // Remove any uninstalled packages.
237             if (!isPkgInstalled(pkgName))
238             {
239                 removePkgFromGlobalSettings(pkgName);
240             }
241             // Remove any packages with invalid driver values
242             else if (!isValidDiverValue(getDriverForPkg(pkgName)))
243             {
244                 removePkgFromGlobalSettings(pkgName);
245             }
246             // Remove any packages with the 'default' driver selected
247             else if (defaultDriver.equals(getDriverForPkg(pkgName)))
248             {
249                 removePkgFromGlobalSettings(pkgName);
250             }
251         }
252     }
253 
removePkgFromGlobalSettings(String pkgName)254     private void removePkgFromGlobalSettings(String pkgName)
255     {
256         int pkgIndex = getGlobalSettingsPkgIndex(pkgName);
257 
258         mGlobalSettingsDriverPkgs.remove(pkgIndex);
259         mGlobalSettingsDriverValues.remove(pkgIndex);
260     }
261 
getGlobalSettingsPkgIndex(String pkgName)262     private int getGlobalSettingsPkgIndex(String pkgName)
263     {
264         for (int pkgIndex = 0; pkgIndex < mGlobalSettingsDriverPkgs.size(); pkgIndex++)
265         {
266             if (mGlobalSettingsDriverPkgs.get(pkgIndex).equals(pkgName))
267             {
268                 return pkgIndex;
269             }
270         }
271 
272         return -1;
273     }
274 
isPkgInstalled(String pkgName)275     private Boolean isPkgInstalled(String pkgName)
276     {
277         for (PackageInfo pkg : mInstalledPkgs)
278         {
279             if (pkg.packageName.equals(pkgName))
280             {
281                 return true;
282             }
283         }
284 
285         return false;
286     }
287 
isValidDiverValue(String driverValue)288     private Boolean isValidDiverValue(String driverValue)
289     {
290         CharSequence[] drivers = mContext.getResources().getStringArray(R.array.driver_values);
291 
292         for (CharSequence driver : drivers)
293         {
294             if (driverValue.equals(driver.toString()))
295             {
296                 return true;
297             }
298         }
299 
300         return false;
301     }
302 }
303