blob: dd80222ab161c8d0ef9c013fe985e3c89d9d2852 [file] [log] [blame]
The Android Open Source Projectafc4ab22009-03-03 19:32:34 -08001/**
2 * Copyright (C) 2007 Google Inc.
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License"); you may not
5 * use this file except in compliance with the License. You may obtain a copy
6 * 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, WITHOUT
12 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13 * License for the specific language governing permissions and limitations
14 * under the License.
15 */
16
17package com.android.settings;
18
19import android.content.Context;
20import android.content.Intent;
21import android.content.pm.ApplicationInfo;
22import android.content.pm.PackageManager;
Daisuke Miyakawaa2633d02010-09-15 20:09:12 -070023import android.content.pm.ResolveInfo;
Amith Yamasani02cf71a2010-09-21 15:48:52 -070024import android.content.pm.PackageManager.NameNotFoundException;
Anders Hammar1b2dd9032010-04-08 10:03:50 +020025import android.content.res.Resources;
26import android.content.res.Resources.NotFoundException;
27import android.graphics.drawable.Drawable;
28import android.os.Bundle;
Amith Yamasani60133dd2010-09-11 14:17:31 -070029import android.os.SystemProperties;
The Android Open Source Projectafc4ab22009-03-03 19:32:34 -080030import android.preference.Preference;
31import android.preference.PreferenceGroup;
Amith Yamasani02cf71a2010-09-21 15:48:52 -070032import android.preference.PreferenceActivity.Header;
Amith Yamasani60133dd2010-09-11 14:17:31 -070033import android.telephony.TelephonyManager;
Anders Hammar1b2dd9032010-04-08 10:03:50 +020034import android.text.TextUtils;
Daisuke Miyakawaa2633d02010-09-15 20:09:12 -070035
36import java.util.List;
The Android Open Source Projectafc4ab22009-03-03 19:32:34 -080037
The Android Open Source Projectafc4ab22009-03-03 19:32:34 -080038public class Utils {
39
40 /**
41 * Set the preference's title to the matching activity's label.
42 */
43 public static final int UPDATE_PREFERENCE_FLAG_SET_TITLE_TO_MATCHING_ACTIVITY = 1;
44
45 /**
Anders Hammar1b2dd9032010-04-08 10:03:50 +020046 * Name of the meta-data item that should be set in the AndroidManifest.xml
47 * to specify the icon that should be displayed for the preference.
48 */
49 private static final String META_DATA_PREFERENCE_ICON = "com.android.settings.icon";
50
51 /**
52 * Name of the meta-data item that should be set in the AndroidManifest.xml
53 * to specify the title that should be displayed for the preference.
54 */
55 private static final String META_DATA_PREFERENCE_TITLE = "com.android.settings.title";
56
57 /**
58 * Name of the meta-data item that should be set in the AndroidManifest.xml
59 * to specify the summary text that should be displayed for the preference.
60 */
61 private static final String META_DATA_PREFERENCE_SUMMARY = "com.android.settings.summary";
62
63 /**
The Android Open Source Projectafc4ab22009-03-03 19:32:34 -080064 * Finds a matching activity for a preference's intent. If a matching
65 * activity is not found, it will remove the preference.
Ying Wanga7188322010-01-04 18:45:10 -080066 *
The Android Open Source Projectafc4ab22009-03-03 19:32:34 -080067 * @param context The context.
68 * @param parentPreferenceGroup The preference group that contains the
69 * preference whose intent is being resolved.
70 * @param preferenceKey The key of the preference whose intent is being
71 * resolved.
72 * @param flags 0 or one or more of
73 * {@link #UPDATE_PREFERENCE_FLAG_SET_TITLE_TO_MATCHING_ACTIVITY}
74 * .
75 * @return Whether an activity was found. If false, the preference was
76 * removed.
77 */
78 public static boolean updatePreferenceToSpecificActivityOrRemove(Context context,
79 PreferenceGroup parentPreferenceGroup, String preferenceKey, int flags) {
Ying Wanga7188322010-01-04 18:45:10 -080080
The Android Open Source Projectafc4ab22009-03-03 19:32:34 -080081 Preference preference = parentPreferenceGroup.findPreference(preferenceKey);
82 if (preference == null) {
83 return false;
84 }
Ying Wanga7188322010-01-04 18:45:10 -080085
The Android Open Source Projectafc4ab22009-03-03 19:32:34 -080086 Intent intent = preference.getIntent();
87 if (intent != null) {
88 // Find the activity that is in the system image
89 PackageManager pm = context.getPackageManager();
90 List<ResolveInfo> list = pm.queryIntentActivities(intent, 0);
91 int listSize = list.size();
92 for (int i = 0; i < listSize; i++) {
93 ResolveInfo resolveInfo = list.get(i);
94 if ((resolveInfo.activityInfo.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM)
95 != 0) {
Ying Wanga7188322010-01-04 18:45:10 -080096
The Android Open Source Projectafc4ab22009-03-03 19:32:34 -080097 // Replace the intent with this specific activity
98 preference.setIntent(new Intent().setClassName(
99 resolveInfo.activityInfo.packageName,
100 resolveInfo.activityInfo.name));
101
102 if ((flags & UPDATE_PREFERENCE_FLAG_SET_TITLE_TO_MATCHING_ACTIVITY) != 0) {
103 // Set the preference title to the activity's label
104 preference.setTitle(resolveInfo.loadLabel(pm));
105 }
Ying Wanga7188322010-01-04 18:45:10 -0800106
The Android Open Source Projectafc4ab22009-03-03 19:32:34 -0800107 return true;
108 }
109 }
110 }
111
112 // Did not find a matching activity, so remove the preference
113 parentPreferenceGroup.removePreference(preference);
Ying Wanga7188322010-01-04 18:45:10 -0800114
The Android Open Source Projectafc4ab22009-03-03 19:32:34 -0800115 return true;
116 }
Ying Wanga7188322010-01-04 18:45:10 -0800117
118 /**
Anders Hammar1b2dd9032010-04-08 10:03:50 +0200119 * Finds a matching activity for a preference's intent. If a matching
120 * activity is not found, it will remove the preference. The icon, title and
121 * summary of the preference will also be updated with the values retrieved
122 * from the activity's meta-data elements. If no meta-data elements are
123 * specified then the preference title will be set to match the label of the
124 * activity, an icon and summary text will not be displayed.
125 *
126 * @param context The context.
127 * @param parentPreferenceGroup The preference group that contains the
128 * preference whose intent is being resolved.
129 * @param preferenceKey The key of the preference whose intent is being
130 * resolved.
131 *
132 * @return Whether an activity was found. If false, the preference was
133 * removed.
134 *
135 * @see {@link #META_DATA_PREFERENCE_ICON}
136 * {@link #META_DATA_PREFERENCE_TITLE}
137 * {@link #META_DATA_PREFERENCE_SUMMARY}
138 */
139 public static boolean updatePreferenceToSpecificActivityFromMetaDataOrRemove(Context context,
140 PreferenceGroup parentPreferenceGroup, String preferenceKey) {
141
142 IconPreferenceScreen preference = (IconPreferenceScreen)parentPreferenceGroup
143 .findPreference(preferenceKey);
144 if (preference == null) {
145 return false;
146 }
147
148 Intent intent = preference.getIntent();
149 if (intent != null) {
150 // Find the activity that is in the system image
151 PackageManager pm = context.getPackageManager();
152 List<ResolveInfo> list = pm.queryIntentActivities(intent, PackageManager.GET_META_DATA);
153 int listSize = list.size();
154 for (int i = 0; i < listSize; i++) {
155 ResolveInfo resolveInfo = list.get(i);
156 if ((resolveInfo.activityInfo.applicationInfo.flags
157 & ApplicationInfo.FLAG_SYSTEM) != 0) {
158 Drawable icon = null;
159 String title = null;
160 String summary = null;
161
162 // Get the activity's meta-data
163 try {
164 Resources res = pm
165 .getResourcesForApplication(resolveInfo.activityInfo.packageName);
166 Bundle metaData = resolveInfo.activityInfo.metaData;
167
168 if (res != null && metaData != null) {
169 icon = res.getDrawable(metaData.getInt(META_DATA_PREFERENCE_ICON));
170 title = res.getString(metaData.getInt(META_DATA_PREFERENCE_TITLE));
171 summary = res.getString(metaData.getInt(META_DATA_PREFERENCE_SUMMARY));
172 }
173 } catch (NameNotFoundException e) {
174 // Ignore
175 } catch (NotFoundException e) {
176 // Ignore
177 }
178
179 // Set the preference title to the activity's label if no
180 // meta-data is found
181 if (TextUtils.isEmpty(title)) {
182 title = resolveInfo.loadLabel(pm).toString();
183 }
184
185 // Set icon, title and summary for the preference
186 preference.setIcon(icon);
187 preference.setTitle(title);
188 preference.setSummary(summary);
189
190 // Replace the intent with this specific activity
191 preference.setIntent(new Intent().setClassName(
192 resolveInfo.activityInfo.packageName,
193 resolveInfo.activityInfo.name));
194
195 return true;
196 }
197 }
198 }
199
200 // Did not find a matching activity, so remove the preference
201 parentPreferenceGroup.removePreference(preference);
202
203 return false;
204 }
205
Amith Yamasani02cf71a2010-09-21 15:48:52 -0700206 public static boolean updateHeaderToSpecificActivityFromMetaDataOrRemove(Context context,
207 List<Header> target, Header header) {
208
209 Intent intent = header.intent;
210 if (intent != null) {
211 // Find the activity that is in the system image
212 PackageManager pm = context.getPackageManager();
213 List<ResolveInfo> list = pm.queryIntentActivities(intent, PackageManager.GET_META_DATA);
214 int listSize = list.size();
215 for (int i = 0; i < listSize; i++) {
216 ResolveInfo resolveInfo = list.get(i);
217 if ((resolveInfo.activityInfo.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM)
218 != 0) {
219 Drawable icon = null;
220 String title = null;
221 String summary = null;
222
223 // Get the activity's meta-data
224 try {
225 Resources res = pm.getResourcesForApplication(
226 resolveInfo.activityInfo.packageName);
227 Bundle metaData = resolveInfo.activityInfo.metaData;
228
229 if (res != null && metaData != null) {
230 icon = res.getDrawable(metaData.getInt(META_DATA_PREFERENCE_ICON));
231 title = res.getString(metaData.getInt(META_DATA_PREFERENCE_TITLE));
232 summary = res.getString(metaData.getInt(META_DATA_PREFERENCE_SUMMARY));
233 }
234 } catch (NameNotFoundException e) {
235 // Ignore
236 } catch (NotFoundException e) {
237 // Ignore
238 }
239
240 // Set the preference title to the activity's label if no
241 // meta-data is found
242 if (TextUtils.isEmpty(title)) {
243 title = resolveInfo.loadLabel(pm).toString();
244 }
245
246 // Set icon, title and summary for the preference
247 // TODO:
248 //header.icon = icon;
249 header.title = title;
250 header.summary = summary;
251 // Replace the intent with this specific activity
252 header.intent = new Intent().setClassName(resolveInfo.activityInfo.packageName,
253 resolveInfo.activityInfo.name);
254
255 return true;
256 }
257 }
258 }
259
260 // Did not find a matching activity, so remove the preference
261 if (target.remove(header)) System.err.println("Removed " + header.id);
262
263 return false;
264 }
265
Anders Hammar1b2dd9032010-04-08 10:03:50 +0200266 /**
Ying Wanga7188322010-01-04 18:45:10 -0800267 * Returns true if Monkey is running.
268 */
269 public static boolean isMonkeyRunning() {
270 return SystemProperties.getBoolean("ro.monkey", false);
271 }
Amith Yamasani60133dd2010-09-11 14:17:31 -0700272
273 /**
274 * Returns whether the device is voice-capable (meaning, it is also a phone).
275 */
276 public static boolean isVoiceCapable(Context context) {
277 TelephonyManager telephony =
278 (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
279 return telephony != null && telephony.isVoiceCapable();
280 }
Amith Yamasani0f85c482011-02-23 17:19:11 -0800281
282 public static boolean isWifiOnly() {
283 return "wifi-only".equals(SystemProperties.get("ro.carrier"));
284 }
The Android Open Source Projectafc4ab22009-03-03 19:32:34 -0800285}