• 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.Context;
19 import android.content.Intent;
20 import android.content.IntentFilter;
21 import android.content.SharedPreferences;
22 import android.content.SharedPreferences.OnSharedPreferenceChangeListener;
23 import android.content.pm.ApplicationInfo;
24 import android.content.pm.ActivityInfo;
25 import android.content.pm.PackageInfo;
26 import android.content.pm.PackageManager;
27 import android.content.pm.PackageManager.NameNotFoundException;
28 import android.content.pm.ResolveInfo;
29 import android.os.Build;
30 import android.os.Bundle;
31 import android.os.Process;
32 import android.util.Log;
33 import androidx.preference.ListPreference;
34 import androidx.preference.Preference;
35 import androidx.preference.PreferenceCategory;
36 import androidx.preference.PreferenceFragment;
37 import androidx.preference.PreferenceManager;
38 import androidx.preference.SwitchPreference;
39 
40 import java.text.Collator;
41 import java.util.ArrayList;
42 import java.util.Collections;
43 import java.util.Comparator;
44 import java.util.List;
45 import java.util.Map;
46 
47 import com.android.angle.R;
48 
49 public class MainFragment extends PreferenceFragment implements OnSharedPreferenceChangeListener
50 {
51 
52     private final String TAG = this.getClass().getSimpleName();
53     private final boolean DEBUG = false;
54 
55     private SharedPreferences mSharedPreferences;
56     private SwitchPreference mShowAngleInUseSwitchPref;
57     private List<ListPreference> mApplicationListPreferences = new ArrayList<>();
58 
59     private GlobalSettings mGlobalSettings;
60     private Receiver mRefreshReceiver = new Receiver();
61     private List<PackageInfo> mInstalledPackages = new ArrayList<>();
62     private AngleRuleHelper angleRuleHelper;
63 
64     SharedPreferences.OnSharedPreferenceChangeListener listener =
65             new SharedPreferences.OnSharedPreferenceChangeListener() {
66                 public void onSharedPreferenceChanged(SharedPreferences prefs, String key)
67                 {
68                     // Nothing to do yet
69                 }
70             };
71 
72     @Override
onCreate(Bundle savedInstanceState)73     public void onCreate(Bundle savedInstanceState)
74     {
75         super.onCreate(savedInstanceState);
76 
77         queryInstalledPackages();
78 
79         mSharedPreferences = PreferenceManager.getDefaultSharedPreferences(
80                 getActivity().getApplicationContext());
81         if (DEBUG)
82         {
83             Map<String, ?> preferences = PreferenceManager
84                     .getDefaultSharedPreferences(getActivity().getApplicationContext()).getAll();
85             for (String key : preferences.keySet())
86             {
87                 Log.d(TAG, key + ", " + preferences.get(key));
88             }
89         }
90         mGlobalSettings = new GlobalSettings(getContext(), mSharedPreferences, mInstalledPackages);
91 
92         createShowAngleInUseSwitchPreference();
93         createInstalledAppsListPreference();
94     }
95 
96     @Override
onResume()97     public void onResume()
98     {
99         super.onResume();
100 
101         getActivity().registerReceiver(mRefreshReceiver,
102                 new IntentFilter(
103                         getContext().getString(R.string.intent_angle_for_android_toast_message)), Context.RECEIVER_EXPORTED);
104         getPreferenceScreen().getSharedPreferences().registerOnSharedPreferenceChangeListener(
105                 listener);
106         updatePreferences();
107     }
108 
109     @Override
onPause()110     public void onPause()
111     {
112         getActivity().unregisterReceiver(mRefreshReceiver);
113         getPreferenceScreen().getSharedPreferences().unregisterOnSharedPreferenceChangeListener(
114                 listener);
115 
116         super.onPause();
117     }
118 
119     @Override
onCreatePreferences(Bundle savedInstanceState, String rootKey)120     public void onCreatePreferences(Bundle savedInstanceState, String rootKey)
121     {
122         addPreferencesFromResource(R.xml.main);
123     }
124 
125     @Override
onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key)126     public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key)
127     {
128         Log.v(TAG, "Shared preference changed: " + key);
129     }
130 
updatePreferences()131     private void updatePreferences()
132     {
133         mShowAngleInUseSwitchPref.setChecked(mGlobalSettings.getShowAngleInUse());
134     }
135 
createShowAngleInUseSwitchPreference()136     private void createShowAngleInUseSwitchPreference()
137     {
138         final String showAngleInUseKey =
139                 getContext().getString(R.string.pref_key_angle_in_use_dialog);
140         mShowAngleInUseSwitchPref =
141                 (SwitchPreference) findPreference(showAngleInUseKey);
142 
143         mShowAngleInUseSwitchPref.setOnPreferenceChangeListener(
144                 new Preference.OnPreferenceChangeListener() {
145                     @Override
146                     public boolean onPreferenceChange(Preference preference, Object newValue)
147                     {
148                         if (DEBUG)
149                         {
150                             Log.v(TAG, "Show angle in use switch: " + newValue.toString());
151                         }
152                         GlobalSettings.updateShowAngleInUse(getContext(), (Boolean) newValue);
153                         return true;
154                     }
155         });
156     }
157 
createInstalledAppsListPreference()158     private void createInstalledAppsListPreference()
159     {
160         final String selectDriverCategoryKey =
161                 getContext().getString(R.string.pref_key_select_opengl_driver_category);
162         final PreferenceCategory preferenceCategory =
163                 (PreferenceCategory) findPreference(selectDriverCategoryKey);
164         preferenceCategory.removeAll();
165         mApplicationListPreferences.clear();
166 
167         final Context context = preferenceCategory.getContext();
168         for (PackageInfo packageInfo : mInstalledPackages)
169         {
170             ListPreference listPreference = new ListPreference(context);
171             initListPreference(packageInfo, listPreference);
172             preferenceCategory.addPreference(listPreference);
173         }
174     }
175 
queryInstalledPackages()176     private void queryInstalledPackages()
177     {
178         mInstalledPackages.clear();
179 
180         final Intent mainIntent = new Intent(Intent.ACTION_MAIN, null);
181         mainIntent.addCategory(Intent.CATEGORY_LAUNCHER);
182         final PackageManager packageManager = getActivity().getPackageManager();
183 
184         List<ResolveInfo> resolveInfos = packageManager.queryIntentActivities(mainIntent, 0);
185 
186         for (ResolveInfo resolveInfo : resolveInfos)
187         {
188             final String packageName = resolveInfo.activityInfo.packageName;
189             if (DEBUG)
190             {
191                 Log.d(TAG, "Package found: " + packageName);
192             }
193             try
194             {
195                 if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU)
196                 {
197                     PackageInfo packageInfo = packageManager.getPackageInfo(packageName,
198                             PackageManager.PackageInfoFlags.of(0));
199                     mInstalledPackages.add(packageInfo);
200                 }
201                 else
202                 {
203                     PackageInfo packageInfo = packageManager.getPackageInfo(packageName, 0);
204                     mInstalledPackages.add(packageInfo);
205                 }
206             }
207             catch (NameNotFoundException e)
208             {
209                 Log.v(TAG, "Package not found: " + packageName);
210             }
211         }
212 
213         Collections.sort(mInstalledPackages, displayNameComparator);
214     }
215 
216     private final Comparator<PackageInfo> displayNameComparator = new Comparator<PackageInfo>() {
217         public final int compare(PackageInfo a, PackageInfo b)
218         {
219             return collator.compare(getAppName(a), getAppName(b));
220         }
221 
222         private final Collator collator = Collator.getInstance();
223     };
224 
getAppName(PackageInfo packageInfo)225     private String getAppName(PackageInfo packageInfo)
226     {
227         return packageInfo.applicationInfo.loadLabel(getActivity().getPackageManager()).toString();
228     }
229 
initListPreference(PackageInfo packageInfo, ListPreference listPreference)230     private void initListPreference(PackageInfo packageInfo, ListPreference listPreference)
231     {
232         CharSequence[] drivers = getResources().getStringArray(R.array.driver_values);
233         listPreference.setEntries(drivers);
234         listPreference.setEntryValues(drivers);
235 
236         final String packageName = packageInfo.packageName;
237         listPreference.setKey(packageName);
238         listPreference.setTitle(getAppName(packageInfo));
239 
240         final String driverSelectionValue = mSharedPreferences.getString(packageName,
241                 GlobalSettings.DRIVER_SELECTION_DEFAULT);
242         listPreference.setDefaultValue(driverSelectionValue);
243         listPreference.setValue(driverSelectionValue);
244         listPreference.setSummary(driverSelectionValue);
245 
246         final String dialogTitle = getContext().getString(R.string.select_opengl_driver_title);
247         listPreference.setDialogTitle(dialogTitle);
248 
249         listPreference.setDialogIcon(packageInfo.applicationInfo.loadIcon(getActivity().getPackageManager()));
250 
251         listPreference.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() {
252             @Override
253             public boolean onPreferenceChange(Preference preference, Object newValue)
254             {
255                 final ListPreference listPreference = (ListPreference) preference;
256                 final String newDriverSelectionValue = newValue.toString();
257                 listPreference.setSummary(newDriverSelectionValue);
258                 mGlobalSettings.updatePackageDriverSelection(preference.getKey(), newDriverSelectionValue);
259                 return true;
260             }
261         });
262 
263         mApplicationListPreferences.add(listPreference);
264     }
265 }
266