blob: 18c6159f210f1067a380cf38b3b451275af17e45 [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;
Amith Yamasanic06d4c42011-02-25 14:35:20 -080028import android.net.ConnectivityManager;
29import android.net.LinkProperties;
Anders Hammar1b2dd9032010-04-08 10:03:50 +020030import android.os.Bundle;
Amith Yamasani60133dd2010-09-11 14:17:31 -070031import android.os.SystemProperties;
The Android Open Source Projectafc4ab22009-03-03 19:32:34 -080032import android.preference.Preference;
33import android.preference.PreferenceGroup;
Amith Yamasani02cf71a2010-09-21 15:48:52 -070034import android.preference.PreferenceActivity.Header;
Amith Yamasani60133dd2010-09-11 14:17:31 -070035import android.telephony.TelephonyManager;
Anders Hammar1b2dd9032010-04-08 10:03:50 +020036import android.text.TextUtils;
Daisuke Miyakawaa2633d02010-09-15 20:09:12 -070037
Amith Yamasanic06d4c42011-02-25 14:35:20 -080038import java.net.InetAddress;
39import java.util.Iterator;
Daisuke Miyakawaa2633d02010-09-15 20:09:12 -070040import java.util.List;
The Android Open Source Projectafc4ab22009-03-03 19:32:34 -080041
The Android Open Source Projectafc4ab22009-03-03 19:32:34 -080042public class Utils {
43
44 /**
45 * Set the preference's title to the matching activity's label.
46 */
47 public static final int UPDATE_PREFERENCE_FLAG_SET_TITLE_TO_MATCHING_ACTIVITY = 1;
48
49 /**
Anders Hammar1b2dd9032010-04-08 10:03:50 +020050 * Name of the meta-data item that should be set in the AndroidManifest.xml
51 * to specify the icon that should be displayed for the preference.
52 */
53 private static final String META_DATA_PREFERENCE_ICON = "com.android.settings.icon";
54
55 /**
56 * Name of the meta-data item that should be set in the AndroidManifest.xml
57 * to specify the title that should be displayed for the preference.
58 */
59 private static final String META_DATA_PREFERENCE_TITLE = "com.android.settings.title";
60
61 /**
62 * Name of the meta-data item that should be set in the AndroidManifest.xml
63 * to specify the summary text that should be displayed for the preference.
64 */
65 private static final String META_DATA_PREFERENCE_SUMMARY = "com.android.settings.summary";
66
67 /**
The Android Open Source Projectafc4ab22009-03-03 19:32:34 -080068 * Finds a matching activity for a preference's intent. If a matching
69 * activity is not found, it will remove the preference.
Ying Wanga7188322010-01-04 18:45:10 -080070 *
The Android Open Source Projectafc4ab22009-03-03 19:32:34 -080071 * @param context The context.
72 * @param parentPreferenceGroup The preference group that contains the
73 * preference whose intent is being resolved.
74 * @param preferenceKey The key of the preference whose intent is being
75 * resolved.
76 * @param flags 0 or one or more of
77 * {@link #UPDATE_PREFERENCE_FLAG_SET_TITLE_TO_MATCHING_ACTIVITY}
78 * .
79 * @return Whether an activity was found. If false, the preference was
80 * removed.
81 */
82 public static boolean updatePreferenceToSpecificActivityOrRemove(Context context,
83 PreferenceGroup parentPreferenceGroup, String preferenceKey, int flags) {
Ying Wanga7188322010-01-04 18:45:10 -080084
The Android Open Source Projectafc4ab22009-03-03 19:32:34 -080085 Preference preference = parentPreferenceGroup.findPreference(preferenceKey);
86 if (preference == null) {
87 return false;
88 }
Ying Wanga7188322010-01-04 18:45:10 -080089
The Android Open Source Projectafc4ab22009-03-03 19:32:34 -080090 Intent intent = preference.getIntent();
91 if (intent != null) {
92 // Find the activity that is in the system image
93 PackageManager pm = context.getPackageManager();
94 List<ResolveInfo> list = pm.queryIntentActivities(intent, 0);
95 int listSize = list.size();
96 for (int i = 0; i < listSize; i++) {
97 ResolveInfo resolveInfo = list.get(i);
98 if ((resolveInfo.activityInfo.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM)
99 != 0) {
Ying Wanga7188322010-01-04 18:45:10 -0800100
The Android Open Source Projectafc4ab22009-03-03 19:32:34 -0800101 // Replace the intent with this specific activity
102 preference.setIntent(new Intent().setClassName(
103 resolveInfo.activityInfo.packageName,
104 resolveInfo.activityInfo.name));
105
106 if ((flags & UPDATE_PREFERENCE_FLAG_SET_TITLE_TO_MATCHING_ACTIVITY) != 0) {
107 // Set the preference title to the activity's label
108 preference.setTitle(resolveInfo.loadLabel(pm));
109 }
Ying Wanga7188322010-01-04 18:45:10 -0800110
The Android Open Source Projectafc4ab22009-03-03 19:32:34 -0800111 return true;
112 }
113 }
114 }
115
116 // Did not find a matching activity, so remove the preference
117 parentPreferenceGroup.removePreference(preference);
Ying Wanga7188322010-01-04 18:45:10 -0800118
The Android Open Source Projectafc4ab22009-03-03 19:32:34 -0800119 return true;
120 }
Ying Wanga7188322010-01-04 18:45:10 -0800121
122 /**
Anders Hammar1b2dd9032010-04-08 10:03:50 +0200123 * Finds a matching activity for a preference's intent. If a matching
124 * activity is not found, it will remove the preference. The icon, title and
125 * summary of the preference will also be updated with the values retrieved
126 * from the activity's meta-data elements. If no meta-data elements are
127 * specified then the preference title will be set to match the label of the
128 * activity, an icon and summary text will not be displayed.
129 *
130 * @param context The context.
131 * @param parentPreferenceGroup The preference group that contains the
132 * preference whose intent is being resolved.
133 * @param preferenceKey The key of the preference whose intent is being
134 * resolved.
135 *
136 * @return Whether an activity was found. If false, the preference was
137 * removed.
138 *
139 * @see {@link #META_DATA_PREFERENCE_ICON}
140 * {@link #META_DATA_PREFERENCE_TITLE}
141 * {@link #META_DATA_PREFERENCE_SUMMARY}
142 */
143 public static boolean updatePreferenceToSpecificActivityFromMetaDataOrRemove(Context context,
144 PreferenceGroup parentPreferenceGroup, String preferenceKey) {
145
146 IconPreferenceScreen preference = (IconPreferenceScreen)parentPreferenceGroup
147 .findPreference(preferenceKey);
148 if (preference == null) {
149 return false;
150 }
151
152 Intent intent = preference.getIntent();
153 if (intent != null) {
154 // Find the activity that is in the system image
155 PackageManager pm = context.getPackageManager();
156 List<ResolveInfo> list = pm.queryIntentActivities(intent, PackageManager.GET_META_DATA);
157 int listSize = list.size();
158 for (int i = 0; i < listSize; i++) {
159 ResolveInfo resolveInfo = list.get(i);
160 if ((resolveInfo.activityInfo.applicationInfo.flags
161 & ApplicationInfo.FLAG_SYSTEM) != 0) {
162 Drawable icon = null;
163 String title = null;
164 String summary = null;
165
166 // Get the activity's meta-data
167 try {
168 Resources res = pm
169 .getResourcesForApplication(resolveInfo.activityInfo.packageName);
170 Bundle metaData = resolveInfo.activityInfo.metaData;
171
172 if (res != null && metaData != null) {
173 icon = res.getDrawable(metaData.getInt(META_DATA_PREFERENCE_ICON));
174 title = res.getString(metaData.getInt(META_DATA_PREFERENCE_TITLE));
175 summary = res.getString(metaData.getInt(META_DATA_PREFERENCE_SUMMARY));
176 }
177 } catch (NameNotFoundException e) {
178 // Ignore
179 } catch (NotFoundException e) {
180 // Ignore
181 }
182
183 // Set the preference title to the activity's label if no
184 // meta-data is found
185 if (TextUtils.isEmpty(title)) {
186 title = resolveInfo.loadLabel(pm).toString();
187 }
188
189 // Set icon, title and summary for the preference
190 preference.setIcon(icon);
191 preference.setTitle(title);
192 preference.setSummary(summary);
193
194 // Replace the intent with this specific activity
195 preference.setIntent(new Intent().setClassName(
196 resolveInfo.activityInfo.packageName,
197 resolveInfo.activityInfo.name));
198
199 return true;
200 }
201 }
202 }
203
204 // Did not find a matching activity, so remove the preference
205 parentPreferenceGroup.removePreference(preference);
206
207 return false;
208 }
209
Amith Yamasani02cf71a2010-09-21 15:48:52 -0700210 public static boolean updateHeaderToSpecificActivityFromMetaDataOrRemove(Context context,
211 List<Header> target, Header header) {
212
213 Intent intent = header.intent;
214 if (intent != null) {
215 // Find the activity that is in the system image
216 PackageManager pm = context.getPackageManager();
217 List<ResolveInfo> list = pm.queryIntentActivities(intent, PackageManager.GET_META_DATA);
218 int listSize = list.size();
219 for (int i = 0; i < listSize; i++) {
220 ResolveInfo resolveInfo = list.get(i);
221 if ((resolveInfo.activityInfo.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM)
222 != 0) {
223 Drawable icon = null;
224 String title = null;
225 String summary = null;
226
227 // Get the activity's meta-data
228 try {
229 Resources res = pm.getResourcesForApplication(
230 resolveInfo.activityInfo.packageName);
231 Bundle metaData = resolveInfo.activityInfo.metaData;
232
233 if (res != null && metaData != null) {
234 icon = res.getDrawable(metaData.getInt(META_DATA_PREFERENCE_ICON));
235 title = res.getString(metaData.getInt(META_DATA_PREFERENCE_TITLE));
236 summary = res.getString(metaData.getInt(META_DATA_PREFERENCE_SUMMARY));
237 }
238 } catch (NameNotFoundException e) {
239 // Ignore
240 } catch (NotFoundException e) {
241 // Ignore
242 }
243
244 // Set the preference title to the activity's label if no
245 // meta-data is found
246 if (TextUtils.isEmpty(title)) {
247 title = resolveInfo.loadLabel(pm).toString();
248 }
249
250 // Set icon, title and summary for the preference
251 // TODO:
252 //header.icon = icon;
253 header.title = title;
254 header.summary = summary;
255 // Replace the intent with this specific activity
256 header.intent = new Intent().setClassName(resolveInfo.activityInfo.packageName,
257 resolveInfo.activityInfo.name);
258
259 return true;
260 }
261 }
262 }
263
264 // Did not find a matching activity, so remove the preference
265 if (target.remove(header)) System.err.println("Removed " + header.id);
266
267 return false;
268 }
269
Anders Hammar1b2dd9032010-04-08 10:03:50 +0200270 /**
Ying Wanga7188322010-01-04 18:45:10 -0800271 * Returns true if Monkey is running.
272 */
273 public static boolean isMonkeyRunning() {
274 return SystemProperties.getBoolean("ro.monkey", false);
275 }
Amith Yamasani60133dd2010-09-11 14:17:31 -0700276
277 /**
278 * Returns whether the device is voice-capable (meaning, it is also a phone).
279 */
280 public static boolean isVoiceCapable(Context context) {
281 TelephonyManager telephony =
282 (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
283 return telephony != null && telephony.isVoiceCapable();
284 }
Amith Yamasani0f85c482011-02-23 17:19:11 -0800285
286 public static boolean isWifiOnly() {
287 return "wifi-only".equals(SystemProperties.get("ro.carrier"));
288 }
Amith Yamasanic06d4c42011-02-25 14:35:20 -0800289
290 /**
291 * Returns the WIFI IP Addresses, if any, taking into account IPv4 and IPv6 style addresses.
292 * @param context the application context
293 * @return the formatted and comma-separated IP addresses, or null if none.
294 */
295 public static String getWifiIpAddresses(Context context) {
296 ConnectivityManager cm = (ConnectivityManager)
297 context.getSystemService(Context.CONNECTIVITY_SERVICE);
298 LinkProperties prop = cm.getLinkProperties(ConnectivityManager.TYPE_WIFI);
299 if (prop == null) return null;
300 Iterator<InetAddress> iter = prop.getAddresses().iterator();
301 // If there are no entries, return null
302 if (!iter.hasNext()) return null;
303 // Concatenate all available addresses, comma separated
304 String addresses = "";
305 while (iter.hasNext()) {
306 addresses += iter.next().getHostAddress();
307 if (iter.hasNext()) addresses += ", ";
308 }
309 return addresses;
310 }
The Android Open Source Projectafc4ab22009-03-03 19:32:34 -0800311}