• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2015 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 package com.android.tv.settings.about;
18 
19 import android.content.BroadcastReceiver;
20 import android.content.Context;
21 import android.content.Intent;
22 import android.content.IntentFilter;
23 import android.content.pm.ResolveInfo;
24 import android.net.ConnectivityManager;
25 import android.os.Build;
26 import android.os.Bundle;
27 import android.os.PersistableBundle;
28 import android.os.SELinux;
29 import android.os.SystemClock;
30 import android.os.SystemProperties;
31 import android.os.UserManager;
32 import android.provider.Settings;
33 import android.support.annotation.Nullable;
34 import android.support.v17.preference.LeanbackPreferenceFragment;
35 import android.support.v17.preference.LeanbackSettingsFragment;
36 import android.support.v4.content.LocalBroadcastManager;
37 import android.support.v7.preference.Preference;
38 import android.support.v7.preference.PreferenceScreen;
39 import android.telephony.CarrierConfigManager;
40 import android.text.TextUtils;
41 import android.util.Log;
42 import android.widget.Toast;
43 
44 import com.android.internal.telephony.TelephonyProperties;
45 import com.android.settingslib.DeviceInfoUtils;
46 import com.android.tv.settings.LongClickPreference;
47 import com.android.tv.settings.MainFragment;
48 import com.android.tv.settings.PreferenceUtils;
49 import com.android.tv.settings.R;
50 import com.android.tv.settings.name.DeviceManager;
51 
52 public class AboutFragment extends LeanbackPreferenceFragment implements
53         LongClickPreference.OnLongClickListener {
54     private static final String TAG = "AboutFragment";
55 
56     private static final String KEY_MANUAL = "manual";
57     private static final String KEY_REGULATORY_INFO = "regulatory_info";
58     private static final String KEY_SYSTEM_UPDATE_SETTINGS = "system_update_settings";
59     private static final String PROPERTY_URL_SAFETYLEGAL = "ro.url.safetylegal";
60     private static final String PROPERTY_SELINUX_STATUS = "ro.build.selinux";
61     private static final String KEY_KERNEL_VERSION = "kernel_version";
62     private static final String KEY_BUILD_NUMBER = "build_number";
63     private static final String KEY_DEVICE_MODEL = "device_model";
64     private static final String KEY_SELINUX_STATUS = "selinux_status";
65     private static final String KEY_BASEBAND_VERSION = "baseband_version";
66     private static final String KEY_FIRMWARE_VERSION = "firmware_version";
67     private static final String KEY_SECURITY_PATCH = "security_patch";
68     private static final String KEY_UPDATE_SETTING = "additional_system_update_settings";
69     private static final String KEY_EQUIPMENT_ID = "fcc_equipment_id";
70     private static final String PROPERTY_EQUIPMENT_ID = "ro.ril.fccid";
71     private static final String KEY_DEVICE_FEEDBACK = "device_feedback";
72     private static final String KEY_SAFETY_LEGAL = "safetylegal";
73     private static final String KEY_DEVICE_NAME = "device_name";
74     private static final String KEY_RESTART = "restart";
75     private static final String KEY_TUTORIALS = "tutorials";
76 
77     static final int TAPS_TO_BE_A_DEVELOPER = 7;
78 
79     long[] mHits = new long[3];
80     int mDevHitCountdown;
81     Toast mDevHitToast;
82 
83     private UserManager mUm;
84 
85     private final BroadcastReceiver mDeviceNameReceiver = new BroadcastReceiver() {
86         @Override
87         public void onReceive(Context context, Intent intent) {
88             refreshDeviceName();
89         }
90     };
91 
newInstance()92     public static AboutFragment newInstance() {
93         return new AboutFragment();
94     }
95 
96     @Override
onCreate(Bundle savedInstanceState)97     public void onCreate(Bundle savedInstanceState) {
98         mUm = UserManager.get(getActivity());
99 
100         super.onCreate(savedInstanceState);
101     }
102 
103     @Override
onCreatePreferences(Bundle savedInstanceState, String rootKey)104     public void onCreatePreferences(Bundle savedInstanceState, String rootKey) {
105         setPreferencesFromResource(R.xml.device_info_settings, null);
106         final PreferenceScreen screen = getPreferenceScreen();
107 
108         refreshDeviceName();
109         final Preference deviceNamePref = findPreference(KEY_DEVICE_NAME);
110         PreferenceUtils.resolveSystemActivityOrRemove(getActivity(), screen, deviceNamePref, 0);
111 
112         final Preference firmwareVersionPref = findPreference(KEY_FIRMWARE_VERSION);
113         firmwareVersionPref.setSummary(Build.VERSION.RELEASE);
114         firmwareVersionPref.setEnabled(true);
115 
116         final Preference securityPatchPref = findPreference(KEY_SECURITY_PATCH);
117         final String patch = DeviceInfoUtils.getSecurityPatch();
118         if (!TextUtils.isEmpty(patch)) {
119             securityPatchPref.setSummary(patch);
120         } else {
121             removePreference(securityPatchPref);
122         }
123 
124         final LongClickPreference restartPref = (LongClickPreference) findPreference(KEY_RESTART);
125         restartPref.setLongClickListener(this);
126 
127         findPreference(KEY_BASEBAND_VERSION).setSummary(
128                 getSystemPropertySummary(TelephonyProperties.PROPERTY_BASEBAND_VERSION));
129         findPreference(KEY_DEVICE_MODEL).setSummary(Build.MODEL + DeviceInfoUtils.getMsvSuffix());
130         findPreference(KEY_EQUIPMENT_ID)
131                 .setSummary(getSystemPropertySummary(PROPERTY_EQUIPMENT_ID));
132 
133         final Preference buildNumberPref = findPreference(KEY_BUILD_NUMBER);
134         buildNumberPref.setSummary(Build.DISPLAY);
135         buildNumberPref.setEnabled(true);
136         findPreference(KEY_KERNEL_VERSION).setSummary(DeviceInfoUtils.getFormattedKernelVersion());
137 
138         final Preference selinuxPref = findPreference(KEY_SELINUX_STATUS);
139         if (!SELinux.isSELinuxEnabled()) {
140             selinuxPref.setSummary(R.string.selinux_status_disabled);
141         } else if (!SELinux.isSELinuxEnforced()) {
142             selinuxPref.setSummary(R.string.selinux_status_permissive);
143         }
144 
145         // Remove selinux information if property is not present
146         if (TextUtils.isEmpty(SystemProperties.get(PROPERTY_SELINUX_STATUS))) {
147             removePreference(selinuxPref);
148         }
149 
150         // Remove Safety information preference if PROPERTY_URL_SAFETYLEGAL is not set
151         if (TextUtils.isEmpty(SystemProperties.get(PROPERTY_URL_SAFETYLEGAL))) {
152             removePreference(findPreference(KEY_SAFETY_LEGAL));
153         }
154 
155         // Remove Equipment id preference if FCC ID is not set by RIL
156         if (TextUtils.isEmpty(SystemProperties.get(PROPERTY_EQUIPMENT_ID))) {
157             removePreference(findPreference(KEY_EQUIPMENT_ID));
158         }
159 
160         // Remove Baseband version if wifi-only device
161         if (isWifiOnly(getActivity())) {
162             removePreference(findPreference(KEY_BASEBAND_VERSION));
163         }
164 
165         // Dont show feedback option if there is no reporter.
166         if (TextUtils.isEmpty(DeviceInfoUtils.getFeedbackReporterPackage(getActivity()))) {
167             removePreference(findPreference(KEY_DEVICE_FEEDBACK));
168         }
169 
170         final Preference updateSettingsPref = findPreference(KEY_SYSTEM_UPDATE_SETTINGS);
171         if (mUm.isAdminUser()) {
172             PreferenceUtils.resolveSystemActivityOrRemove(getActivity(), screen,
173                     updateSettingsPref, PreferenceUtils.FLAG_SET_TITLE);
174         } else if (updateSettingsPref != null) {
175             // Remove for secondary users
176             removePreference(updateSettingsPref);
177         }
178 
179         // Read platform settings for additional system update setting
180         if (!getResources().getBoolean(R.bool.config_additional_system_update_setting_enable)) {
181             removePreference(findPreference(KEY_UPDATE_SETTING));
182         }
183 
184         // Remove manual entry if none present.
185         if (!getResources().getBoolean(R.bool.config_show_manual)) {
186             removePreference(findPreference(KEY_MANUAL));
187         }
188 
189         // Remove regulatory information if none present.
190         final Preference regulatoryPref = findPreference(KEY_REGULATORY_INFO);
191         PreferenceUtils.resolveSystemActivityOrRemove(getActivity(), screen, regulatoryPref, 0);
192     }
193 
removePreference(@ullable Preference preference)194     private void removePreference(@Nullable Preference preference) {
195         if (preference != null) {
196             getPreferenceScreen().removePreference(preference);
197         }
198     }
199 
200     @Override
onStart()201     public void onStart() {
202         super.onStart();
203         refreshDeviceName();
204 
205         LocalBroadcastManager.getInstance(getContext()).registerReceiver(mDeviceNameReceiver,
206                 new IntentFilter(DeviceManager.ACTION_DEVICE_NAME_UPDATE));
207     }
208 
209     @Override
onResume()210     public void onResume() {
211         super.onResume();
212         final boolean developerEnabled = Settings.Global.getInt(getActivity().getContentResolver(),
213                 Settings.Global.DEVELOPMENT_SETTINGS_ENABLED,
214                 android.os.Build.TYPE.equals("eng") ? 1 : 0) == 1;
215         mDevHitCountdown = developerEnabled ? -1 : TAPS_TO_BE_A_DEVELOPER;
216         mDevHitToast = null;
217         updateTutorials();
218     }
219 
220     @Override
onStop()221     public void onStop() {
222         super.onStop();
223         LocalBroadcastManager.getInstance(getContext()).unregisterReceiver(mDeviceNameReceiver);
224     }
225 
refreshDeviceName()226     private void refreshDeviceName() {
227         final Preference deviceNamePref = findPreference(KEY_DEVICE_NAME);
228         if (deviceNamePref != null) {
229             deviceNamePref.setSummary(DeviceManager.getDeviceName(getActivity()));
230         }
231     }
232 
233     @Override
onPreferenceLongClick(Preference preference)234     public boolean onPreferenceLongClick(Preference preference) {
235         if (TextUtils.equals(preference.getKey(), KEY_RESTART)) {
236             if (getCallbackFragment() instanceof LeanbackSettingsFragment) {
237                 LeanbackSettingsFragment callback =
238                         (LeanbackSettingsFragment) getCallbackFragment();
239                 callback.startImmersiveFragment(
240                         RebootConfirmFragment.newInstance(true /* safeMode */));
241                 return true;
242             }
243         }
244         return false;
245     }
246 
247     @Override
onPreferenceTreeClick(Preference preference)248     public boolean onPreferenceTreeClick(Preference preference) {
249         switch (preference.getKey()) {
250             case KEY_FIRMWARE_VERSION:
251                 System.arraycopy(mHits, 1, mHits, 0, mHits.length - 1);
252                 mHits[mHits.length - 1] = SystemClock.uptimeMillis();
253                 if (mHits[0] >= (SystemClock.uptimeMillis() - 500)) {
254                     if (mUm.hasUserRestriction(UserManager.DISALLOW_FUN)) {
255                         Log.d(TAG, "Sorry, no fun for you!");
256                         return false;
257                     }
258 
259                     Intent intent = new Intent(Intent.ACTION_MAIN);
260                     intent.setClassName("android",
261                             com.android.internal.app.PlatLogoActivity.class.getName());
262                     try {
263                         startActivity(intent);
264                     } catch (Exception e) {
265                         Log.e(TAG, "Unable to start activity " + intent.toString());
266                     }
267                 }
268                 break;
269             case KEY_BUILD_NUMBER:
270                 // Don't enable developer options for secondary users.
271                 if (!mUm.isAdminUser())
272                     return true;
273 
274                 if (mUm.hasUserRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES))
275                     return true;
276 
277                 if (mDevHitCountdown > 0) {
278                     mDevHitCountdown--;
279                     if (mDevHitCountdown == 0) {
280                         Settings.Global.putInt(getActivity().getContentResolver(),
281                                 Settings.Global.DEVELOPMENT_SETTINGS_ENABLED, 1);
282                         if (mDevHitToast != null) {
283                             mDevHitToast.cancel();
284                         }
285                         mDevHitToast = Toast.makeText(getActivity(), R.string.show_dev_on,
286                                 Toast.LENGTH_LONG);
287                         mDevHitToast.show();
288                         // This is good time to index the Developer Options
289 //                    Index.getInstance(
290 //                            getActivity().getApplicationContext()).updateFromClassNameResource(
291 //                            DevelopmentSettings.class.getName(), true, true);
292 
293                     } else if (mDevHitCountdown > 0
294                             && mDevHitCountdown < (TAPS_TO_BE_A_DEVELOPER - 2)) {
295                         if (mDevHitToast != null) {
296                             mDevHitToast.cancel();
297                         }
298                         mDevHitToast = Toast
299                                 .makeText(getActivity(), getResources().getQuantityString(
300                                         R.plurals.show_dev_countdown, mDevHitCountdown,
301                                         mDevHitCountdown),
302                                         Toast.LENGTH_SHORT);
303                         mDevHitToast.show();
304                     }
305                 } else if (mDevHitCountdown < 0) {
306                     if (mDevHitToast != null) {
307                         mDevHitToast.cancel();
308                     }
309                     mDevHitToast = Toast.makeText(getActivity(), R.string.show_dev_already,
310                             Toast.LENGTH_LONG);
311                     mDevHitToast.show();
312                 }
313                 break;
314             case KEY_DEVICE_FEEDBACK:
315                 sendFeedback();
316                 break;
317             case KEY_SYSTEM_UPDATE_SETTINGS:
318                 CarrierConfigManager configManager = (CarrierConfigManager)
319                         getActivity().getSystemService(Context.CARRIER_CONFIG_SERVICE);
320                 PersistableBundle b = configManager.getConfig();
321                 if (b != null &&
322                         b.getBoolean(CarrierConfigManager.KEY_CI_ACTION_ON_SYS_UPDATE_BOOL)) {
323                     ciActionOnSysUpdate(b);
324                 }
325                 break;
326         }
327         return super.onPreferenceTreeClick(preference);
328     }
329 
330     /**
331      * Trigger client initiated action (send intent) on system update
332      */
ciActionOnSysUpdate(PersistableBundle b)333     private void ciActionOnSysUpdate(PersistableBundle b) {
334         String intentStr = b.getString(CarrierConfigManager.
335                 KEY_CI_ACTION_ON_SYS_UPDATE_INTENT_STRING);
336         if (!TextUtils.isEmpty(intentStr)) {
337             String extra = b.getString(CarrierConfigManager.
338                     KEY_CI_ACTION_ON_SYS_UPDATE_EXTRA_STRING);
339             String extraVal = b.getString(CarrierConfigManager.
340                     KEY_CI_ACTION_ON_SYS_UPDATE_EXTRA_VAL_STRING);
341 
342             Intent intent = new Intent(intentStr);
343             if (!TextUtils.isEmpty(extra)) {
344                 intent.putExtra(extra, extraVal);
345             }
346             Log.d(TAG, "ciActionOnSysUpdate: broadcasting intent " + intentStr +
347                     " with extra " + extra + ", " + extraVal);
348             getActivity().getApplicationContext().sendBroadcast(intent);
349         }
350     }
351 
getSystemPropertySummary(String property)352     private String getSystemPropertySummary(String property) {
353         return SystemProperties.get(property,
354                 getResources().getString(R.string.device_info_default));
355     }
356 
isWifiOnly(Context context)357     public static boolean isWifiOnly(Context context) {
358         ConnectivityManager cm = (ConnectivityManager)context.getSystemService(
359                 Context.CONNECTIVITY_SERVICE);
360         return (!cm.isNetworkSupported(ConnectivityManager.TYPE_MOBILE));
361     }
362 
sendFeedback()363     private void sendFeedback() {
364         String reporterPackage = DeviceInfoUtils.getFeedbackReporterPackage(getActivity());
365         if (TextUtils.isEmpty(reporterPackage)) {
366             return;
367         }
368         Intent intent = new Intent(Intent.ACTION_BUG_REPORT);
369         intent.setPackage(reporterPackage);
370         startActivityForResult(intent, 0);
371     }
372 
updateTutorials()373     private void updateTutorials() {
374         final Preference deviceTutorialsPref = findPreference(KEY_TUTORIALS);
375         if (deviceTutorialsPref != null) {
376             final ResolveInfo info = MainFragment.systemIntentIsHandled(getContext(),
377                     deviceTutorialsPref.getIntent());
378             deviceTutorialsPref.setVisible(info != null);
379             if (info != null) {
380                 deviceTutorialsPref.setTitle(info.loadLabel(getContext().getPackageManager()));
381             }
382         }
383     }
384 }
385