DeviceInfoSettings.java revision 39b467482d1bf256a111c757e9b7621c6f523271
1afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project/*
2afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project * Copyright (C) 2008 The Android Open Source Project
3afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project *
4afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License");
5afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project * you may not use this file except in compliance with the License.
6afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project * You may obtain a copy of the License at
7afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project *
8afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project *      http://www.apache.org/licenses/LICENSE-2.0
9afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project *
10afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project * Unless required by applicable law or agreed to in writing, software
11afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS,
12afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project * See the License for the specific language governing permissions and
14afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project * limitations under the License.
15afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project */
16afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
17afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Projectpackage com.android.settings;
18afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
19d79934731c8d33f6fc63b21c120b9ffba5d06f54Amith Yamasaniimport android.app.Activity;
20caefa9b5f03b595b81729407e4123fee18a4342cDianne Hackbornimport android.content.Context;
21afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Projectimport android.content.Intent;
22b42573d0e6870b026110ece22f13dc15452d507cRajat Dewanimport android.content.pm.ApplicationInfo;
23b42573d0e6870b026110ece22f13dc15452d507cRajat Dewanimport android.content.pm.PackageManager;
24b42573d0e6870b026110ece22f13dc15452d507cRajat Dewanimport android.content.pm.ResolveInfo;
25afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Projectimport android.os.Build;
26afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Projectimport android.os.Bundle;
279d4b5486198a16053e5fdeba6b34268104faead2Amit Mahajanimport android.os.PersistableBundle;
28b4e84f34e095ad423b854f66f75aeb36514d49f0Stephen Smalleyimport android.os.SELinux;
294749fcf762de0e34ac28f927501d42555062c521Dianne Hackbornimport android.os.SystemClock;
30afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Projectimport android.os.SystemProperties;
316c088cb221bb43d47be065387231ffa7192ff211Julia Reynoldsimport android.os.UserManager;
32b2385ea46286933add8ea3fb86db7870fe294334Fabrice Di Meglioimport android.provider.SearchIndexableResource;
333daa259d8042b614539cc307c79ef07b526adb0dJeff Sharkeyimport android.provider.Settings;
3439b467482d1bf256a111c757e9b7621c6f523271Jason Monkimport android.support.v7.preference.Preference;
3539b467482d1bf256a111c757e9b7621c6f523271Jason Monkimport android.support.v7.preference.PreferenceGroup;
369d4b5486198a16053e5fdeba6b34268104faead2Amit Mahajanimport android.telephony.CarrierConfigManager;
37b42573d0e6870b026110ece22f13dc15452d507cRajat Dewanimport android.text.TextUtils;
38ffe701dc0e52ee95bf6c54291ed1b574d389019cChristopher Tateimport android.text.format.DateFormat;
39afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Projectimport android.util.Log;
40caefa9b5f03b595b81729407e4123fee18a4342cDianne Hackbornimport android.widget.Toast;
41ffe701dc0e52ee95bf6c54291ed1b574d389019cChristopher Tate
428a963babe2e36b7a41f77b8d2598c97658196e58Chris Wrenimport com.android.internal.logging.MetricsLogger;
43b2385ea46286933add8ea3fb86db7870fe294334Fabrice Di Meglioimport com.android.settings.search.BaseSearchIndexProvider;
442ec78636f75964a48be5e95fe9b7e71f2270f917Fabrice Di Meglioimport com.android.settings.search.Index;
45b2385ea46286933add8ea3fb86db7870fe294334Fabrice Di Meglioimport com.android.settings.search.Indexable;
46afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
47afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Projectimport java.io.BufferedReader;
48afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Projectimport java.io.FileReader;
49afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Projectimport java.io.IOException;
50ffe701dc0e52ee95bf6c54291ed1b574d389019cChristopher Tateimport java.text.ParseException;
51ffe701dc0e52ee95bf6c54291ed1b574d389019cChristopher Tateimport java.text.SimpleDateFormat;
52b2385ea46286933add8ea3fb86db7870fe294334Fabrice Di Meglioimport java.util.ArrayList;
53b2385ea46286933add8ea3fb86db7870fe294334Fabrice Di Meglioimport java.util.Arrays;
54ffe701dc0e52ee95bf6c54291ed1b574d389019cChristopher Tateimport java.util.Date;
55b42573d0e6870b026110ece22f13dc15452d507cRajat Dewanimport java.util.List;
56ffe701dc0e52ee95bf6c54291ed1b574d389019cChristopher Tateimport java.util.Locale;
57afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Projectimport java.util.regex.Matcher;
58afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Projectimport java.util.regex.Pattern;
59afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
60b2385ea46286933add8ea3fb86db7870fe294334Fabrice Di Megliopublic class DeviceInfoSettings extends SettingsPreferenceFragment implements Indexable {
61c06d4c48a9455d6018f2d793c6b8f211f1131055Amith Yamasani
62362bd107a11e4cb74c53e8058fe0dfaf9baac65fGilles Debunne    private static final String LOG_TAG = "DeviceInfoSettings";
632397a7391e2ba9434ee89345c1d3a47948d8f226Amith Yamasani    private static final String FILENAME_PROC_VERSION = "/proc/version";
642397a7391e2ba9434ee89345c1d3a47948d8f226Amith Yamasani    private static final String FILENAME_MSV = "/sys/board_properties/soc/msv";
652397a7391e2ba9434ee89345c1d3a47948d8f226Amith Yamasani
665adcb3d353b066a056b86ae66946a06a251ff1fbZachary Kuznia    private static final String KEY_MANUAL = "manual";
67a6dbaea2dacaaef7c91f89aae8d5f1ed7580b893Brian Muramatsu    private static final String KEY_REGULATORY_INFO = "regulatory_info";
68afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    private static final String KEY_SYSTEM_UPDATE_SETTINGS = "system_update_settings";
69a40fb23734cc5d5ac6e69a060cbb488269ad8af3Wink Saville    private static final String PROPERTY_URL_SAFETYLEGAL = "ro.url.safetylegal";
70b4e84f34e095ad423b854f66f75aeb36514d49f0Stephen Smalley    private static final String PROPERTY_SELINUX_STATUS = "ro.build.selinux";
71c06d4c48a9455d6018f2d793c6b8f211f1131055Amith Yamasani    private static final String KEY_KERNEL_VERSION = "kernel_version";
72c06d4c48a9455d6018f2d793c6b8f211f1131055Amith Yamasani    private static final String KEY_BUILD_NUMBER = "build_number";
73c06d4c48a9455d6018f2d793c6b8f211f1131055Amith Yamasani    private static final String KEY_DEVICE_MODEL = "device_model";
74b4e84f34e095ad423b854f66f75aeb36514d49f0Stephen Smalley    private static final String KEY_SELINUX_STATUS = "selinux_status";
75c06d4c48a9455d6018f2d793c6b8f211f1131055Amith Yamasani    private static final String KEY_BASEBAND_VERSION = "baseband_version";
76c06d4c48a9455d6018f2d793c6b8f211f1131055Amith Yamasani    private static final String KEY_FIRMWARE_VERSION = "firmware_version";
77b9a8e277d94827a16e7366d60914de34533b23a6Dianne Hackborn    private static final String KEY_SECURITY_PATCH = "security_patch";
783feacdf3969800d6c53c6ca6f8ced2f8fc637f7fMeng Hu    private static final String KEY_UPDATE_SETTING = "additional_system_update_settings";
79b0b45c02ec73c87f78a8358a7e98747bd96ec103John Wang    private static final String KEY_EQUIPMENT_ID = "fcc_equipment_id";
80b0b45c02ec73c87f78a8358a7e98747bd96ec103John Wang    private static final String PROPERTY_EQUIPMENT_ID = "ro.ril.fccid";
81b42573d0e6870b026110ece22f13dc15452d507cRajat Dewan    private static final String KEY_DEVICE_FEEDBACK = "device_feedback";
82b2385ea46286933add8ea3fb86db7870fe294334Fabrice Di Meglio    private static final String KEY_SAFETY_LEGAL = "safetylegal";
832fc2ba11fedd529340eefc042d3a00ef6f70e7b6Freeman Ng
84d6a24d505a237c26a280cfbeb5a3bedaca8a3f7dDianne Hackborn    static final int TAPS_TO_BE_A_DEVELOPER = 7;
85d6a24d505a237c26a280cfbeb5a3bedaca8a3f7dDianne Hackborn
864749fcf762de0e34ac28f927501d42555062c521Dianne Hackborn    long[] mHits = new long[3];
87caefa9b5f03b595b81729407e4123fee18a4342cDianne Hackborn    int mDevHitCountdown;
88caefa9b5f03b595b81729407e4123fee18a4342cDianne Hackborn    Toast mDevHitToast;
892fc2ba11fedd529340eefc042d3a00ef6f70e7b6Freeman Ng
9044879a387a6be6b93cdcc8894227d68af7dbbb1aXiaohui Chen    private UserManager mUm;
9144879a387a6be6b93cdcc8894227d68af7dbbb1aXiaohui Chen
92afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    @Override
938a963babe2e36b7a41f77b8d2598c97658196e58Chris Wren    protected int getMetricsCategory() {
948a963babe2e36b7a41f77b8d2598c97658196e58Chris Wren        return MetricsLogger.DEVICEINFO;
958a963babe2e36b7a41f77b8d2598c97658196e58Chris Wren    }
968a963babe2e36b7a41f77b8d2598c97658196e58Chris Wren
978a963babe2e36b7a41f77b8d2598c97658196e58Chris Wren    @Override
9823acc2bb8af7da000d72a8c1d8c28a2792200348Jason Monk    protected int getHelpResource() {
9923acc2bb8af7da000d72a8c1d8c28a2792200348Jason Monk        return R.string.help_uri_about;
10023acc2bb8af7da000d72a8c1d8c28a2792200348Jason Monk    }
10123acc2bb8af7da000d72a8c1d8c28a2792200348Jason Monk
10223acc2bb8af7da000d72a8c1d8c28a2792200348Jason Monk    @Override
103d79934731c8d33f6fc63b21c120b9ffba5d06f54Amith Yamasani    public void onCreate(Bundle icicle) {
104afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        super.onCreate(icicle);
10544879a387a6be6b93cdcc8894227d68af7dbbb1aXiaohui Chen        mUm = UserManager.get(getActivity());
1062fc2ba11fedd529340eefc042d3a00ef6f70e7b6Freeman Ng
107afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        addPreferencesFromResource(R.xml.device_info_settings);
1082fc2ba11fedd529340eefc042d3a00ef6f70e7b6Freeman Ng
109c06d4c48a9455d6018f2d793c6b8f211f1131055Amith Yamasani        setStringSummary(KEY_FIRMWARE_VERSION, Build.VERSION.RELEASE);
110c06d4c48a9455d6018f2d793c6b8f211f1131055Amith Yamasani        findPreference(KEY_FIRMWARE_VERSION).setEnabled(true);
111b9a8e277d94827a16e7366d60914de34533b23a6Dianne Hackborn        String patch = Build.VERSION.SECURITY_PATCH;
112b9a8e277d94827a16e7366d60914de34533b23a6Dianne Hackborn        if (!"".equals(patch)) {
113ffe701dc0e52ee95bf6c54291ed1b574d389019cChristopher Tate            try {
114ffe701dc0e52ee95bf6c54291ed1b574d389019cChristopher Tate                SimpleDateFormat template = new SimpleDateFormat("yyyy-MM-dd");
115ffe701dc0e52ee95bf6c54291ed1b574d389019cChristopher Tate                Date patchDate = template.parse(patch);
116ffe701dc0e52ee95bf6c54291ed1b574d389019cChristopher Tate                String format = DateFormat.getBestDateTimePattern(Locale.getDefault(), "dMMMMyyyy");
117ffe701dc0e52ee95bf6c54291ed1b574d389019cChristopher Tate                patch = DateFormat.format(format, patchDate).toString();
118ffe701dc0e52ee95bf6c54291ed1b574d389019cChristopher Tate            } catch (ParseException e) {
119ffe701dc0e52ee95bf6c54291ed1b574d389019cChristopher Tate                // broken parse; fall through and use the raw string
120ffe701dc0e52ee95bf6c54291ed1b574d389019cChristopher Tate            }
121b9a8e277d94827a16e7366d60914de34533b23a6Dianne Hackborn            setStringSummary(KEY_SECURITY_PATCH, patch);
122b9a8e277d94827a16e7366d60914de34533b23a6Dianne Hackborn        } else {
123b9a8e277d94827a16e7366d60914de34533b23a6Dianne Hackborn            getPreferenceScreen().removePreference(findPreference(KEY_SECURITY_PATCH));
124b9a8e277d94827a16e7366d60914de34533b23a6Dianne Hackborn
125b9a8e277d94827a16e7366d60914de34533b23a6Dianne Hackborn        }
126c06d4c48a9455d6018f2d793c6b8f211f1131055Amith Yamasani        setValueSummary(KEY_BASEBAND_VERSION, "gsm.version.baseband");
1272397a7391e2ba9434ee89345c1d3a47948d8f226Amith Yamasani        setStringSummary(KEY_DEVICE_MODEL, Build.MODEL + getMsvSuffix());
128b0b45c02ec73c87f78a8358a7e98747bd96ec103John Wang        setValueSummary(KEY_EQUIPMENT_ID, PROPERTY_EQUIPMENT_ID);
129b0b45c02ec73c87f78a8358a7e98747bd96ec103John Wang        setStringSummary(KEY_DEVICE_MODEL, Build.MODEL);
130c06d4c48a9455d6018f2d793c6b8f211f1131055Amith Yamasani        setStringSummary(KEY_BUILD_NUMBER, Build.DISPLAY);
131caefa9b5f03b595b81729407e4123fee18a4342cDianne Hackborn        findPreference(KEY_BUILD_NUMBER).setEnabled(true);
132c06d4c48a9455d6018f2d793c6b8f211f1131055Amith Yamasani        findPreference(KEY_KERNEL_VERSION).setSummary(getFormattedKernelVersion());
133afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
134b4e84f34e095ad423b854f66f75aeb36514d49f0Stephen Smalley        if (!SELinux.isSELinuxEnabled()) {
135b4e84f34e095ad423b854f66f75aeb36514d49f0Stephen Smalley            String status = getResources().getString(R.string.selinux_status_disabled);
136b4e84f34e095ad423b854f66f75aeb36514d49f0Stephen Smalley            setStringSummary(KEY_SELINUX_STATUS, status);
137b4e84f34e095ad423b854f66f75aeb36514d49f0Stephen Smalley        } else if (!SELinux.isSELinuxEnforced()) {
138b4e84f34e095ad423b854f66f75aeb36514d49f0Stephen Smalley            String status = getResources().getString(R.string.selinux_status_permissive);
139b4e84f34e095ad423b854f66f75aeb36514d49f0Stephen Smalley            setStringSummary(KEY_SELINUX_STATUS, status);
140b4e84f34e095ad423b854f66f75aeb36514d49f0Stephen Smalley        }
141b4e84f34e095ad423b854f66f75aeb36514d49f0Stephen Smalley
142b4e84f34e095ad423b854f66f75aeb36514d49f0Stephen Smalley        // Remove selinux information if property is not present
143b4e84f34e095ad423b854f66f75aeb36514d49f0Stephen Smalley        removePreferenceIfPropertyMissing(getPreferenceScreen(), KEY_SELINUX_STATUS,
144b4e84f34e095ad423b854f66f75aeb36514d49f0Stephen Smalley                PROPERTY_SELINUX_STATUS);
145b4e84f34e095ad423b854f66f75aeb36514d49f0Stephen Smalley
146a40fb23734cc5d5ac6e69a060cbb488269ad8af3Wink Saville        // Remove Safety information preference if PROPERTY_URL_SAFETYLEGAL is not set
147b2385ea46286933add8ea3fb86db7870fe294334Fabrice Di Meglio        removePreferenceIfPropertyMissing(getPreferenceScreen(), KEY_SAFETY_LEGAL,
148a40fb23734cc5d5ac6e69a060cbb488269ad8af3Wink Saville                PROPERTY_URL_SAFETYLEGAL);
149a40fb23734cc5d5ac6e69a060cbb488269ad8af3Wink Saville
150b0b45c02ec73c87f78a8358a7e98747bd96ec103John Wang        // Remove Equipment id preference if FCC ID is not set by RIL
151b0b45c02ec73c87f78a8358a7e98747bd96ec103John Wang        removePreferenceIfPropertyMissing(getPreferenceScreen(), KEY_EQUIPMENT_ID,
152b0b45c02ec73c87f78a8358a7e98747bd96ec103John Wang                PROPERTY_EQUIPMENT_ID);
153b0b45c02ec73c87f78a8358a7e98747bd96ec103John Wang
154c06d4c48a9455d6018f2d793c6b8f211f1131055Amith Yamasani        // Remove Baseband version if wifi-only device
1558af88fb8387259e51615709b2d1ea0260f7057fdRobert Greenwalt        if (Utils.isWifiOnly(getActivity())) {
156c06d4c48a9455d6018f2d793c6b8f211f1131055Amith Yamasani            getPreferenceScreen().removePreference(findPreference(KEY_BASEBAND_VERSION));
157c06d4c48a9455d6018f2d793c6b8f211f1131055Amith Yamasani        }
158c06d4c48a9455d6018f2d793c6b8f211f1131055Amith Yamasani
159b42573d0e6870b026110ece22f13dc15452d507cRajat Dewan        // Dont show feedback option if there is no reporter.
160b42573d0e6870b026110ece22f13dc15452d507cRajat Dewan        if (TextUtils.isEmpty(getFeedbackReporterPackage(getActivity()))) {
161b42573d0e6870b026110ece22f13dc15452d507cRajat Dewan            getPreferenceScreen().removePreference(findPreference(KEY_DEVICE_FEEDBACK));
162b42573d0e6870b026110ece22f13dc15452d507cRajat Dewan        }
163b42573d0e6870b026110ece22f13dc15452d507cRajat Dewan
164afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        /*
165afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project         * Settings is a generic app and should not contain any device-specific
166afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project         * info.
167afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project         */
168d79934731c8d33f6fc63b21c120b9ffba5d06f54Amith Yamasani        final Activity act = getActivity();
1692fc2ba11fedd529340eefc042d3a00ef6f70e7b6Freeman Ng
170afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        // These are contained by the root preference screen
171f94023216accd128b06acdc50950e455a60a9c4eJason Monk        PreferenceGroup parentPreference = getPreferenceScreen();
17244879a387a6be6b93cdcc8894227d68af7dbbb1aXiaohui Chen
17344879a387a6be6b93cdcc8894227d68af7dbbb1aXiaohui Chen        if (mUm.isAdminUser()) {
1749627a8ea151c1f27e5e9f34592c7b34fea3101c3Amith Yamasani            Utils.updatePreferenceToSpecificActivityOrRemove(act, parentPreference,
1759627a8ea151c1f27e5e9f34592c7b34fea3101c3Amith Yamasani                    KEY_SYSTEM_UPDATE_SETTINGS,
1769627a8ea151c1f27e5e9f34592c7b34fea3101c3Amith Yamasani                    Utils.UPDATE_PREFERENCE_FLAG_SET_TITLE_TO_MATCHING_ACTIVITY);
1779627a8ea151c1f27e5e9f34592c7b34fea3101c3Amith Yamasani        } else {
1789627a8ea151c1f27e5e9f34592c7b34fea3101c3Amith Yamasani            // Remove for secondary users
1799627a8ea151c1f27e5e9f34592c7b34fea3101c3Amith Yamasani            removePreference(KEY_SYSTEM_UPDATE_SETTINGS);
1809627a8ea151c1f27e5e9f34592c7b34fea3101c3Amith Yamasani        }
1813feacdf3969800d6c53c6ca6f8ced2f8fc637f7fMeng Hu
1823feacdf3969800d6c53c6ca6f8ced2f8fc637f7fMeng Hu        // Read platform settings for additional system update setting
183a6dbaea2dacaaef7c91f89aae8d5f1ed7580b893Brian Muramatsu        removePreferenceIfBoolFalse(KEY_UPDATE_SETTING,
184a6dbaea2dacaaef7c91f89aae8d5f1ed7580b893Brian Muramatsu                R.bool.config_additional_system_update_setting_enable);
185a6dbaea2dacaaef7c91f89aae8d5f1ed7580b893Brian Muramatsu
1865adcb3d353b066a056b86ae66946a06a251ff1fbZachary Kuznia        // Remove manual entry if none present.
1875adcb3d353b066a056b86ae66946a06a251ff1fbZachary Kuznia        removePreferenceIfBoolFalse(KEY_MANUAL, R.bool.config_show_manual);
1885adcb3d353b066a056b86ae66946a06a251ff1fbZachary Kuznia
1893daa259d8042b614539cc307c79ef07b526adb0dJeff Sharkey        // Remove regulatory information if none present.
1903daa259d8042b614539cc307c79ef07b526adb0dJeff Sharkey        final Intent intent = new Intent(Settings.ACTION_SHOW_REGULATORY_INFO);
1913daa259d8042b614539cc307c79ef07b526adb0dJeff Sharkey        if (getPackageManager().queryIntentActivities(intent, 0).isEmpty()) {
1923daa259d8042b614539cc307c79ef07b526adb0dJeff Sharkey            Preference pref = findPreference(KEY_REGULATORY_INFO);
1933daa259d8042b614539cc307c79ef07b526adb0dJeff Sharkey            if (pref != null) {
1943daa259d8042b614539cc307c79ef07b526adb0dJeff Sharkey                getPreferenceScreen().removePreference(pref);
1953daa259d8042b614539cc307c79ef07b526adb0dJeff Sharkey            }
1963daa259d8042b614539cc307c79ef07b526adb0dJeff Sharkey        }
197afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    }
1982fc2ba11fedd529340eefc042d3a00ef6f70e7b6Freeman Ng
1993673546205ebf1b4c83c212c1032eea38c8adbe7Dianne Hackborn    @Override
200caefa9b5f03b595b81729407e4123fee18a4342cDianne Hackborn    public void onResume() {
201caefa9b5f03b595b81729407e4123fee18a4342cDianne Hackborn        super.onResume();
202caefa9b5f03b595b81729407e4123fee18a4342cDianne Hackborn        mDevHitCountdown = getActivity().getSharedPreferences(DevelopmentSettings.PREF_FILE,
203caefa9b5f03b595b81729407e4123fee18a4342cDianne Hackborn                Context.MODE_PRIVATE).getBoolean(DevelopmentSettings.PREF_SHOW,
204d6a24d505a237c26a280cfbeb5a3bedaca8a3f7dDianne Hackborn                        android.os.Build.TYPE.equals("eng")) ? -1 : TAPS_TO_BE_A_DEVELOPER;
205caefa9b5f03b595b81729407e4123fee18a4342cDianne Hackborn        mDevHitToast = null;
206caefa9b5f03b595b81729407e4123fee18a4342cDianne Hackborn    }
207caefa9b5f03b595b81729407e4123fee18a4342cDianne Hackborn
208caefa9b5f03b595b81729407e4123fee18a4342cDianne Hackborn    @Override
20939b467482d1bf256a111c757e9b7621c6f523271Jason Monk    public boolean onPreferenceTreeClick(Preference preference) {
210c06d4c48a9455d6018f2d793c6b8f211f1131055Amith Yamasani        if (preference.getKey().equals(KEY_FIRMWARE_VERSION)) {
2114749fcf762de0e34ac28f927501d42555062c521Dianne Hackborn            System.arraycopy(mHits, 1, mHits, 0, mHits.length-1);
2124749fcf762de0e34ac28f927501d42555062c521Dianne Hackborn            mHits[mHits.length-1] = SystemClock.uptimeMillis();
2134749fcf762de0e34ac28f927501d42555062c521Dianne Hackborn            if (mHits[0] >= (SystemClock.uptimeMillis()-500)) {
21444879a387a6be6b93cdcc8894227d68af7dbbb1aXiaohui Chen                if (mUm.hasUserRestriction(UserManager.DISALLOW_FUN)) {
2159a5550e9e6efe211b03d067eae2689f6ef5eb2d1Jeff Sharkey                    Log.d(LOG_TAG, "Sorry, no fun for you!");
2169a5550e9e6efe211b03d067eae2689f6ef5eb2d1Jeff Sharkey                    return false;
2179a5550e9e6efe211b03d067eae2689f6ef5eb2d1Jeff Sharkey                }
2189a5550e9e6efe211b03d067eae2689f6ef5eb2d1Jeff Sharkey
2194749fcf762de0e34ac28f927501d42555062c521Dianne Hackborn                Intent intent = new Intent(Intent.ACTION_MAIN);
2204749fcf762de0e34ac28f927501d42555062c521Dianne Hackborn                intent.setClassName("android",
2214749fcf762de0e34ac28f927501d42555062c521Dianne Hackborn                        com.android.internal.app.PlatLogoActivity.class.getName());
2224749fcf762de0e34ac28f927501d42555062c521Dianne Hackborn                try {
2234749fcf762de0e34ac28f927501d42555062c521Dianne Hackborn                    startActivity(intent);
2244749fcf762de0e34ac28f927501d42555062c521Dianne Hackborn                } catch (Exception e) {
225362bd107a11e4cb74c53e8058fe0dfaf9baac65fGilles Debunne                    Log.e(LOG_TAG, "Unable to start activity " + intent.toString());
2264749fcf762de0e34ac28f927501d42555062c521Dianne Hackborn                }
2273673546205ebf1b4c83c212c1032eea38c8adbe7Dianne Hackborn            }
228caefa9b5f03b595b81729407e4123fee18a4342cDianne Hackborn        } else if (preference.getKey().equals(KEY_BUILD_NUMBER)) {
229b02b26e3cb4a8a3aa7b3dd718fbc2cc7c6ac8016Amith Yamasani            // Don't enable developer options for secondary users.
23044879a387a6be6b93cdcc8894227d68af7dbbb1aXiaohui Chen            if (!mUm.isAdminUser()) return true;
231b02b26e3cb4a8a3aa7b3dd718fbc2cc7c6ac8016Amith Yamasani
23244879a387a6be6b93cdcc8894227d68af7dbbb1aXiaohui Chen            if (mUm.hasUserRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES)) return true;
2336c088cb221bb43d47be065387231ffa7192ff211Julia Reynolds
234caefa9b5f03b595b81729407e4123fee18a4342cDianne Hackborn            if (mDevHitCountdown > 0) {
235caefa9b5f03b595b81729407e4123fee18a4342cDianne Hackborn                mDevHitCountdown--;
236caefa9b5f03b595b81729407e4123fee18a4342cDianne Hackborn                if (mDevHitCountdown == 0) {
237caefa9b5f03b595b81729407e4123fee18a4342cDianne Hackborn                    getActivity().getSharedPreferences(DevelopmentSettings.PREF_FILE,
238caefa9b5f03b595b81729407e4123fee18a4342cDianne Hackborn                            Context.MODE_PRIVATE).edit().putBoolean(
239caefa9b5f03b595b81729407e4123fee18a4342cDianne Hackborn                                    DevelopmentSettings.PREF_SHOW, true).apply();
240caefa9b5f03b595b81729407e4123fee18a4342cDianne Hackborn                    if (mDevHitToast != null) {
241caefa9b5f03b595b81729407e4123fee18a4342cDianne Hackborn                        mDevHitToast.cancel();
242caefa9b5f03b595b81729407e4123fee18a4342cDianne Hackborn                    }
243caefa9b5f03b595b81729407e4123fee18a4342cDianne Hackborn                    mDevHitToast = Toast.makeText(getActivity(), R.string.show_dev_on,
244caefa9b5f03b595b81729407e4123fee18a4342cDianne Hackborn                            Toast.LENGTH_LONG);
245caefa9b5f03b595b81729407e4123fee18a4342cDianne Hackborn                    mDevHitToast.show();
2462ec78636f75964a48be5e95fe9b7e71f2270f917Fabrice Di Meglio                    // This is good time to index the Developer Options
2472ec78636f75964a48be5e95fe9b7e71f2270f917Fabrice Di Meglio                    Index.getInstance(
2482ec78636f75964a48be5e95fe9b7e71f2270f917Fabrice Di Meglio                            getActivity().getApplicationContext()).updateFromClassNameResource(
2492ec78636f75964a48be5e95fe9b7e71f2270f917Fabrice Di Meglio                                    DevelopmentSettings.class.getName(), true, true);
2502ec78636f75964a48be5e95fe9b7e71f2270f917Fabrice Di Meglio
251d6a24d505a237c26a280cfbeb5a3bedaca8a3f7dDianne Hackborn                } else if (mDevHitCountdown > 0
252d6a24d505a237c26a280cfbeb5a3bedaca8a3f7dDianne Hackborn                        && mDevHitCountdown < (TAPS_TO_BE_A_DEVELOPER-2)) {
253caefa9b5f03b595b81729407e4123fee18a4342cDianne Hackborn                    if (mDevHitToast != null) {
254caefa9b5f03b595b81729407e4123fee18a4342cDianne Hackborn                        mDevHitToast.cancel();
255caefa9b5f03b595b81729407e4123fee18a4342cDianne Hackborn                    }
256673130bbf8017cf0e082dc65a24609290da4daa4Evan Charlton                    mDevHitToast = Toast.makeText(getActivity(), getResources().getQuantityString(
257673130bbf8017cf0e082dc65a24609290da4daa4Evan Charlton                            R.plurals.show_dev_countdown, mDevHitCountdown, mDevHitCountdown),
258caefa9b5f03b595b81729407e4123fee18a4342cDianne Hackborn                            Toast.LENGTH_SHORT);
259caefa9b5f03b595b81729407e4123fee18a4342cDianne Hackborn                    mDevHitToast.show();
260caefa9b5f03b595b81729407e4123fee18a4342cDianne Hackborn                }
261caefa9b5f03b595b81729407e4123fee18a4342cDianne Hackborn            } else if (mDevHitCountdown < 0) {
262caefa9b5f03b595b81729407e4123fee18a4342cDianne Hackborn                if (mDevHitToast != null) {
263caefa9b5f03b595b81729407e4123fee18a4342cDianne Hackborn                    mDevHitToast.cancel();
264caefa9b5f03b595b81729407e4123fee18a4342cDianne Hackborn                }
265caefa9b5f03b595b81729407e4123fee18a4342cDianne Hackborn                mDevHitToast = Toast.makeText(getActivity(), R.string.show_dev_already,
266caefa9b5f03b595b81729407e4123fee18a4342cDianne Hackborn                        Toast.LENGTH_LONG);
267caefa9b5f03b595b81729407e4123fee18a4342cDianne Hackborn                mDevHitToast.show();
268caefa9b5f03b595b81729407e4123fee18a4342cDianne Hackborn            }
269b42573d0e6870b026110ece22f13dc15452d507cRajat Dewan        } else if (preference.getKey().equals(KEY_DEVICE_FEEDBACK)) {
270b42573d0e6870b026110ece22f13dc15452d507cRajat Dewan            sendFeedback();
2719d4b5486198a16053e5fdeba6b34268104faead2Amit Mahajan        } else if(preference.getKey().equals(KEY_SYSTEM_UPDATE_SETTINGS)) {
2729d4b5486198a16053e5fdeba6b34268104faead2Amit Mahajan            CarrierConfigManager configManager =
2739d4b5486198a16053e5fdeba6b34268104faead2Amit Mahajan                    (CarrierConfigManager) getSystemService(Context.CARRIER_CONFIG_SERVICE);
2749d4b5486198a16053e5fdeba6b34268104faead2Amit Mahajan            PersistableBundle b = configManager.getConfig();
2759d4b5486198a16053e5fdeba6b34268104faead2Amit Mahajan            if (b.getBoolean(CarrierConfigManager.KEY_CI_ACTION_ON_SYS_UPDATE_BOOL)) {
2769d4b5486198a16053e5fdeba6b34268104faead2Amit Mahajan                ciActionOnSysUpdate(b);
2779d4b5486198a16053e5fdeba6b34268104faead2Amit Mahajan            }
2783673546205ebf1b4c83c212c1032eea38c8adbe7Dianne Hackborn        }
27939b467482d1bf256a111c757e9b7621c6f523271Jason Monk        return super.onPreferenceTreeClick(preference);
2803673546205ebf1b4c83c212c1032eea38c8adbe7Dianne Hackborn    }
281a40fb23734cc5d5ac6e69a060cbb488269ad8af3Wink Saville
2829d4b5486198a16053e5fdeba6b34268104faead2Amit Mahajan    /**
2839d4b5486198a16053e5fdeba6b34268104faead2Amit Mahajan     * Trigger client initiated action (send intent) on system update
2849d4b5486198a16053e5fdeba6b34268104faead2Amit Mahajan     */
2859d4b5486198a16053e5fdeba6b34268104faead2Amit Mahajan    private void ciActionOnSysUpdate(PersistableBundle b) {
2869d4b5486198a16053e5fdeba6b34268104faead2Amit Mahajan        String intentStr = b.getString(CarrierConfigManager.
2879d4b5486198a16053e5fdeba6b34268104faead2Amit Mahajan                KEY_CI_ACTION_ON_SYS_UPDATE_INTENT_STRING);
2889d4b5486198a16053e5fdeba6b34268104faead2Amit Mahajan        if (!TextUtils.isEmpty(intentStr)) {
2899d4b5486198a16053e5fdeba6b34268104faead2Amit Mahajan            String extra = b.getString(CarrierConfigManager.
2909d4b5486198a16053e5fdeba6b34268104faead2Amit Mahajan                    KEY_CI_ACTION_ON_SYS_UPDATE_EXTRA_STRING);
2919d4b5486198a16053e5fdeba6b34268104faead2Amit Mahajan            String extraVal = b.getString(CarrierConfigManager.
2929d4b5486198a16053e5fdeba6b34268104faead2Amit Mahajan                    KEY_CI_ACTION_ON_SYS_UPDATE_EXTRA_VAL_STRING);
2939d4b5486198a16053e5fdeba6b34268104faead2Amit Mahajan
2949d4b5486198a16053e5fdeba6b34268104faead2Amit Mahajan            Intent intent = new Intent(intentStr);
2959d4b5486198a16053e5fdeba6b34268104faead2Amit Mahajan            if (!TextUtils.isEmpty(extra)) {
2969d4b5486198a16053e5fdeba6b34268104faead2Amit Mahajan                intent.putExtra(extra, extraVal);
2979d4b5486198a16053e5fdeba6b34268104faead2Amit Mahajan            }
2989d4b5486198a16053e5fdeba6b34268104faead2Amit Mahajan            Log.d(LOG_TAG, "ciActionOnSysUpdate: broadcasting intent " + intentStr +
2999d4b5486198a16053e5fdeba6b34268104faead2Amit Mahajan                    " with extra " + extra + ", " + extraVal);
3009d4b5486198a16053e5fdeba6b34268104faead2Amit Mahajan            getActivity().getApplicationContext().sendBroadcast(intent);
3019d4b5486198a16053e5fdeba6b34268104faead2Amit Mahajan        }
3029d4b5486198a16053e5fdeba6b34268104faead2Amit Mahajan    }
3039d4b5486198a16053e5fdeba6b34268104faead2Amit Mahajan
304a40fb23734cc5d5ac6e69a060cbb488269ad8af3Wink Saville    private void removePreferenceIfPropertyMissing(PreferenceGroup preferenceGroup,
305a40fb23734cc5d5ac6e69a060cbb488269ad8af3Wink Saville            String preference, String property ) {
306a6dbaea2dacaaef7c91f89aae8d5f1ed7580b893Brian Muramatsu        if (SystemProperties.get(property).equals("")) {
307a40fb23734cc5d5ac6e69a060cbb488269ad8af3Wink Saville            // Property is missing so remove preference from group
308a40fb23734cc5d5ac6e69a060cbb488269ad8af3Wink Saville            try {
309a40fb23734cc5d5ac6e69a060cbb488269ad8af3Wink Saville                preferenceGroup.removePreference(findPreference(preference));
310a40fb23734cc5d5ac6e69a060cbb488269ad8af3Wink Saville            } catch (RuntimeException e) {
311362bd107a11e4cb74c53e8058fe0dfaf9baac65fGilles Debunne                Log.d(LOG_TAG, "Property '" + property + "' missing and no '"
312a40fb23734cc5d5ac6e69a060cbb488269ad8af3Wink Saville                        + preference + "' preference");
313a40fb23734cc5d5ac6e69a060cbb488269ad8af3Wink Saville            }
314a40fb23734cc5d5ac6e69a060cbb488269ad8af3Wink Saville        }
315a40fb23734cc5d5ac6e69a060cbb488269ad8af3Wink Saville    }
316a40fb23734cc5d5ac6e69a060cbb488269ad8af3Wink Saville
317a6dbaea2dacaaef7c91f89aae8d5f1ed7580b893Brian Muramatsu    private void removePreferenceIfBoolFalse(String preference, int resId) {
318a6dbaea2dacaaef7c91f89aae8d5f1ed7580b893Brian Muramatsu        if (!getResources().getBoolean(resId)) {
319185ba407bab02c1442d02b82800f0220779ecb10Brian Muramatsu            Preference pref = findPreference(preference);
320185ba407bab02c1442d02b82800f0220779ecb10Brian Muramatsu            if (pref != null) {
321185ba407bab02c1442d02b82800f0220779ecb10Brian Muramatsu                getPreferenceScreen().removePreference(pref);
322185ba407bab02c1442d02b82800f0220779ecb10Brian Muramatsu            }
323a6dbaea2dacaaef7c91f89aae8d5f1ed7580b893Brian Muramatsu        }
324a6dbaea2dacaaef7c91f89aae8d5f1ed7580b893Brian Muramatsu    }
325a6dbaea2dacaaef7c91f89aae8d5f1ed7580b893Brian Muramatsu
326afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    private void setStringSummary(String preference, String value) {
327afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        try {
328afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project            findPreference(preference).setSummary(value);
329afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        } catch (RuntimeException e) {
330afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project            findPreference(preference).setSummary(
331afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project                getResources().getString(R.string.device_info_default));
332afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        }
333afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    }
3342fc2ba11fedd529340eefc042d3a00ef6f70e7b6Freeman Ng
335afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    private void setValueSummary(String preference, String property) {
336afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        try {
337afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project            findPreference(preference).setSummary(
3382fc2ba11fedd529340eefc042d3a00ef6f70e7b6Freeman Ng                    SystemProperties.get(property,
339afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project                            getResources().getString(R.string.device_info_default)));
340afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        } catch (RuntimeException e) {
341362bd107a11e4cb74c53e8058fe0dfaf9baac65fGilles Debunne            // No recovery
342afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        }
343afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    }
344afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
345b42573d0e6870b026110ece22f13dc15452d507cRajat Dewan    private void sendFeedback() {
346b42573d0e6870b026110ece22f13dc15452d507cRajat Dewan        String reporterPackage = getFeedbackReporterPackage(getActivity());
347b42573d0e6870b026110ece22f13dc15452d507cRajat Dewan        if (TextUtils.isEmpty(reporterPackage)) {
348b42573d0e6870b026110ece22f13dc15452d507cRajat Dewan            return;
349b42573d0e6870b026110ece22f13dc15452d507cRajat Dewan        }
350b42573d0e6870b026110ece22f13dc15452d507cRajat Dewan        Intent intent = new Intent(Intent.ACTION_BUG_REPORT);
351b42573d0e6870b026110ece22f13dc15452d507cRajat Dewan        intent.setPackage(reporterPackage);
352b42573d0e6870b026110ece22f13dc15452d507cRajat Dewan        startActivityForResult(intent, 0);
353b42573d0e6870b026110ece22f13dc15452d507cRajat Dewan    }
354b42573d0e6870b026110ece22f13dc15452d507cRajat Dewan
3552397a7391e2ba9434ee89345c1d3a47948d8f226Amith Yamasani    /**
3562397a7391e2ba9434ee89345c1d3a47948d8f226Amith Yamasani     * Reads a line from the specified file.
3572397a7391e2ba9434ee89345c1d3a47948d8f226Amith Yamasani     * @param filename the file to read from
3582397a7391e2ba9434ee89345c1d3a47948d8f226Amith Yamasani     * @return the first line, if any.
3592397a7391e2ba9434ee89345c1d3a47948d8f226Amith Yamasani     * @throws IOException if the file couldn't be read
3602397a7391e2ba9434ee89345c1d3a47948d8f226Amith Yamasani     */
361d267d377fba9f6685dfd73af51d85c244f1f970fElliott Hughes    private static String readLine(String filename) throws IOException {
3622397a7391e2ba9434ee89345c1d3a47948d8f226Amith Yamasani        BufferedReader reader = new BufferedReader(new FileReader(filename), 256);
3632397a7391e2ba9434ee89345c1d3a47948d8f226Amith Yamasani        try {
3642397a7391e2ba9434ee89345c1d3a47948d8f226Amith Yamasani            return reader.readLine();
3652397a7391e2ba9434ee89345c1d3a47948d8f226Amith Yamasani        } finally {
3662397a7391e2ba9434ee89345c1d3a47948d8f226Amith Yamasani            reader.close();
3672397a7391e2ba9434ee89345c1d3a47948d8f226Amith Yamasani        }
3682397a7391e2ba9434ee89345c1d3a47948d8f226Amith Yamasani    }
3692397a7391e2ba9434ee89345c1d3a47948d8f226Amith Yamasani
370d267d377fba9f6685dfd73af51d85c244f1f970fElliott Hughes    public static String getFormattedKernelVersion() {
371afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        try {
372d267d377fba9f6685dfd73af51d85c244f1f970fElliott Hughes            return formatKernelVersion(readLine(FILENAME_PROC_VERSION));
373afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
3742fc2ba11fedd529340eefc042d3a00ef6f70e7b6Freeman Ng        } catch (IOException e) {
375362bd107a11e4cb74c53e8058fe0dfaf9baac65fGilles Debunne            Log.e(LOG_TAG,
376afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project                "IO Exception when getting kernel version for Device Info screen",
377afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project                e);
378afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
379afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project            return "Unavailable";
380afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project        }
381afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project    }
382afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project
383d267d377fba9f6685dfd73af51d85c244f1f970fElliott Hughes    public static String formatKernelVersion(String rawKernelVersion) {
384d267d377fba9f6685dfd73af51d85c244f1f970fElliott Hughes        // Example (see tests for more):
385d267d377fba9f6685dfd73af51d85c244f1f970fElliott Hughes        // Linux version 3.0.31-g6fb96c9 (android-build@xxx.xxx.xxx.xxx.com) \
386d267d377fba9f6685dfd73af51d85c244f1f970fElliott Hughes        //     (gcc version 4.6.x-xxx 20120106 (prerelease) (GCC) ) #1 SMP PREEMPT \
387d267d377fba9f6685dfd73af51d85c244f1f970fElliott Hughes        //     Thu Jun 28 11:02:39 PDT 2012
388d267d377fba9f6685dfd73af51d85c244f1f970fElliott Hughes
389d267d377fba9f6685dfd73af51d85c244f1f970fElliott Hughes        final String PROC_VERSION_REGEX =
390d267d377fba9f6685dfd73af51d85c244f1f970fElliott Hughes            "Linux version (\\S+) " + /* group 1: "3.0.31-g6fb96c9" */
391d267d377fba9f6685dfd73af51d85c244f1f970fElliott Hughes            "\\((\\S+?)\\) " +        /* group 2: "x@y.com" (kernel builder) */
392d267d377fba9f6685dfd73af51d85c244f1f970fElliott Hughes            "(?:\\(gcc.+? \\)) " +    /* ignore: GCC version information */
393d267d377fba9f6685dfd73af51d85c244f1f970fElliott Hughes            "(#\\d+) " +              /* group 3: "#1" */
394d267d377fba9f6685dfd73af51d85c244f1f970fElliott Hughes            "(?:.*?)?" +              /* ignore: optional SMP, PREEMPT, and any CONFIG_FLAGS */
395d267d377fba9f6685dfd73af51d85c244f1f970fElliott Hughes            "((Sun|Mon|Tue|Wed|Thu|Fri|Sat).+)"; /* group 4: "Thu Jun 28 11:02:39 PDT 2012" */
396d267d377fba9f6685dfd73af51d85c244f1f970fElliott Hughes
397d267d377fba9f6685dfd73af51d85c244f1f970fElliott Hughes        Matcher m = Pattern.compile(PROC_VERSION_REGEX).matcher(rawKernelVersion);
398d267d377fba9f6685dfd73af51d85c244f1f970fElliott Hughes        if (!m.matches()) {
399d267d377fba9f6685dfd73af51d85c244f1f970fElliott Hughes            Log.e(LOG_TAG, "Regex did not match on /proc/version: " + rawKernelVersion);
400d267d377fba9f6685dfd73af51d85c244f1f970fElliott Hughes            return "Unavailable";
401d267d377fba9f6685dfd73af51d85c244f1f970fElliott Hughes        } else if (m.groupCount() < 4) {
402d267d377fba9f6685dfd73af51d85c244f1f970fElliott Hughes            Log.e(LOG_TAG, "Regex match on /proc/version only returned " + m.groupCount()
403d267d377fba9f6685dfd73af51d85c244f1f970fElliott Hughes                    + " groups");
404d267d377fba9f6685dfd73af51d85c244f1f970fElliott Hughes            return "Unavailable";
405d267d377fba9f6685dfd73af51d85c244f1f970fElliott Hughes        }
406d267d377fba9f6685dfd73af51d85c244f1f970fElliott Hughes        return m.group(1) + "\n" +                 // 3.0.31-g6fb96c9
407d267d377fba9f6685dfd73af51d85c244f1f970fElliott Hughes            m.group(2) + " " + m.group(3) + "\n" + // x@y.com #1
408d267d377fba9f6685dfd73af51d85c244f1f970fElliott Hughes            m.group(4);                            // Thu Jun 28 11:02:39 PDT 2012
409d267d377fba9f6685dfd73af51d85c244f1f970fElliott Hughes    }
410d267d377fba9f6685dfd73af51d85c244f1f970fElliott Hughes
4112397a7391e2ba9434ee89345c1d3a47948d8f226Amith Yamasani    /**
4122397a7391e2ba9434ee89345c1d3a47948d8f226Amith Yamasani     * Returns " (ENGINEERING)" if the msv file has a zero value, else returns "".
4132397a7391e2ba9434ee89345c1d3a47948d8f226Amith Yamasani     * @return a string to append to the model number description.
4142397a7391e2ba9434ee89345c1d3a47948d8f226Amith Yamasani     */
4152397a7391e2ba9434ee89345c1d3a47948d8f226Amith Yamasani    private String getMsvSuffix() {
4162397a7391e2ba9434ee89345c1d3a47948d8f226Amith Yamasani        // Production devices should have a non-zero value. If we can't read it, assume it's a
4172397a7391e2ba9434ee89345c1d3a47948d8f226Amith Yamasani        // production device so that we don't accidentally show that it's an ENGINEERING device.
4182397a7391e2ba9434ee89345c1d3a47948d8f226Amith Yamasani        try {
4192397a7391e2ba9434ee89345c1d3a47948d8f226Amith Yamasani            String msv = readLine(FILENAME_MSV);
4202397a7391e2ba9434ee89345c1d3a47948d8f226Amith Yamasani            // Parse as a hex number. If it evaluates to a zero, then it's an engineering build.
4212397a7391e2ba9434ee89345c1d3a47948d8f226Amith Yamasani            if (Long.parseLong(msv, 16) == 0) {
4222397a7391e2ba9434ee89345c1d3a47948d8f226Amith Yamasani                return " (ENGINEERING)";
4232397a7391e2ba9434ee89345c1d3a47948d8f226Amith Yamasani            }
4242397a7391e2ba9434ee89345c1d3a47948d8f226Amith Yamasani        } catch (IOException ioe) {
4252397a7391e2ba9434ee89345c1d3a47948d8f226Amith Yamasani            // Fail quietly, as the file may not exist on some devices.
4262397a7391e2ba9434ee89345c1d3a47948d8f226Amith Yamasani        } catch (NumberFormatException nfe) {
4272397a7391e2ba9434ee89345c1d3a47948d8f226Amith Yamasani            // Fail quietly, returning empty string should be sufficient
4282397a7391e2ba9434ee89345c1d3a47948d8f226Amith Yamasani        }
4292397a7391e2ba9434ee89345c1d3a47948d8f226Amith Yamasani        return "";
4302397a7391e2ba9434ee89345c1d3a47948d8f226Amith Yamasani    }
431b42573d0e6870b026110ece22f13dc15452d507cRajat Dewan
432b42573d0e6870b026110ece22f13dc15452d507cRajat Dewan    private static String getFeedbackReporterPackage(Context context) {
433b2385ea46286933add8ea3fb86db7870fe294334Fabrice Di Meglio        final String feedbackReporter =
434b42573d0e6870b026110ece22f13dc15452d507cRajat Dewan                context.getResources().getString(R.string.oem_preferred_feedback_reporter);
435b42573d0e6870b026110ece22f13dc15452d507cRajat Dewan        if (TextUtils.isEmpty(feedbackReporter)) {
436b42573d0e6870b026110ece22f13dc15452d507cRajat Dewan            // Reporter not configured. Return.
437b42573d0e6870b026110ece22f13dc15452d507cRajat Dewan            return feedbackReporter;
438b42573d0e6870b026110ece22f13dc15452d507cRajat Dewan        }
439b42573d0e6870b026110ece22f13dc15452d507cRajat Dewan        // Additional checks to ensure the reporter is on system image, and reporter is
440b42573d0e6870b026110ece22f13dc15452d507cRajat Dewan        // configured to listen to the intent. Otherwise, dont show the "send feedback" option.
441b2385ea46286933add8ea3fb86db7870fe294334Fabrice Di Meglio        final Intent intent = new Intent(Intent.ACTION_BUG_REPORT);
442b42573d0e6870b026110ece22f13dc15452d507cRajat Dewan
443b42573d0e6870b026110ece22f13dc15452d507cRajat Dewan        PackageManager pm = context.getPackageManager();
444b42573d0e6870b026110ece22f13dc15452d507cRajat Dewan        List<ResolveInfo> resolvedPackages =
445b42573d0e6870b026110ece22f13dc15452d507cRajat Dewan                pm.queryIntentActivities(intent, PackageManager.GET_RESOLVED_FILTER);
446b42573d0e6870b026110ece22f13dc15452d507cRajat Dewan        for (ResolveInfo info : resolvedPackages) {
447b42573d0e6870b026110ece22f13dc15452d507cRajat Dewan            if (info.activityInfo != null) {
448b42573d0e6870b026110ece22f13dc15452d507cRajat Dewan                if (!TextUtils.isEmpty(info.activityInfo.packageName)) {
449b42573d0e6870b026110ece22f13dc15452d507cRajat Dewan                    try {
450b42573d0e6870b026110ece22f13dc15452d507cRajat Dewan                        ApplicationInfo ai = pm.getApplicationInfo(info.activityInfo.packageName, 0);
451b42573d0e6870b026110ece22f13dc15452d507cRajat Dewan                        if ((ai.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
452b42573d0e6870b026110ece22f13dc15452d507cRajat Dewan                            // Package is on the system image
453b42573d0e6870b026110ece22f13dc15452d507cRajat Dewan                            if (TextUtils.equals(
454b42573d0e6870b026110ece22f13dc15452d507cRajat Dewan                                        info.activityInfo.packageName, feedbackReporter)) {
455b42573d0e6870b026110ece22f13dc15452d507cRajat Dewan                                return feedbackReporter;
456b42573d0e6870b026110ece22f13dc15452d507cRajat Dewan                            }
457b42573d0e6870b026110ece22f13dc15452d507cRajat Dewan                        }
458b42573d0e6870b026110ece22f13dc15452d507cRajat Dewan                    } catch (PackageManager.NameNotFoundException e) {
459b42573d0e6870b026110ece22f13dc15452d507cRajat Dewan                         // No need to do anything here.
460b42573d0e6870b026110ece22f13dc15452d507cRajat Dewan                    }
461b42573d0e6870b026110ece22f13dc15452d507cRajat Dewan                }
462b42573d0e6870b026110ece22f13dc15452d507cRajat Dewan            }
463b42573d0e6870b026110ece22f13dc15452d507cRajat Dewan        }
464b42573d0e6870b026110ece22f13dc15452d507cRajat Dewan        return null;
465b42573d0e6870b026110ece22f13dc15452d507cRajat Dewan    }
466b2385ea46286933add8ea3fb86db7870fe294334Fabrice Di Meglio
467b2385ea46286933add8ea3fb86db7870fe294334Fabrice Di Meglio    /**
468b2385ea46286933add8ea3fb86db7870fe294334Fabrice Di Meglio     * For Search.
469b2385ea46286933add8ea3fb86db7870fe294334Fabrice Di Meglio     */
470b2385ea46286933add8ea3fb86db7870fe294334Fabrice Di Meglio    public static final SearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
471b2385ea46286933add8ea3fb86db7870fe294334Fabrice Di Meglio        new BaseSearchIndexProvider() {
472b2385ea46286933add8ea3fb86db7870fe294334Fabrice Di Meglio
473b2385ea46286933add8ea3fb86db7870fe294334Fabrice Di Meglio            @Override
474b2385ea46286933add8ea3fb86db7870fe294334Fabrice Di Meglio            public List<SearchIndexableResource> getXmlResourcesToIndex(
475b2385ea46286933add8ea3fb86db7870fe294334Fabrice Di Meglio                    Context context, boolean enabled) {
476b2385ea46286933add8ea3fb86db7870fe294334Fabrice Di Meglio                final SearchIndexableResource sir = new SearchIndexableResource(context);
477b2385ea46286933add8ea3fb86db7870fe294334Fabrice Di Meglio                sir.xmlResId = R.xml.device_info_settings;
478b2385ea46286933add8ea3fb86db7870fe294334Fabrice Di Meglio                return Arrays.asList(sir);
479b2385ea46286933add8ea3fb86db7870fe294334Fabrice Di Meglio            }
480b2385ea46286933add8ea3fb86db7870fe294334Fabrice Di Meglio
481b2385ea46286933add8ea3fb86db7870fe294334Fabrice Di Meglio            @Override
482b2385ea46286933add8ea3fb86db7870fe294334Fabrice Di Meglio            public List<String> getNonIndexableKeys(Context context) {
483b2385ea46286933add8ea3fb86db7870fe294334Fabrice Di Meglio                final List<String> keys = new ArrayList<String>();
484b2385ea46286933add8ea3fb86db7870fe294334Fabrice Di Meglio                if (isPropertyMissing(PROPERTY_SELINUX_STATUS)) {
485b2385ea46286933add8ea3fb86db7870fe294334Fabrice Di Meglio                    keys.add(KEY_SELINUX_STATUS);
486b2385ea46286933add8ea3fb86db7870fe294334Fabrice Di Meglio                }
487b2385ea46286933add8ea3fb86db7870fe294334Fabrice Di Meglio                if (isPropertyMissing(PROPERTY_URL_SAFETYLEGAL)) {
488b2385ea46286933add8ea3fb86db7870fe294334Fabrice Di Meglio                    keys.add(KEY_SAFETY_LEGAL);
489b2385ea46286933add8ea3fb86db7870fe294334Fabrice Di Meglio                }
490b2385ea46286933add8ea3fb86db7870fe294334Fabrice Di Meglio                if (isPropertyMissing(PROPERTY_EQUIPMENT_ID)) {
491b2385ea46286933add8ea3fb86db7870fe294334Fabrice Di Meglio                    keys.add(KEY_EQUIPMENT_ID);
492b2385ea46286933add8ea3fb86db7870fe294334Fabrice Di Meglio                }
493b2385ea46286933add8ea3fb86db7870fe294334Fabrice Di Meglio                // Remove Baseband version if wifi-only device
494b2385ea46286933add8ea3fb86db7870fe294334Fabrice Di Meglio                if (Utils.isWifiOnly(context)) {
495b2385ea46286933add8ea3fb86db7870fe294334Fabrice Di Meglio                    keys.add((KEY_BASEBAND_VERSION));
496b2385ea46286933add8ea3fb86db7870fe294334Fabrice Di Meglio                }
497b2385ea46286933add8ea3fb86db7870fe294334Fabrice Di Meglio                // Dont show feedback option if there is no reporter.
498b2385ea46286933add8ea3fb86db7870fe294334Fabrice Di Meglio                if (TextUtils.isEmpty(getFeedbackReporterPackage(context))) {
499b2385ea46286933add8ea3fb86db7870fe294334Fabrice Di Meglio                    keys.add(KEY_DEVICE_FEEDBACK);
500b2385ea46286933add8ea3fb86db7870fe294334Fabrice Di Meglio                }
50144879a387a6be6b93cdcc8894227d68af7dbbb1aXiaohui Chen                final UserManager um = UserManager.get(context);
50244879a387a6be6b93cdcc8894227d68af7dbbb1aXiaohui Chen                // TODO: system update needs to be fixed for non-owner user b/22760654
50344879a387a6be6b93cdcc8894227d68af7dbbb1aXiaohui Chen                if (!um.isAdminUser()) {
504b2385ea46286933add8ea3fb86db7870fe294334Fabrice Di Meglio                    keys.add(KEY_SYSTEM_UPDATE_SETTINGS);
505b2385ea46286933add8ea3fb86db7870fe294334Fabrice Di Meglio                }
506b2385ea46286933add8ea3fb86db7870fe294334Fabrice Di Meglio                if (!context.getResources().getBoolean(
507b2385ea46286933add8ea3fb86db7870fe294334Fabrice Di Meglio                        R.bool.config_additional_system_update_setting_enable)) {
508b2385ea46286933add8ea3fb86db7870fe294334Fabrice Di Meglio                    keys.add(KEY_UPDATE_SETTING);
509b2385ea46286933add8ea3fb86db7870fe294334Fabrice Di Meglio                }
510b2385ea46286933add8ea3fb86db7870fe294334Fabrice Di Meglio                return keys;
511b2385ea46286933add8ea3fb86db7870fe294334Fabrice Di Meglio            }
512b2385ea46286933add8ea3fb86db7870fe294334Fabrice Di Meglio
513b2385ea46286933add8ea3fb86db7870fe294334Fabrice Di Meglio            private boolean isPropertyMissing(String property) {
514b2385ea46286933add8ea3fb86db7870fe294334Fabrice Di Meglio                return SystemProperties.get(property).equals("");
515b2385ea46286933add8ea3fb86db7870fe294334Fabrice Di Meglio            }
516b2385ea46286933add8ea3fb86db7870fe294334Fabrice Di Meglio        };
517b2385ea46286933add8ea3fb86db7870fe294334Fabrice Di Meglio
518afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project}
519b42573d0e6870b026110ece22f13dc15452d507cRajat Dewan
520