• 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.IntentFilter;
19 import android.content.SharedPreferences;
20 import android.content.SharedPreferences.OnSharedPreferenceChangeListener;
21 import android.content.pm.ApplicationInfo;
22 import android.content.pm.PackageInfo;
23 import android.os.Bundle;
24 import android.os.Process;
25 import android.util.Log;
26 import androidx.preference.ListPreference;
27 import androidx.preference.Preference;
28 import androidx.preference.PreferenceCategory;
29 import androidx.preference.PreferenceFragment;
30 import androidx.preference.PreferenceManager;
31 import androidx.preference.SwitchPreference;
32 
33 import java.text.Collator;
34 import java.util.ArrayList;
35 import java.util.Collections;
36 import java.util.Comparator;
37 import java.util.List;
38 import java.util.Map;
39 
40 public class MainFragment extends PreferenceFragment implements OnSharedPreferenceChangeListener
41 {
42 
43     private final String TAG = this.getClass().getSimpleName();
44 
45     private SharedPreferences mPrefs;
46     private GlobalSettings mGlobalSettings;
47     private Receiver mRefreshReceiver = new Receiver();
48     private SwitchPreference mAllAngleSwitchPref;
49     private SwitchPreference mShowAngleInUseDialogSwitchPref;
50     private List<PackageInfo> mInstalledPkgs      = new ArrayList<>();
51     private List<ListPreference> mDriverListPrefs = new ArrayList<>();
52 
53     SharedPreferences.OnSharedPreferenceChangeListener listener =
54             new SharedPreferences.OnSharedPreferenceChangeListener() {
55                 public void onSharedPreferenceChanged(SharedPreferences prefs, String key)
56                 {
57                     // Nothing to do yet
58                 }
59             };
60 
61     @Override
onCreate(Bundle savedInstanceState)62     public void onCreate(Bundle savedInstanceState)
63     {
64         super.onCreate(savedInstanceState);
65 
66         getInstalledPkgsList();
67 
68         mPrefs = PreferenceManager.getDefaultSharedPreferences(
69                 getActivity().getApplicationContext());
70         validatePreferences();
71 
72         mGlobalSettings = new GlobalSettings(getContext(), mInstalledPkgs);
73         mergeGlobalSettings();
74 
75         createAllUseAnglePreference();
76         createShowAngleInUseDialogPreference();
77 
78         updatePreferencesFromGlobalSettings();
79     }
80 
81     @Override
onResume()82     public void onResume()
83     {
84         super.onResume();
85 
86         updatePreferencesFromGlobalSettings();
87 
88         getActivity().registerReceiver(mRefreshReceiver,
89                 new IntentFilter(
90                         getContext().getString(R.string.intent_angle_for_android_toast_message)));
91         getPreferenceScreen().getSharedPreferences().registerOnSharedPreferenceChangeListener(
92                 listener);
93     }
94 
95     @Override
onPause()96     public void onPause()
97     {
98         getActivity().unregisterReceiver(mRefreshReceiver);
99         getPreferenceScreen().getSharedPreferences().unregisterOnSharedPreferenceChangeListener(
100                 listener);
101 
102         super.onPause();
103     }
104 
105     @Override
onCreatePreferences(Bundle savedInstanceState, String rootKey)106     public void onCreatePreferences(Bundle savedInstanceState, String rootKey)
107     {
108         addPreferencesFromResource(R.xml.main);
109     }
110 
111     @Override
onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key)112     public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key)
113     {
114         Log.v(TAG, "Shared preference changed: key = '" + key + "'");
115     }
116 
updatePreferencesFromGlobalSettings()117     private void updatePreferencesFromGlobalSettings()
118     {
119         mAllAngleSwitchPref.setChecked(mGlobalSettings.getAllUseAngle());
120         mShowAngleInUseDialogSwitchPref.setChecked(mGlobalSettings.getShowAngleInUseDialogBox());
121         createInstalledAppsListPreference();
122     }
123 
createAllUseAnglePreference()124     private void createAllUseAnglePreference()
125     {
126         String allUseAngleKey = getContext().getString(R.string.pref_key_all_angle);
127         Boolean allUseAngle   = mPrefs.getBoolean(allUseAngleKey, false);
128         mAllAngleSwitchPref   = (SwitchPreference) findPreference(allUseAngleKey);
129         mAllAngleSwitchPref.setOnPreferenceClickListener(
130                 new Preference.OnPreferenceClickListener() {
131                     @Override
132                     public boolean onPreferenceClick(Preference preference)
133                     {
134                         Receiver.updateAllUseAngle(getContext());
135                         return true;
136                     }
137                 });
138     }
139 
createShowAngleInUseDialogPreference()140     private void createShowAngleInUseDialogPreference()
141     {
142         String showAngleInUseDialogKey =
143                 getContext().getString(R.string.pref_key_angle_in_use_dialog);
144         Boolean showAngleInUseDialogBox = mPrefs.getBoolean(showAngleInUseDialogKey, false);
145         mShowAngleInUseDialogSwitchPref =
146                 (SwitchPreference) findPreference(showAngleInUseDialogKey);
147         mShowAngleInUseDialogSwitchPref.setOnPreferenceClickListener(
148                 new Preference.OnPreferenceClickListener() {
149                     @Override
150                     public boolean onPreferenceClick(Preference preference)
151                     {
152                         Receiver.updateShowAngleInUseDialogBox(getContext());
153                         return true;
154                     }
155                 });
156     }
157 
createInstalledAppsListPreference()158     private void createInstalledAppsListPreference()
159     {
160         getInstalledPkgsList();
161         mGlobalSettings.setInstalledPkgs(mInstalledPkgs);
162         mergeGlobalSettings();
163 
164         String selectDriverCatKey =
165                 getContext().getString(R.string.pref_key_select_opengl_driver_category);
166         PreferenceCategory installedPkgsCat =
167                 (PreferenceCategory) findPreference(selectDriverCatKey);
168         installedPkgsCat.removeAll();
169         mDriverListPrefs.clear();
170         if (mInstalledPkgs.isEmpty())
171         {
172             ListPreference listPreference = new ListPreference(installedPkgsCat.getContext());
173             initEmptyListPreference(listPreference);
174             installedPkgsCat.addPreference(listPreference);
175         }
176         else
177         {
178             for (PackageInfo packageInfo : mInstalledPkgs)
179             {
180                 ListPreference listPreference = new ListPreference(installedPkgsCat.getContext());
181                 initListPreference(packageInfo, listPreference);
182                 installedPkgsCat.addPreference(listPreference);
183             }
184         }
185     }
186 
validatePreferences()187     private void validatePreferences()
188     {
189         Map<String, ?> allPrefs = mPrefs.getAll();
190 
191         // Remove Preference values for any uninstalled PKGs
192         for (String key : allPrefs.keySet())
193         {
194             // Remove any uninstalled PKGs
195             PackageInfo packageInfo = getPackageInfoForPackageName(key);
196 
197             if (packageInfo != null)
198             {
199                 removePkgPreference(key);
200             }
201         }
202     }
203 
getInstalledPkgsList()204     private void getInstalledPkgsList()
205     {
206         List<PackageInfo> pkgs = getActivity().getPackageManager().getInstalledPackages(0);
207 
208         mInstalledPkgs.clear();
209 
210         for (PackageInfo packageInfo : pkgs)
211         {
212             if (packageInfo.applicationInfo.uid == Process.SYSTEM_UID)
213             {
214                 continue;
215             }
216 
217             // Filter out apps that are system apps
218             if ((packageInfo.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0)
219             {
220                 continue;
221             }
222 
223             mInstalledPkgs.add(packageInfo);
224         }
225 
226         Collections.sort(mInstalledPkgs, displayNameComparator);
227     }
228 
229     private final Comparator<PackageInfo> displayNameComparator = new Comparator<PackageInfo>() {
230         public final int compare(PackageInfo a, PackageInfo b)
231         {
232             return collator.compare(getAppName(a), getAppName(b));
233         }
234 
235         private final Collator collator = Collator.getInstance();
236     };
237 
getAppName(PackageInfo packageInfo)238     private String getAppName(PackageInfo packageInfo)
239     {
240         return packageInfo.applicationInfo.loadLabel(getActivity().getPackageManager()).toString();
241     }
242 
initEmptyListPreference(ListPreference listPreference)243     private void initEmptyListPreference(ListPreference listPreference)
244     {
245         String noAppsInstalledTitle = getContext().getString(R.string.no_apps_installed_title);
246         listPreference.setTitle(noAppsInstalledTitle);
247 
248         String noAppsInstalledSummary = getContext().getString(R.string.no_apps_installed_summary);
249         listPreference.setSummary(noAppsInstalledSummary);
250 
251         listPreference.setSelectable(false);
252 
253         mDriverListPrefs.add(listPreference);
254     }
255 
initListPreference(PackageInfo packageInfo, ListPreference listPreference)256     private void initListPreference(PackageInfo packageInfo, ListPreference listPreference)
257     {
258         CharSequence[] drivers = getResources().getStringArray(R.array.driver_values);
259         listPreference.setEntryValues(drivers);
260         listPreference.setEntries(drivers);
261 
262         String defaultDriver = getContext().getString(R.string.default_driver);
263         listPreference.setDefaultValue(defaultDriver);
264 
265         String dialogTitleKey = getContext().getString(R.string.select_opengl_driver_title);
266         listPreference.setDialogTitle(dialogTitleKey);
267         listPreference.setKey(packageInfo.packageName);
268 
269         listPreference.setTitle(getAppName(packageInfo));
270         listPreference.setSummary(mPrefs.getString(packageInfo.packageName, defaultDriver));
271 
272         listPreference.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() {
273             @Override
274             public boolean onPreferenceChange(Preference preference, Object newValue)
275             {
276                 ListPreference listPreference = (ListPreference) preference;
277 
278                 listPreference.setSummary(newValue.toString());
279                 mGlobalSettings.updatePkg(preference.getKey(), newValue.toString());
280 
281                 return true;
282             }
283         });
284 
285         mDriverListPrefs.add(listPreference);
286     }
287 
removePkgPreference(String key)288     private void removePkgPreference(String key)
289     {
290         SharedPreferences.Editor editor = mPrefs.edit();
291 
292         editor.remove(key);
293         editor.apply();
294 
295         for (ListPreference listPreference : mDriverListPrefs)
296         {
297             if (listPreference.getKey().equals(key))
298             {
299                 mDriverListPrefs.remove(listPreference);
300             }
301         }
302     }
303 
getPackageInfoForPackageName(String pkgName)304     private PackageInfo getPackageInfoForPackageName(String pkgName)
305     {
306         PackageInfo foundPackageInfo = null;
307 
308         for (PackageInfo packageInfo : mInstalledPkgs)
309         {
310             if (pkgName.equals(getAppName(packageInfo)))
311             {
312                 foundPackageInfo = packageInfo;
313                 break;
314             }
315         }
316 
317         return foundPackageInfo;
318     }
319 
mergeGlobalSettings()320     private void mergeGlobalSettings()
321     {
322         SharedPreferences.Editor editor = mPrefs.edit();
323 
324         for (PackageInfo packageInfo : mInstalledPkgs)
325         {
326             String driver = mGlobalSettings.getDriverForPkg(packageInfo.packageName);
327 
328             if (driver != null)
329             {
330                 editor.putString(packageInfo.packageName, driver);
331             }
332             else
333             {
334                 // No Global.Setting driver value for this package, so must be 'default'
335                 String defaultDriver = getContext().getString(R.string.default_driver);
336                 editor.putString(packageInfo.packageName, defaultDriver);
337             }
338         }
339 
340         editor.apply();
341     }
342 }
343