Dan Morrill | 5df275b | 2010-08-11 12:19:19 -0700 | [diff] [blame] | 1 | /* |
| 2 | * Copyright (C) 2010 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 | |
| 17 | /* |
| 18 | * This file references fs_error.png, fs_good.png, fs_indeterminate.png, |
| 19 | * and fs_warning.png which are licensed under Creative Commons 3.0 |
| 20 | * by fatcow.com. |
| 21 | * http://www.fatcow.com/free-icons/ |
| 22 | * http://creativecommons.org/licenses/by/3.0/us/ |
| 23 | */ |
Dan Morrill | 71351d8 | 2010-10-20 15:26:00 -0700 | [diff] [blame] | 24 | |
Dan Morrill | 5df275b | 2010-08-11 12:19:19 -0700 | [diff] [blame] | 25 | package com.android.cts.verifier.features; |
| 26 | |
Brian Muramatsu | e118187 | 2010-08-20 12:59:39 -0700 | [diff] [blame] | 27 | import com.android.cts.verifier.PassFailButtons; |
Dan Morrill | 5df275b | 2010-08-11 12:19:19 -0700 | [diff] [blame] | 28 | import com.android.cts.verifier.R; |
| 29 | |
Dan Morrill | 5df275b | 2010-08-11 12:19:19 -0700 | [diff] [blame] | 30 | import android.content.pm.FeatureInfo; |
| 31 | import android.content.pm.PackageManager; |
Dan Morrill | 71351d8 | 2010-10-20 15:26:00 -0700 | [diff] [blame] | 32 | import android.os.Build; |
Dan Morrill | 5df275b | 2010-08-11 12:19:19 -0700 | [diff] [blame] | 33 | import android.os.Bundle; |
| 34 | import android.view.View; |
| 35 | import android.widget.ImageView; |
| 36 | import android.widget.SimpleAdapter; |
| 37 | import android.widget.TextView; |
| 38 | |
Brian Muramatsu | e118187 | 2010-08-20 12:59:39 -0700 | [diff] [blame] | 39 | import java.util.ArrayList; |
| 40 | import java.util.Collections; |
| 41 | import java.util.Comparator; |
| 42 | import java.util.HashMap; |
Brian Muramatsu | d8d37a4 | 2011-07-07 14:11:26 -0700 | [diff] [blame] | 43 | import java.util.LinkedHashSet; |
| 44 | import java.util.Set; |
Brian Muramatsu | e118187 | 2010-08-20 12:59:39 -0700 | [diff] [blame] | 45 | |
| 46 | public class FeatureSummaryActivity extends PassFailButtons.ListActivity { |
Dan Morrill | 5df275b | 2010-08-11 12:19:19 -0700 | [diff] [blame] | 47 | /** |
| 48 | * Simple storage class for data about an Android feature. |
| 49 | */ |
| 50 | static class Feature { |
| 51 | /** |
| 52 | * The name of the feature. Should be one of the PackageManager.FEATURE* |
| 53 | * constants. |
| 54 | */ |
| 55 | public String name; |
| 56 | |
| 57 | /** |
| 58 | * Indicates whether the field is present on the current device. |
| 59 | */ |
| 60 | public boolean present; |
| 61 | |
| 62 | /** |
| 63 | * Indicates whether the field is required for the current device. |
| 64 | */ |
| 65 | public boolean required; |
| 66 | |
| 67 | /** |
| 68 | * Constructor does not include 'present' because that's a detected |
| 69 | * value, and not set during creation. |
Brian Muramatsu | de69444 | 2011-03-09 14:13:01 -0800 | [diff] [blame] | 70 | * |
Dan Morrill | 5df275b | 2010-08-11 12:19:19 -0700 | [diff] [blame] | 71 | * @param name value for this.name |
| 72 | * @param required value for this.required |
| 73 | */ |
| 74 | public Feature(String name, boolean required) { |
| 75 | this.name = name; |
| 76 | this.required = required; |
| 77 | this.present = false; |
| 78 | } |
Brian Muramatsu | d8d37a4 | 2011-07-07 14:11:26 -0700 | [diff] [blame] | 79 | |
| 80 | @Override |
| 81 | public boolean equals(Object o) { |
| 82 | if (this == o) { |
| 83 | return true; |
| 84 | } else if (o == null || !(o instanceof Feature)) { |
| 85 | return false; |
| 86 | } else { |
| 87 | Feature feature = (Feature) o; |
| 88 | return name.equals(feature.name); |
| 89 | } |
| 90 | } |
| 91 | |
| 92 | @Override |
| 93 | public int hashCode() { |
| 94 | return name.hashCode(); |
| 95 | } |
Dan Morrill | 5df275b | 2010-08-11 12:19:19 -0700 | [diff] [blame] | 96 | } |
| 97 | |
Dan Morrill | 71351d8 | 2010-10-20 15:26:00 -0700 | [diff] [blame] | 98 | public static final Feature[] ALL_ECLAIR_FEATURES = { |
Dan Morrill | 5df275b | 2010-08-11 12:19:19 -0700 | [diff] [blame] | 99 | new Feature(PackageManager.FEATURE_CAMERA, true), |
| 100 | new Feature(PackageManager.FEATURE_CAMERA_AUTOFOCUS, false), |
| 101 | new Feature(PackageManager.FEATURE_CAMERA_FLASH, false), |
| 102 | new Feature(PackageManager.FEATURE_LIVE_WALLPAPER, false), |
Dan Morrill | 5df275b | 2010-08-11 12:19:19 -0700 | [diff] [blame] | 103 | new Feature(PackageManager.FEATURE_SENSOR_LIGHT, false), |
| 104 | new Feature(PackageManager.FEATURE_SENSOR_PROXIMITY, false), |
| 105 | new Feature(PackageManager.FEATURE_TELEPHONY, false), |
| 106 | new Feature(PackageManager.FEATURE_TELEPHONY_CDMA, false), |
| 107 | new Feature(PackageManager.FEATURE_TELEPHONY_GSM, false), |
Dan Morrill | 71351d8 | 2010-10-20 15:26:00 -0700 | [diff] [blame] | 108 | }; |
| 109 | |
Dan Morrill | 71351d8 | 2010-10-20 15:26:00 -0700 | [diff] [blame] | 110 | public static final Feature[] ALL_FROYO_FEATURES = { |
| 111 | new Feature("android.hardware.bluetooth", true), |
| 112 | new Feature("android.hardware.location", true), |
| 113 | new Feature("android.hardware.location.gps", true), |
| 114 | new Feature("android.hardware.location.network", true), |
| 115 | new Feature("android.hardware.microphone", true), |
| 116 | new Feature("android.hardware.sensor.accelerometer", true), |
| 117 | new Feature("android.hardware.sensor.compass", true), |
| 118 | new Feature("android.hardware.touchscreen", true), |
| 119 | new Feature("android.hardware.touchscreen.multitouch", false), |
| 120 | new Feature("android.hardware.touchscreen.multitouch.distinct", false), |
| 121 | new Feature("android.hardware.wifi", false), |
Dan Morrill | 5df275b | 2010-08-11 12:19:19 -0700 | [diff] [blame] | 122 | }; |
| 123 | |
Reena Lee | f8451ed | 2011-01-27 17:34:17 -0800 | [diff] [blame] | 124 | public static final Feature[] ALL_GINGERBREAD_FEATURES = { |
Brian Muramatsu | d8d37a4 | 2011-07-07 14:11:26 -0700 | [diff] [blame] | 125 | // Required features in prior releases that became optional in GB |
| 126 | new Feature("android.hardware.bluetooth", false), |
| 127 | new Feature("android.hardware.camera", false), |
| 128 | new Feature("android.hardware.location.gps", false), |
| 129 | new Feature("android.hardware.microphone", false), |
| 130 | new Feature("android.hardware.sensor.accelerometer", false), |
| 131 | new Feature("android.hardware.sensor.compass", false), |
| 132 | |
| 133 | // New features in GB |
Reena Lee | f8451ed | 2011-01-27 17:34:17 -0800 | [diff] [blame] | 134 | new Feature("android.hardware.audio.low_latency", false), |
| 135 | new Feature("android.hardware.camera.front", false), |
| 136 | new Feature("android.hardware.nfc", false), |
| 137 | new Feature("android.hardware.sensor.barometer", false), |
| 138 | new Feature("android.hardware.sensor.gyroscope", false), |
| 139 | new Feature("android.hardware.touchscreen.multitouch.jazzhand", false), |
| 140 | new Feature("android.software.sip", false), |
| 141 | new Feature("android.software.sip.voip", false), |
| 142 | }; |
| 143 | |
Brian Muramatsu | fc13382 | 2011-07-27 11:16:29 -0700 | [diff] [blame] | 144 | public static final Feature[] ALL_GINGERBREAD_MR1_FEATURES = { |
| 145 | new Feature("android.hardware.usb.accessory", false), |
| 146 | }; |
| 147 | |
Mac_Wang | 2e9193f | 2011-03-10 14:06:58 +0800 | [diff] [blame] | 148 | public static final Feature[] ALL_HONEYCOMB_FEATURES = { |
Brian Muramatsu | 30e241c | 2011-08-01 16:07:47 -0700 | [diff] [blame] | 149 | // Required features in prior releases that became optional in HC |
| 150 | new Feature("android.hardware.touchscreen", false), |
| 151 | |
Mac_Wang | 2e9193f | 2011-03-10 14:06:58 +0800 | [diff] [blame] | 152 | new Feature("android.hardware.faketouch", true), |
| 153 | }; |
| 154 | |
Brian Muramatsu | 34317ff | 2011-06-06 14:22:49 -0700 | [diff] [blame] | 155 | public static final Feature[] ALL_HONEYCOMB_MR1_FEATURES = { |
Brian Muramatsu | 677fe34 | 2011-07-15 10:46:28 -0700 | [diff] [blame] | 156 | new Feature("android.hardware.usb.host", false), |
Kent Cheng | 5c0b5d8 | 2013-08-07 18:13:26 +0800 | [diff] [blame] | 157 | new Feature("android.hardware.usb.accessory", false), |
Brian Muramatsu | 34317ff | 2011-06-06 14:22:49 -0700 | [diff] [blame] | 158 | }; |
| 159 | |
Brian Muramatsu | 177bac5 | 2011-07-12 18:28:18 -0700 | [diff] [blame] | 160 | public static final Feature[] ALL_HONEYCOMB_MR2_FEATURES = { |
| 161 | new Feature("android.hardware.faketouch.multitouch.distinct", false), |
| 162 | new Feature("android.hardware.faketouch.multitouch.jazzhand", false), |
| 163 | new Feature("android.hardware.screen.landscape", false), |
| 164 | new Feature("android.hardware.screen.portrait", false), |
| 165 | }; |
| 166 | |
Brian Muramatsu | 278962c | 2012-01-19 17:37:38 -0800 | [diff] [blame] | 167 | public static final Feature[] ALL_ICE_CREAM_SANDWICH_FEATURES = { |
| 168 | new Feature(PackageManager.FEATURE_WIFI_DIRECT, false), |
| 169 | }; |
| 170 | |
Leo Liao | 0801e93 | 2013-01-30 10:23:14 +0800 | [diff] [blame] | 171 | public static final Feature[] ALL_JELLY_BEAN_FEATURES = { |
| 172 | new Feature(PackageManager.FEATURE_TELEVISION, false), |
| 173 | }; |
| 174 | |
Guru Nagarajan | dcaa4d5 | 2013-07-22 13:48:42 -0700 | [diff] [blame] | 175 | public static final Feature[] ALL_JELLY_BEAN_MR2_FEATURES = { |
| 176 | new Feature("android.software.app_widgets", false), |
Guru Nagarajan | d8716c9 | 2013-07-26 15:55:54 -0700 | [diff] [blame] | 177 | new Feature("android.software.input_methods", false), |
Guru Nagarajan | dcaa4d5 | 2013-07-22 13:48:42 -0700 | [diff] [blame] | 178 | new Feature("android.software.home_screen", false), |
| 179 | new Feature("android.hardware.bluetooth_le", false), |
Guru Nagarajan | d8716c9 | 2013-07-26 15:55:54 -0700 | [diff] [blame] | 180 | new Feature("android.hardware.camera.any", false), |
Guru Nagarajan | dcaa4d5 | 2013-07-22 13:48:42 -0700 | [diff] [blame] | 181 | }; |
| 182 | |
Martijn Coenen | 9f342d3 | 2013-10-25 13:59:50 -0700 | [diff] [blame] | 183 | public static final Feature[] ALL_KITKAT_FEATURES = { |
| 184 | new Feature(PackageManager.FEATURE_NFC_HOST_CARD_EMULATION, false), |
Madan Ankapura | d58c029 | 2013-11-03 23:42:34 -0800 | [diff] [blame] | 185 | new Feature(PackageManager.FEATURE_CONSUMER_IR, false), |
| 186 | new Feature(PackageManager.FEATURE_DEVICE_ADMIN, false), |
| 187 | new Feature(PackageManager.FEATURE_SENSOR_STEP_COUNTER, false), |
| 188 | new Feature(PackageManager.FEATURE_SENSOR_STEP_DETECTOR, false), |
Martijn Coenen | 9f342d3 | 2013-10-25 13:59:50 -0700 | [diff] [blame] | 189 | }; |
| 190 | |
Vinod Krishnan | 20d6725 | 2014-04-30 11:12:01 -0700 | [diff] [blame] | 191 | public static final Feature[] ALL_KITKAT_WATCH_FEATURES = { |
| 192 | new Feature(PackageManager.FEATURE_SENSOR_HEART_RATE, false), |
| 193 | }; |
| 194 | |
Vinod Krishnan | 9a277c8 | 2014-08-19 14:17:39 -0700 | [diff] [blame^] | 195 | public static final Feature[] ALL_LMP_FEATURES = { |
| 196 | new Feature(PackageManager.FEATURE_SENSOR_HEART_RATE_ECG, false), |
| 197 | }; |
| 198 | |
Dan Morrill | 5df275b | 2010-08-11 12:19:19 -0700 | [diff] [blame] | 199 | @Override |
| 200 | public void onCreate(Bundle savedInstanceState) { |
| 201 | super.onCreate(savedInstanceState); |
| 202 | setContentView(R.layout.fs_main); |
Brian Muramatsu | de69444 | 2011-03-09 14:13:01 -0800 | [diff] [blame] | 203 | setPassFailButtonClickListeners(); |
Dan Morrill | 71351d8 | 2010-10-20 15:26:00 -0700 | [diff] [blame] | 204 | setInfoResources(R.string.feature_summary, R.string.feature_summary_info, R.layout.fs_info); |
Dan Morrill | 5df275b | 2010-08-11 12:19:19 -0700 | [diff] [blame] | 205 | |
Dan Morrill | 71351d8 | 2010-10-20 15:26:00 -0700 | [diff] [blame] | 206 | // some values used to detect warn-able conditions involving multiple |
| 207 | // features |
Dan Morrill | 5df275b | 2010-08-11 12:19:19 -0700 | [diff] [blame] | 208 | boolean hasWifi = false; |
| 209 | boolean hasTelephony = false; |
| 210 | boolean hasIllegalFeature = false; |
| 211 | |
Dan Morrill | 71351d8 | 2010-10-20 15:26:00 -0700 | [diff] [blame] | 212 | // get list of all features device thinks it has, & store in a HashMap |
| 213 | // for fast lookups |
Dan Morrill | 5df275b | 2010-08-11 12:19:19 -0700 | [diff] [blame] | 214 | HashMap<String, String> actualFeatures = new HashMap<String, String>(); |
| 215 | for (FeatureInfo fi : getPackageManager().getSystemAvailableFeatures()) { |
| 216 | actualFeatures.put(fi.name, fi.name); |
| 217 | } |
| 218 | |
| 219 | // data structure that the SimpleAdapter will use to populate ListView |
| 220 | ArrayList<HashMap<String, Object>> listViewData = new ArrayList<HashMap<String, Object>>(); |
| 221 | |
| 222 | // roll over all known features & check whether device reports them |
| 223 | boolean present = false; |
| 224 | int statusIcon; |
Brian Muramatsu | d8d37a4 | 2011-07-07 14:11:26 -0700 | [diff] [blame] | 225 | Set<Feature> features = new LinkedHashSet<Feature>(); |
| 226 | |
| 227 | // add features from latest to last so that the latest requirements are put in the set first |
Dan Morrill | 71351d8 | 2010-10-20 15:26:00 -0700 | [diff] [blame] | 228 | int apiVersion = Build.VERSION.SDK_INT; |
Vinod Krishnan | 9a277c8 | 2014-08-19 14:17:39 -0700 | [diff] [blame^] | 229 | if (apiVersion >= Build.VERSION_CODES.L) { |
| 230 | Collections.addAll(features, ALL_LMP_FEATURES); |
| 231 | } |
Vinod Krishnan | 20d6725 | 2014-04-30 11:12:01 -0700 | [diff] [blame] | 232 | if (apiVersion >= Build.VERSION_CODES.KITKAT_WATCH) { |
| 233 | Collections.addAll(features, ALL_KITKAT_WATCH_FEATURES); |
| 234 | } |
Martijn Coenen | 9f342d3 | 2013-10-25 13:59:50 -0700 | [diff] [blame] | 235 | if (apiVersion >= Build.VERSION_CODES.KITKAT) { |
| 236 | Collections.addAll(features, ALL_KITKAT_FEATURES); |
| 237 | } |
Guru Nagarajan | dcaa4d5 | 2013-07-22 13:48:42 -0700 | [diff] [blame] | 238 | if (apiVersion >= Build.VERSION_CODES.JELLY_BEAN_MR2) { |
Guru Nagarajan | 89cd939 | 2013-07-26 15:31:11 -0700 | [diff] [blame] | 239 | Collections.addAll(features, ALL_JELLY_BEAN_MR2_FEATURES); |
Guru Nagarajan | dcaa4d5 | 2013-07-22 13:48:42 -0700 | [diff] [blame] | 240 | } |
Leo Liao | 0801e93 | 2013-01-30 10:23:14 +0800 | [diff] [blame] | 241 | if (apiVersion >= Build.VERSION_CODES.JELLY_BEAN) { |
| 242 | Collections.addAll(features, ALL_JELLY_BEAN_FEATURES); |
| 243 | } |
Brian Muramatsu | 278962c | 2012-01-19 17:37:38 -0800 | [diff] [blame] | 244 | if (apiVersion >= Build.VERSION_CODES.ICE_CREAM_SANDWICH) { |
| 245 | Collections.addAll(features, ALL_ICE_CREAM_SANDWICH_FEATURES); |
| 246 | } |
Brian Muramatsu | 177bac5 | 2011-07-12 18:28:18 -0700 | [diff] [blame] | 247 | if (apiVersion >= Build.VERSION_CODES.HONEYCOMB_MR2) { |
| 248 | Collections.addAll(features, ALL_HONEYCOMB_MR2_FEATURES); |
| 249 | } |
Brian Muramatsu | 23c84d9 | 2011-07-12 17:39:28 -0700 | [diff] [blame] | 250 | if (apiVersion >= Build.VERSION_CODES.HONEYCOMB_MR1) { |
| 251 | Collections.addAll(features, ALL_HONEYCOMB_MR1_FEATURES); |
Reena Lee | f8451ed | 2011-01-27 17:34:17 -0800 | [diff] [blame] | 252 | } |
Mac_Wang | 2e9193f | 2011-03-10 14:06:58 +0800 | [diff] [blame] | 253 | if (apiVersion >= Build.VERSION_CODES.HONEYCOMB) { |
| 254 | Collections.addAll(features, ALL_HONEYCOMB_FEATURES); |
| 255 | } |
Brian Muramatsu | fc13382 | 2011-07-27 11:16:29 -0700 | [diff] [blame] | 256 | if (apiVersion >= Build.VERSION_CODES.GINGERBREAD_MR1) { |
| 257 | Collections.addAll(features, ALL_GINGERBREAD_MR1_FEATURES); |
| 258 | } |
Dan Morrill | 5df275b | 2010-08-11 12:19:19 -0700 | [diff] [blame] | 259 | if (apiVersion >= Build.VERSION_CODES.GINGERBREAD) { |
| 260 | Collections.addAll(features, ALL_GINGERBREAD_FEATURES); |
| 261 | } |
Dan Morrill | 5df275b | 2010-08-11 12:19:19 -0700 | [diff] [blame] | 262 | if (apiVersion >= Build.VERSION_CODES.FROYO) { |
| 263 | Collections.addAll(features, ALL_FROYO_FEATURES); |
Dan Morrill | 71351d8 | 2010-10-20 15:26:00 -0700 | [diff] [blame] | 264 | } |
Brian Muramatsu | d8d37a4 | 2011-07-07 14:11:26 -0700 | [diff] [blame] | 265 | if (apiVersion >= Build.VERSION_CODES.ECLAIR_MR1) { |
| 266 | Collections.addAll(features, ALL_ECLAIR_FEATURES); |
Brian Muramatsu | 34317ff | 2011-06-06 14:22:49 -0700 | [diff] [blame] | 267 | } |
Dan Morrill | 5df275b | 2010-08-11 12:19:19 -0700 | [diff] [blame] | 268 | for (Feature f : features) { |
| 269 | HashMap<String, Object> row = new HashMap<String, Object>(); |
| 270 | listViewData.add(row); |
| 271 | present = actualFeatures.containsKey(f.name); |
| 272 | if (present) { |
| 273 | // device reports it -- yay! set the happy icon |
| 274 | hasWifi = hasWifi || PackageManager.FEATURE_WIFI.equals(f.name); |
| 275 | hasTelephony = hasTelephony || PackageManager.FEATURE_TELEPHONY.equals(f.name); |
| 276 | statusIcon = R.drawable.fs_good; |
| 277 | actualFeatures.remove(f.name); |
| 278 | } else if (!present && f.required) { |
Dan Morrill | 71351d8 | 2010-10-20 15:26:00 -0700 | [diff] [blame] | 279 | // it's required, but device doesn't report it. Boo, set the |
| 280 | // bogus icon |
Dan Morrill | 5df275b | 2010-08-11 12:19:19 -0700 | [diff] [blame] | 281 | statusIcon = R.drawable.fs_error; |
| 282 | } else { |
Dan Morrill | 71351d8 | 2010-10-20 15:26:00 -0700 | [diff] [blame] | 283 | // device doesn't report it, but it's not req'd, so can't tell |
| 284 | // if there's a problem |
Dan Morrill | 5df275b | 2010-08-11 12:19:19 -0700 | [diff] [blame] | 285 | statusIcon = R.drawable.fs_indeterminate; |
| 286 | } |
| 287 | row.put("feature", f.name); |
| 288 | row.put("icon", statusIcon); |
| 289 | } |
| 290 | |
| 291 | // now roll over any remaining features (which are non-standard) |
| 292 | for (String feature : actualFeatures.keySet()) { |
| 293 | if (feature == null || "".equals(feature)) |
| 294 | continue; |
| 295 | HashMap<String, Object> row = new HashMap<String, Object>(); |
| 296 | listViewData.add(row); |
| 297 | row.put("feature", feature); |
| 298 | if (feature.startsWith("android")) { // intentionally not "android." |
Dan Morrill | 71351d8 | 2010-10-20 15:26:00 -0700 | [diff] [blame] | 299 | // sorry, you're not allowed to squat in the official namespace; |
| 300 | // set bogus icon |
Dan Morrill | 5df275b | 2010-08-11 12:19:19 -0700 | [diff] [blame] | 301 | row.put("icon", R.drawable.fs_error); |
| 302 | hasIllegalFeature = true; |
| 303 | } else { |
| 304 | // non-standard features are okay, but flag them just in case |
| 305 | row.put("icon", R.drawable.fs_warning); |
| 306 | } |
| 307 | } |
| 308 | |
Dan Morrill | 71351d8 | 2010-10-20 15:26:00 -0700 | [diff] [blame] | 309 | // sort the ListView's data to group by icon type, for easier reading by |
| 310 | // humans |
Dan Morrill | 5df275b | 2010-08-11 12:19:19 -0700 | [diff] [blame] | 311 | final HashMap<Integer, Integer> idMap = new HashMap<Integer, Integer>(); |
| 312 | idMap.put(R.drawable.fs_error, 0); |
| 313 | idMap.put(R.drawable.fs_warning, 1); |
| 314 | idMap.put(R.drawable.fs_indeterminate, 2); |
| 315 | idMap.put(R.drawable.fs_good, 3); |
| 316 | Collections.sort(listViewData, new Comparator<HashMap<String, Object>>() { |
| 317 | public int compare(HashMap<String, Object> left, HashMap<String, Object> right) { |
Brian Muramatsu | e118187 | 2010-08-20 12:59:39 -0700 | [diff] [blame] | 318 | int leftId = idMap.get(left.get("icon")); |
| 319 | int rightId = idMap.get(right.get("icon")); |
Dan Morrill | 5df275b | 2010-08-11 12:19:19 -0700 | [diff] [blame] | 320 | if (leftId == rightId) { |
| 321 | return ((String) left.get("feature")).compareTo((String) right.get("feature")); |
| 322 | } |
| 323 | if (leftId < rightId) |
| 324 | return -1; |
| 325 | return 1; |
| 326 | } |
| 327 | }); |
| 328 | |
| 329 | // Set up the SimpleAdapter used to populate the ListView |
| 330 | SimpleAdapter adapter = new SimpleAdapter(this, listViewData, R.layout.fs_row, |
Dan Morrill | 71351d8 | 2010-10-20 15:26:00 -0700 | [diff] [blame] | 331 | new String[] { |
| 332 | "feature", "icon" |
| 333 | }, new int[] { |
| 334 | R.id.fs_feature, R.id.fs_icon |
| 335 | }); |
Dan Morrill | 5df275b | 2010-08-11 12:19:19 -0700 | [diff] [blame] | 336 | adapter.setViewBinder(new SimpleAdapter.ViewBinder() { |
| 337 | public boolean setViewValue(View view, Object data, String repr) { |
| 338 | try { |
| 339 | if (view instanceof ImageView) { |
| 340 | ((ImageView) view).setImageResource((Integer) data); |
| 341 | } else if (view instanceof TextView) { |
| 342 | ((TextView) view).setText((String) data); |
| 343 | } else { |
| 344 | return false; |
| 345 | } |
| 346 | return true; |
| 347 | } catch (ClassCastException e) { |
| 348 | return false; |
| 349 | } |
| 350 | } |
| 351 | }); |
| 352 | setListAdapter(adapter); |
| 353 | |
Dan Morrill | 71351d8 | 2010-10-20 15:26:00 -0700 | [diff] [blame] | 354 | // finally, check for our second-order error cases and set warning text |
| 355 | // if necessary |
Dan Morrill | 5df275b | 2010-08-11 12:19:19 -0700 | [diff] [blame] | 356 | StringBuffer sb = new StringBuffer(); |
| 357 | if (hasIllegalFeature) { |
| 358 | sb.append(getResources().getString(R.string.fs_disallowed)).append("\n"); |
| 359 | } |
| 360 | if (!hasWifi && !hasTelephony) { |
| 361 | sb.append(getResources().getString(R.string.fs_missing_wifi_telephony)).append("\n"); |
| 362 | } |
Dan Morrill | 71351d8 | 2010-10-20 15:26:00 -0700 | [diff] [blame] | 363 | String warnings = sb.toString().trim(); |
| 364 | if (warnings == null || "".equals(warnings)) { |
| 365 | ((TextView) (findViewById(R.id.fs_warnings))).setVisibility(View.GONE); |
| 366 | } else { |
| 367 | ((TextView) (findViewById(R.id.fs_warnings))).setText(warnings); |
| 368 | } |
Dan Morrill | 5df275b | 2010-08-11 12:19:19 -0700 | [diff] [blame] | 369 | } |
| 370 | } |