deadman96385

Untitled

Jan 2nd, 2015
431
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 59.03 KB | None | 0 0
  1. /*
  2. * Copyright (C) 2014 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.settings;
  18.  
  19. import android.app.ActionBar;
  20. import android.app.Activity;
  21. import android.app.Fragment;
  22. import android.app.FragmentManager;
  23. import android.app.FragmentTransaction;
  24. import android.content.BroadcastReceiver;
  25. import android.content.ComponentName;
  26. import android.content.Context;
  27. import android.content.Intent;
  28. import android.content.IntentFilter;
  29. import android.content.SharedPreferences;
  30. import android.content.pm.ActivityInfo;
  31. import android.content.pm.PackageManager;
  32. import android.content.pm.PackageManager.NameNotFoundException;
  33. import android.content.pm.ResolveInfo;
  34. import android.content.res.Configuration;
  35. import android.content.res.TypedArray;
  36. import android.content.res.XmlResourceParser;
  37. import android.nfc.NfcAdapter;
  38. import android.nfc.Tag;
  39. import android.os.Bundle;
  40. import android.os.Handler;
  41. import android.os.INetworkManagementService;
  42. import android.os.Message;
  43. import android.os.RemoteException;
  44. import android.os.ServiceManager;
  45. import android.os.UserHandle;
  46. import android.os.UserManager;
  47. import android.preference.Preference;
  48. import android.preference.PreferenceFragment;
  49. import android.preference.PreferenceManager;
  50. import android.preference.PreferenceScreen;
  51. import android.text.TextUtils;
  52. import android.transition.TransitionManager;
  53. import android.util.AttributeSet;
  54. import android.util.Log;
  55. import android.util.TypedValue;
  56. import android.util.Xml;
  57. import android.view.Menu;
  58. import android.view.MenuInflater;
  59. import android.view.MenuItem;
  60. import android.view.View;
  61. import android.view.View.OnClickListener;
  62. import android.view.ViewGroup;
  63. import android.widget.Button;
  64. import android.widget.SearchView;
  65.  
  66. import com.android.internal.util.ArrayUtils;
  67. import com.android.internal.util.XmlUtils;
  68. import com.android.settings.accessibility.AccessibilitySettings;
  69. import com.android.settings.accessibility.CaptionPropertiesFragment;
  70. import com.android.settings.accounts.AccountSettings;
  71. import com.android.settings.accounts.AccountSyncSettings;
  72. import com.android.settings.applications.InstalledAppDetails;
  73. import com.android.settings.applications.ManageApplications;
  74. import com.android.settings.applications.ProcessStatsUi;
  75. import com.android.settings.blacklist.BlacklistSettings;
  76. import com.android.settings.bluetooth.BluetoothSettings;
  77. import com.android.settings.dashboard.DashboardCategory;
  78. import com.android.settings.dashboard.DashboardSummary;
  79. import com.android.settings.dashboard.DashboardTile;
  80. import com.android.settings.dashboard.NoHomeDialogFragment;
  81. import com.android.settings.dashboard.SearchResultsSummary;
  82. import com.android.settings.deviceinfo.Memory;
  83. import com.android.settings.deviceinfo.UsbSettings;
  84. import com.android.settings.fuelgauge.BatterySaverSettings;
  85. import com.android.settings.fuelgauge.PowerUsageSummary;
  86. import com.android.settings.notification.NotificationAppList;
  87. import com.android.settings.notification.OtherSoundSettings;
  88. import com.android.settings.profiles.NFCProfileTagCallback;
  89. import com.android.settings.quicklaunch.QuickLaunchSettings;
  90. import com.android.settings.search.DynamicIndexableContentMonitor;
  91. import com.android.settings.search.Index;
  92. import com.android.settings.inputmethod.InputMethodAndLanguageSettings;
  93. import com.android.settings.inputmethod.KeyboardLayoutPickerFragment;
  94. import com.android.settings.inputmethod.SpellCheckersSettings;
  95. import com.android.settings.inputmethod.UserDictionaryList;
  96. import com.android.settings.location.LocationSettings;
  97. import com.android.settings.liquid.MainSettings;
  98. import com.android.settings.nfc.AndroidBeam;
  99. import com.android.settings.nfc.PaymentSettings;
  100. import com.android.settings.notification.AppNotificationSettings;
  101. import com.android.settings.notification.ConditionProviderSettings;
  102. import com.android.settings.notification.NotificationAccessSettings;
  103. import com.android.settings.notification.NotificationSettings;
  104. import com.android.settings.notification.NotificationStation;
  105. import com.android.settings.notification.ZenModeSettings;
  106. import com.android.settings.print.PrintJobSettingsFragment;
  107. import com.android.settings.print.PrintSettingsFragment;
  108. import com.android.settings.privacyguard.PrivacyGuardPrefs;
  109. import com.android.settings.sim.SimSettings;
  110. import com.android.settings.tts.TextToSpeechSettings;
  111. import com.android.settings.users.UserSettings;
  112. import com.android.settings.voice.VoiceInputSettings;
  113. import com.android.settings.vpn2.VpnSettings;
  114. import com.android.settings.wfd.WifiDisplaySettings;
  115. import com.android.settings.widget.SwitchBar;
  116. import com.android.settings.wifi.AdvancedWifiSettings;
  117. import com.android.settings.wifi.SavedAccessPointsWifiSettings;
  118. import com.android.settings.wifi.WifiSettings;
  119. import com.android.settings.wifi.p2p.WifiP2pSettings;
  120.  
  121. import org.xmlpull.v1.XmlPullParser;
  122. import org.xmlpull.v1.XmlPullParserException;
  123.  
  124. import java.io.IOException;
  125. import java.util.ArrayList;
  126. import java.util.List;
  127. import java.util.Set;
  128.  
  129. import static com.android.settings.dashboard.DashboardTile.TILE_ID_UNDEFINED;
  130.  
  131. public class SettingsActivity extends Activity
  132. implements PreferenceManager.OnPreferenceTreeClickListener,
  133. PreferenceFragment.OnPreferenceStartFragmentCallback,
  134. ButtonBarHandler, FragmentManager.OnBackStackChangedListener,
  135. SearchView.OnQueryTextListener, SearchView.OnCloseListener,
  136. MenuItem.OnActionExpandListener {
  137.  
  138. private static final String LOG_TAG = "Settings";
  139.  
  140. // Constants for state save/restore
  141. private static final String SAVE_KEY_CATEGORIES = ":settings:categories";
  142. private static final String SAVE_KEY_SEARCH_MENU_EXPANDED = ":settings:search_menu_expanded";
  143. private static final String SAVE_KEY_SEARCH_QUERY = ":settings:search_query";
  144. private static final String SAVE_KEY_SHOW_HOME_AS_UP = ":settings:show_home_as_up";
  145. private static final String SAVE_KEY_SHOW_SEARCH = ":settings:show_search";
  146. private static final String SAVE_KEY_HOME_ACTIVITIES_COUNT = ":settings:home_activities_count";
  147.  
  148. /**
  149. * When starting this activity, the invoking Intent can contain this extra
  150. * string to specify which fragment should be initially displayed.
  151. * <p/>Starting from Key Lime Pie, when this argument is passed in, the activity
  152. * will call isValidFragment() to confirm that the fragment class name is valid for this
  153. * activity.
  154. */
  155. public static final String EXTRA_SHOW_FRAGMENT = ":settings:show_fragment";
  156.  
  157. /**
  158. * When starting this activity and using {@link #EXTRA_SHOW_FRAGMENT},
  159. * this extra can also be specified to supply a Bundle of arguments to pass
  160. * to that fragment when it is instantiated during the initial creation
  161. * of the activity.
  162. */
  163. public static final String EXTRA_SHOW_FRAGMENT_ARGUMENTS = ":settings:show_fragment_args";
  164.  
  165. /**
  166. * Fragment "key" argument passed thru {@link #EXTRA_SHOW_FRAGMENT_ARGUMENTS}
  167. */
  168. public static final String EXTRA_FRAGMENT_ARG_KEY = ":settings:fragment_args_key";
  169.  
  170. public static final String BACK_STACK_PREFS = ":settings:prefs";
  171.  
  172. // extras that allow any preference activity to be launched as part of a wizard
  173.  
  174. // show Back and Next buttons? takes boolean parameter
  175. // Back will then return RESULT_CANCELED and Next RESULT_OK
  176. protected static final String EXTRA_PREFS_SHOW_BUTTON_BAR = "extra_prefs_show_button_bar";
  177.  
  178. // add a Skip button?
  179. private static final String EXTRA_PREFS_SHOW_SKIP = "extra_prefs_show_skip";
  180.  
  181. // specify custom text for the Back or Next buttons, or cause a button to not appear
  182. // at all by setting it to null
  183. protected static final String EXTRA_PREFS_SET_NEXT_TEXT = "extra_prefs_set_next_text";
  184. protected static final String EXTRA_PREFS_SET_BACK_TEXT = "extra_prefs_set_back_text";
  185.  
  186. /**
  187. * When starting this activity and using {@link #EXTRA_SHOW_FRAGMENT},
  188. * those extra can also be specify to supply the title or title res id to be shown for
  189. * that fragment.
  190. */
  191. public static final String EXTRA_SHOW_FRAGMENT_TITLE = ":settings:show_fragment_title";
  192. public static final String EXTRA_SHOW_FRAGMENT_TITLE_RESID =
  193. ":settings:show_fragment_title_resid";
  194. public static final String EXTRA_SHOW_FRAGMENT_AS_SHORTCUT =
  195. ":settings:show_fragment_as_shortcut";
  196.  
  197. public static final String EXTRA_SHOW_FRAGMENT_AS_SUBSETTING =
  198. ":settings:show_fragment_as_subsetting";
  199.  
  200. private static final String META_DATA_KEY_FRAGMENT_CLASS =
  201. "com.android.settings.FRAGMENT_CLASS";
  202.  
  203. private static final String EXTRA_UI_OPTIONS = "settings:ui_options";
  204.  
  205. private static final String EMPTY_QUERY = "";
  206.  
  207. private static boolean sShowNoHomeNotice = false;
  208.  
  209. private String mFragmentClass;
  210.  
  211. private CharSequence mInitialTitle;
  212. private int mInitialTitleResId;
  213.  
  214. private NFCProfileTagCallback mNfcProfileCallback;
  215.  
  216. // Show only these settings for restricted users
  217. private int[] SETTINGS_FOR_RESTRICTED = {
  218. R.id.wireless_section,
  219. R.id.wifi_settings,
  220. R.id.bluetooth_settings,
  221. R.id.data_usage_settings,
  222. R.id.sim_settings,
  223. R.id.wireless_settings,
  224. R.id.button_settings,
  225. R.id.privacy_settings_liquidsmooth,
  226. R.id.main_settings,
  227. R.id.device_section,
  228. R.id.notification_settings,
  229. R.id.display_settings,
  230. R.id.storage_settings,
  231. R.id.application_settings,
  232. R.id.battery_settings,
  233. R.id.personal_section,
  234. R.id.profile_settings,
  235. R.id.location_settings,
  236. R.id.security_settings,
  237. R.id.language_settings,
  238. R.id.user_settings,
  239. R.id.account_settings,
  240. R.id.system_section,
  241. R.id.date_time_settings,
  242. R.id.about_settings,
  243. R.id.accessibility_settings,
  244. R.id.print_settings,
  245. R.id.superuser_settings,
  246. R.id.nfc_payment_settings,
  247. R.id.home_settings,
  248. R.id.dashboard
  249. };
  250.  
  251. private static final String[] ENTRY_FRAGMENTS = {
  252. WirelessSettings.class.getName(),
  253. WifiSettings.class.getName(),
  254. AdvancedWifiSettings.class.getName(),
  255. SavedAccessPointsWifiSettings.class.getName(),
  256. BluetoothSettings.class.getName(),
  257. SimSettings.class.getName(),
  258. TetherSettings.class.getName(),
  259. WifiP2pSettings.class.getName(),
  260. VpnSettings.class.getName(),
  261. DateTimeSettings.class.getName(),
  262. LocalePicker.class.getName(),
  263. InputMethodAndLanguageSettings.class.getName(),
  264. VoiceInputSettings.class.getName(),
  265. SpellCheckersSettings.class.getName(),
  266. UserDictionaryList.class.getName(),
  267. UserDictionarySettings.class.getName(),
  268. HomeSettings.class.getName(),
  269. DisplaySettings.class.getName(),
  270. DeviceInfoSettings.class.getName(),
  271. ManageApplications.class.getName(),
  272. ProcessStatsUi.class.getName(),
  273. NotificationStation.class.getName(),
  274. LocationSettings.class.getName(),
  275. SecuritySettings.class.getName(),
  276. UsageAccessSettings.class.getName(),
  277. PrivacySettings.class.getName(),
  278. DeviceAdminSettings.class.getName(),
  279. AccessibilitySettings.class.getName(),
  280. CaptionPropertiesFragment.class.getName(),
  281. com.android.settings.accessibility.ToggleDaltonizerPreferenceFragment.class.getName(),
  282. TextToSpeechSettings.class.getName(),
  283. Memory.class.getName(),
  284. DevelopmentSettings.class.getName(),
  285. UsbSettings.class.getName(),
  286. AndroidBeam.class.getName(),
  287. WifiDisplaySettings.class.getName(),
  288. PowerUsageSummary.class.getName(),
  289. AccountSyncSettings.class.getName(),
  290. AccountSettings.class.getName(),
  291. CryptKeeperSettings.class.getName(),
  292. DataUsageSummary.class.getName(),
  293. DreamSettings.class.getName(),
  294. UserSettings.class.getName(),
  295. NotificationAccessSettings.class.getName(),
  296. ConditionProviderSettings.class.getName(),
  297. PrintSettingsFragment.class.getName(),
  298. PrintJobSettingsFragment.class.getName(),
  299. TrustedCredentialsSettings.class.getName(),
  300. PaymentSettings.class.getName(),
  301. KeyboardLayoutPickerFragment.class.getName(),
  302. ZenModeSettings.class.getName(),
  303. NotificationSettings.class.getName(),
  304. ChooseLockPassword.ChooseLockPasswordFragment.class.getName(),
  305. ChooseLockPattern.ChooseLockPatternFragment.class.getName(),
  306. InstalledAppDetails.class.getName(),
  307. BatterySaverSettings.class.getName(),
  308. NotificationAppList.class.getName(),
  309. AppNotificationSettings.class.getName(),
  310. OtherSoundSettings.class.getName(),
  311. QuickLaunchSettings.class.getName(),
  312. ApnSettings.class.getName(),
  313. MainSettings.class.getName(),
  314. BlacklistSettings.class.getName(),
  315. com.android.settings.liquid.PrivacySettings.class.getName()
  316. };
  317.  
  318.  
  319. private static final String[] LIKE_SHORTCUT_INTENT_ACTION_ARRAY = {
  320. "android.settings.APPLICATION_DETAILS_SETTINGS"
  321. };
  322.  
  323. private SharedPreferences mDevelopmentPreferences;
  324. private SharedPreferences.OnSharedPreferenceChangeListener mDevelopmentPreferencesListener;
  325.  
  326. private boolean mBatteryPresent = true;
  327. private BroadcastReceiver mBatteryInfoReceiver = new BroadcastReceiver() {
  328. @Override
  329. public void onReceive(Context context, Intent intent) {
  330. String action = intent.getAction();
  331. if (Intent.ACTION_BATTERY_CHANGED.equals(action)) {
  332. boolean batteryPresent = Utils.isBatteryPresent(intent);
  333.  
  334. if (mBatteryPresent != batteryPresent) {
  335. mBatteryPresent = batteryPresent;
  336. invalidateCategories(true);
  337. }
  338. }
  339. }
  340. };
  341.  
  342. private final DynamicIndexableContentMonitor mDynamicIndexableContentMonitor =
  343. new DynamicIndexableContentMonitor();
  344.  
  345. private ActionBar mActionBar;
  346. private SwitchBar mSwitchBar;
  347.  
  348. private Button mNextButton;
  349.  
  350. private boolean mDisplayHomeAsUpEnabled;
  351. private boolean mDisplaySearch;
  352.  
  353. private boolean mIsShowingDashboard;
  354. private boolean mIsShortcut;
  355.  
  356. private ViewGroup mContent;
  357.  
  358. private SearchView mSearchView;
  359. private MenuItem mSearchMenuItem;
  360. private boolean mSearchMenuItemExpanded = false;
  361. private SearchResultsSummary mSearchResultsFragment;
  362. private String mSearchQuery;
  363.  
  364. // Categories
  365. private ArrayList<DashboardCategory> mCategories = new ArrayList<DashboardCategory>();
  366.  
  367. private static final String MSG_DATA_FORCE_REFRESH = "msg_data_force_refresh";
  368. private static final int MSG_BUILD_CATEGORIES = 1;
  369. private Handler mHandler = new Handler() {
  370. @Override
  371. public void handleMessage(Message msg) {
  372. switch (msg.what) {
  373. case MSG_BUILD_CATEGORIES: {
  374. final boolean forceRefresh = msg.getData().getBoolean(MSG_DATA_FORCE_REFRESH);
  375. if (forceRefresh) {
  376. buildDashboardCategories(mCategories);
  377. }
  378. } break;
  379. }
  380. }
  381. };
  382.  
  383. private boolean mNeedToRevertToInitialFragment = false;
  384. private int mHomeActivitiesCount = 1;
  385.  
  386. private Intent mResultIntentData;
  387.  
  388. public SwitchBar getSwitchBar() {
  389. return mSwitchBar;
  390. }
  391.  
  392. public List<DashboardCategory> getDashboardCategories(boolean forceRefresh) {
  393. if (forceRefresh || mCategories.size() == 0) {
  394. buildDashboardCategories(mCategories);
  395. }
  396. return mCategories;
  397. }
  398.  
  399. @Override
  400. public boolean onPreferenceStartFragment(PreferenceFragment caller, Preference pref) {
  401. // Override the fragment title for Wallpaper settings
  402. int titleRes = pref.getTitleRes();
  403. if (pref.getFragment().equals(WallpaperTypeSettings.class.getName())) {
  404. titleRes = R.string.wallpaper_settings_fragment_title;
  405. } else if (pref.getFragment().equals(OwnerInfoSettings.class.getName())
  406. && UserHandle.myUserId() != UserHandle.USER_OWNER) {
  407. if (UserManager.get(this).isLinkedUser()) {
  408. titleRes = R.string.profile_info_settings_title;
  409. } else {
  410. titleRes = R.string.user_info_settings_title;
  411. }
  412. }
  413. startPreferencePanel(pref.getFragment(), pref.getExtras(), titleRes, pref.getTitle(),
  414. null, 0);
  415. return true;
  416. }
  417.  
  418. @Override
  419. public boolean onPreferenceTreeClick(PreferenceScreen preferenceScreen, Preference preference) {
  420. return false;
  421. }
  422.  
  423. private void invalidateCategories(boolean forceRefresh) {
  424. if (!mHandler.hasMessages(MSG_BUILD_CATEGORIES)) {
  425. Message msg = new Message();
  426. msg.what = MSG_BUILD_CATEGORIES;
  427. msg.getData().putBoolean(MSG_DATA_FORCE_REFRESH, forceRefresh);
  428. }
  429. }
  430.  
  431. @Override
  432. public void onConfigurationChanged(Configuration newConfig) {
  433. super.onConfigurationChanged(newConfig);
  434. Index.getInstance(this).update();
  435. }
  436.  
  437. @Override
  438. protected void onStart() {
  439. super.onStart();
  440.  
  441. if (mNeedToRevertToInitialFragment) {
  442. revertToInitialFragment();
  443. }
  444. }
  445.  
  446. @Override
  447. public boolean onCreateOptionsMenu(Menu menu) {
  448. if (!mDisplaySearch) {
  449. return false;
  450. }
  451.  
  452. MenuInflater inflater = getMenuInflater();
  453. inflater.inflate(R.menu.options_menu, menu);
  454.  
  455. // Cache the search query (can be overriden by the OnQueryTextListener)
  456. final String query = mSearchQuery;
  457.  
  458. mSearchMenuItem = menu.findItem(R.id.search);
  459. mSearchView = (SearchView) mSearchMenuItem.getActionView();
  460.  
  461. if (mSearchMenuItem == null || mSearchView == null) {
  462. return false;
  463. }
  464.  
  465. if (mSearchResultsFragment != null) {
  466. mSearchResultsFragment.setSearchView(mSearchView);
  467. }
  468.  
  469. mSearchMenuItem.setOnActionExpandListener(this);
  470. mSearchView.setOnQueryTextListener(this);
  471. mSearchView.setOnCloseListener(this);
  472.  
  473. if (mSearchMenuItemExpanded) {
  474. mSearchMenuItem.expandActionView();
  475. }
  476. mSearchView.setQuery(query, true /* submit */);
  477.  
  478. return true;
  479. }
  480.  
  481. private static boolean isShortCutIntent(final Intent intent) {
  482. Set<String> categories = intent.getCategories();
  483. return (categories != null) && categories.contains("com.android.settings.SHORTCUT");
  484. }
  485.  
  486. private static boolean isLikeShortCutIntent(final Intent intent) {
  487. String action = intent.getAction();
  488. if (action == null) {
  489. return false;
  490. }
  491. for (int i = 0; i < LIKE_SHORTCUT_INTENT_ACTION_ARRAY.length; i++) {
  492. if (LIKE_SHORTCUT_INTENT_ACTION_ARRAY[i].equals(action)) return true;
  493. }
  494. return false;
  495. }
  496.  
  497. @Override
  498. protected void onCreate(Bundle savedState) {
  499. super.onCreate(savedState);
  500.  
  501. // Should happen before any call to getIntent()
  502. getMetaData();
  503.  
  504. final Intent intent = getIntent();
  505. if (intent.hasExtra(EXTRA_UI_OPTIONS)) {
  506. getWindow().setUiOptions(intent.getIntExtra(EXTRA_UI_OPTIONS, 0));
  507. }
  508.  
  509. mDevelopmentPreferences = getSharedPreferences(DevelopmentSettings.PREF_FILE,
  510. Context.MODE_PRIVATE);
  511.  
  512. // Getting Intent properties can only be done after the super.onCreate(...)
  513. final String initialFragmentName = intent.getStringExtra(EXTRA_SHOW_FRAGMENT);
  514.  
  515. mIsShortcut = isShortCutIntent(intent) || isLikeShortCutIntent(intent) ||
  516. intent.getBooleanExtra(EXTRA_SHOW_FRAGMENT_AS_SHORTCUT, false);
  517.  
  518. final ComponentName cn = intent.getComponent();
  519. final String className = cn.getClassName();
  520.  
  521. mIsShowingDashboard = className.equals(Settings.class.getName());
  522.  
  523. // This is a "Sub Settings" when:
  524. // - this is a real SubSettings
  525. // - or :settings:show_fragment_as_subsetting is passed to the Intent
  526. final boolean isSubSettings = className.equals(SubSettings.class.getName()) ||
  527. intent.getBooleanExtra(EXTRA_SHOW_FRAGMENT_AS_SUBSETTING, false);
  528.  
  529. // If this is a sub settings, then apply the SubSettings Theme for the ActionBar content insets
  530. if (isSubSettings) {
  531. // Check also that we are not a Theme Dialog as we don't want to override them
  532. final int themeResId = getThemeResId();
  533. if (themeResId != R.style.Theme_DialogWhenLarge &&
  534. themeResId != R.style.Theme_SubSettingsDialogWhenLarge) {
  535. setTheme(R.style.Theme_SubSettings);
  536. }
  537. }
  538.  
  539. setContentView(mIsShowingDashboard ?
  540. R.layout.settings_main_dashboard : R.layout.settings_main_prefs);
  541.  
  542. mContent = (ViewGroup) findViewById(R.id.main_content);
  543.  
  544. getFragmentManager().addOnBackStackChangedListener(this);
  545.  
  546. if (mIsShowingDashboard) {
  547. Index.getInstance(getApplicationContext()).update();
  548. }
  549.  
  550. if (savedState != null) {
  551. // We are restarting from a previous saved state; used that to initialize, instead
  552. // of starting fresh.
  553. mSearchMenuItemExpanded = savedState.getBoolean(SAVE_KEY_SEARCH_MENU_EXPANDED);
  554. mSearchQuery = savedState.getString(SAVE_KEY_SEARCH_QUERY);
  555.  
  556. setTitleFromIntent(intent);
  557.  
  558. ArrayList<DashboardCategory> categories =
  559. savedState.getParcelableArrayList(SAVE_KEY_CATEGORIES);
  560. if (categories != null) {
  561. mCategories.clear();
  562. mCategories.addAll(categories);
  563. setTitleFromBackStack();
  564. }
  565.  
  566. mDisplayHomeAsUpEnabled = savedState.getBoolean(SAVE_KEY_SHOW_HOME_AS_UP);
  567. mDisplaySearch = savedState.getBoolean(SAVE_KEY_SHOW_SEARCH);
  568. mHomeActivitiesCount = savedState.getInt(SAVE_KEY_HOME_ACTIVITIES_COUNT,
  569. 1 /* one home activity by default */);
  570. } else {
  571. if (!mIsShowingDashboard) {
  572. // Search is shown we are launched thru a Settings "shortcut". UP will be shown
  573. // only if it is a sub settings
  574. if (mIsShortcut) {
  575. mDisplayHomeAsUpEnabled = isSubSettings;
  576. mDisplaySearch = false;
  577. } else if (isSubSettings) {
  578. mDisplayHomeAsUpEnabled = true;
  579. mDisplaySearch = true;
  580. } else {
  581. mDisplayHomeAsUpEnabled = false;
  582. mDisplaySearch = false;
  583. }
  584. setTitleFromIntent(intent);
  585.  
  586. Bundle initialArguments = intent.getBundleExtra(EXTRA_SHOW_FRAGMENT_ARGUMENTS);
  587. switchToFragment(initialFragmentName, initialArguments, true, false,
  588. mInitialTitleResId, mInitialTitle, false);
  589. } else {
  590. // No UP affordance if we are displaying the main Dashboard
  591. mDisplayHomeAsUpEnabled = false;
  592. // Show Search affordance
  593. mDisplaySearch = true;
  594. mInitialTitleResId = R.string.dashboard_title;
  595. switchToFragment(DashboardSummary.class.getName(), null, false, false,
  596. mInitialTitleResId, mInitialTitle, false);
  597. }
  598. }
  599.  
  600. mActionBar = getActionBar();
  601. if (mActionBar != null) {
  602. mActionBar.setDisplayHomeAsUpEnabled(mDisplayHomeAsUpEnabled);
  603. mActionBar.setHomeButtonEnabled(mDisplayHomeAsUpEnabled);
  604. }
  605. mSwitchBar = (SwitchBar) findViewById(R.id.switch_bar);
  606.  
  607. // see if we should show Back/Next buttons
  608. if (intent.getBooleanExtra(EXTRA_PREFS_SHOW_BUTTON_BAR, false)) {
  609.  
  610. View buttonBar = findViewById(R.id.button_bar);
  611. if (buttonBar != null) {
  612. buttonBar.setVisibility(View.VISIBLE);
  613.  
  614. Button backButton = (Button)findViewById(R.id.back_button);
  615. backButton.setOnClickListener(new OnClickListener() {
  616. public void onClick(View v) {
  617. setResult(RESULT_CANCELED, getResultIntentData());
  618. finish();
  619. }
  620. });
  621. Button skipButton = (Button)findViewById(R.id.skip_button);
  622. skipButton.setOnClickListener(new OnClickListener() {
  623. public void onClick(View v) {
  624. setResult(RESULT_OK, getResultIntentData());
  625. finish();
  626. }
  627. });
  628. mNextButton = (Button)findViewById(R.id.next_button);
  629. mNextButton.setOnClickListener(new OnClickListener() {
  630. public void onClick(View v) {
  631. setResult(RESULT_OK, getResultIntentData());
  632. finish();
  633. }
  634. });
  635.  
  636. // set our various button parameters
  637. if (intent.hasExtra(EXTRA_PREFS_SET_NEXT_TEXT)) {
  638. String buttonText = intent.getStringExtra(EXTRA_PREFS_SET_NEXT_TEXT);
  639. if (TextUtils.isEmpty(buttonText)) {
  640. mNextButton.setVisibility(View.GONE);
  641. }
  642. else {
  643. mNextButton.setText(buttonText);
  644. }
  645. }
  646. if (intent.hasExtra(EXTRA_PREFS_SET_BACK_TEXT)) {
  647. String buttonText = intent.getStringExtra(EXTRA_PREFS_SET_BACK_TEXT);
  648. if (TextUtils.isEmpty(buttonText)) {
  649. backButton.setVisibility(View.GONE);
  650. }
  651. else {
  652. backButton.setText(buttonText);
  653. }
  654. }
  655. if (intent.getBooleanExtra(EXTRA_PREFS_SHOW_SKIP, false)) {
  656. skipButton.setVisibility(View.VISIBLE);
  657. }
  658. }
  659. }
  660.  
  661. mHomeActivitiesCount = getHomeActivitiesCount();
  662. }
  663.  
  664. private int getHomeActivitiesCount() {
  665. final ArrayList<ResolveInfo> homeApps = new ArrayList<ResolveInfo>();
  666. getPackageManager().getHomeActivities(homeApps);
  667. return homeApps.size();
  668. }
  669.  
  670. private void setTitleFromIntent(Intent intent) {
  671. final int initialTitleResId = intent.getIntExtra(EXTRA_SHOW_FRAGMENT_TITLE_RESID, -1);
  672. if (initialTitleResId > 0) {
  673. mInitialTitle = null;
  674. mInitialTitleResId = initialTitleResId;
  675. setTitle(mInitialTitleResId);
  676. } else {
  677. mInitialTitleResId = -1;
  678. final String initialTitle = intent.getStringExtra(EXTRA_SHOW_FRAGMENT_TITLE);
  679. mInitialTitle = (initialTitle != null) ? initialTitle : getTitle();
  680. setTitle(mInitialTitle);
  681. }
  682. }
  683.  
  684. @Override
  685. public void onBackStackChanged() {
  686. setTitleFromBackStack();
  687. }
  688.  
  689. private int setTitleFromBackStack() {
  690. final int count = getFragmentManager().getBackStackEntryCount();
  691.  
  692. if (count == 0) {
  693. if (mInitialTitleResId > 0) {
  694. setTitle(mInitialTitleResId);
  695. } else {
  696. setTitle(mInitialTitle);
  697. }
  698. return 0;
  699. }
  700.  
  701. FragmentManager.BackStackEntry bse = getFragmentManager().getBackStackEntryAt(count - 1);
  702. setTitleFromBackStackEntry(bse);
  703.  
  704. return count;
  705. }
  706.  
  707. private void setTitleFromBackStackEntry(FragmentManager.BackStackEntry bse) {
  708. final CharSequence title;
  709. final int titleRes = bse.getBreadCrumbTitleRes();
  710. if (titleRes > 0) {
  711. title = getText(titleRes);
  712. } else {
  713. title = bse.getBreadCrumbTitle();
  714. }
  715. if (title != null) {
  716. setTitle(title);
  717. }
  718. }
  719.  
  720. @Override
  721. protected void onSaveInstanceState(Bundle outState) {
  722. super.onSaveInstanceState(outState);
  723.  
  724. if (mCategories.size() > 0) {
  725. outState.putParcelableArrayList(SAVE_KEY_CATEGORIES, mCategories);
  726. }
  727.  
  728. outState.putBoolean(SAVE_KEY_SHOW_HOME_AS_UP, mDisplayHomeAsUpEnabled);
  729. outState.putBoolean(SAVE_KEY_SHOW_SEARCH, mDisplaySearch);
  730.  
  731. if (mDisplaySearch) {
  732. // The option menus are created if the ActionBar is visible and they are also created
  733. // asynchronously. If you launch Settings with an Intent action like
  734. // android.intent.action.POWER_USAGE_SUMMARY and at the same time your device is locked
  735. // thru a LockScreen, onCreateOptionsMenu() is not yet called and references to the search
  736. // menu item and search view are null.
  737. boolean isExpanded = (mSearchMenuItem != null) && mSearchMenuItem.isActionViewExpanded();
  738. outState.putBoolean(SAVE_KEY_SEARCH_MENU_EXPANDED, isExpanded);
  739.  
  740. String query = (mSearchView != null) ? mSearchView.getQuery().toString() : EMPTY_QUERY;
  741. outState.putString(SAVE_KEY_SEARCH_QUERY, query);
  742. }
  743.  
  744. outState.putInt(SAVE_KEY_HOME_ACTIVITIES_COUNT, mHomeActivitiesCount);
  745. }
  746.  
  747. @Override
  748. public void onResume() {
  749. super.onResume();
  750.  
  751. final int newHomeActivityCount = getHomeActivitiesCount();
  752. if (newHomeActivityCount != mHomeActivitiesCount) {
  753. mHomeActivitiesCount = newHomeActivityCount;
  754. invalidateCategories(true);
  755. }
  756.  
  757. mDevelopmentPreferencesListener = new SharedPreferences.OnSharedPreferenceChangeListener() {
  758. @Override
  759. public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {
  760. invalidateCategories(true);
  761. }
  762. };
  763. mDevelopmentPreferences.registerOnSharedPreferenceChangeListener(
  764. mDevelopmentPreferencesListener);
  765.  
  766. registerReceiver(mBatteryInfoReceiver, new IntentFilter(Intent.ACTION_BATTERY_CHANGED));
  767.  
  768. mDynamicIndexableContentMonitor.register(this);
  769.  
  770. if(mDisplaySearch && !TextUtils.isEmpty(mSearchQuery)) {
  771. onQueryTextSubmit(mSearchQuery);
  772. }
  773. }
  774.  
  775. @Override
  776. public void onPause() {
  777. super.onPause();
  778.  
  779. unregisterReceiver(mBatteryInfoReceiver);
  780. mDynamicIndexableContentMonitor.unregister();
  781. }
  782.  
  783. @Override
  784. public void onDestroy() {
  785. super.onDestroy();
  786.  
  787. mDevelopmentPreferences.unregisterOnSharedPreferenceChangeListener(
  788. mDevelopmentPreferencesListener);
  789. mDevelopmentPreferencesListener = null;
  790. }
  791.  
  792. protected boolean isValidFragment(String fragmentName) {
  793. // Almost all fragments are wrapped in this,
  794. // except for a few that have their own activities.
  795. for (int i = 0; i < ENTRY_FRAGMENTS.length; i++) {
  796. if (ENTRY_FRAGMENTS[i].equals(fragmentName)) return true;
  797. }
  798. return false;
  799. }
  800.  
  801. @Override
  802. public Intent getIntent() {
  803. Intent superIntent = super.getIntent();
  804. String startingFragment = getStartingFragmentClass(superIntent);
  805. // This is called from super.onCreate, isMultiPane() is not yet reliable
  806. // Do not use onIsHidingHeaders either, which relies itself on this method
  807. if (startingFragment != null) {
  808. Intent modIntent = new Intent(superIntent);
  809. modIntent.putExtra(EXTRA_SHOW_FRAGMENT, startingFragment);
  810. Bundle args = superIntent.getExtras();
  811. if (args != null) {
  812. args = new Bundle(args);
  813. } else {
  814. args = new Bundle();
  815. }
  816. args.putParcelable("intent", superIntent);
  817. modIntent.putExtra(EXTRA_SHOW_FRAGMENT_ARGUMENTS, args);
  818. return modIntent;
  819. }
  820. return superIntent;
  821. }
  822.  
  823. /**
  824. * Checks if the component name in the intent is different from the Settings class and
  825. * returns the class name to load as a fragment.
  826. */
  827. private String getStartingFragmentClass(Intent intent) {
  828. if (mFragmentClass != null) return mFragmentClass;
  829.  
  830. String intentClass = intent.getComponent().getClassName();
  831. if (intentClass.equals(getClass().getName())) return null;
  832.  
  833. if ("com.android.settings.ManageApplications".equals(intentClass)
  834. || "com.android.settings.RunningServices".equals(intentClass)
  835. || "com.android.settings.applications.StorageUse".equals(intentClass)) {
  836. // Old names of manage apps.
  837. intentClass = com.android.settings.applications.ManageApplications.class.getName();
  838. }
  839.  
  840. return intentClass;
  841. }
  842.  
  843. /**
  844. * Start a new fragment containing a preference panel. If the preferences
  845. * are being displayed in multi-pane mode, the given fragment class will
  846. * be instantiated and placed in the appropriate pane. If running in
  847. * single-pane mode, a new activity will be launched in which to show the
  848. * fragment.
  849. *
  850. * @param fragmentClass Full name of the class implementing the fragment.
  851. * @param args Any desired arguments to supply to the fragment.
  852. * @param titleRes Optional resource identifier of the title of this
  853. * fragment.
  854. * @param titleText Optional text of the title of this fragment.
  855. * @param resultTo Optional fragment that result data should be sent to.
  856. * If non-null, resultTo.onActivityResult() will be called when this
  857. * preference panel is done. The launched panel must use
  858. * {@link #finishPreferencePanel(Fragment, int, Intent)} when done.
  859. * @param resultRequestCode If resultTo is non-null, this is the caller's
  860. * request code to be received with the result.
  861. */
  862. public void startPreferencePanel(String fragmentClass, Bundle args, int titleRes,
  863. CharSequence titleText, Fragment resultTo, int resultRequestCode) {
  864. String title = null;
  865. if (titleRes < 0) {
  866. if (titleText != null) {
  867. title = titleText.toString();
  868. } else {
  869. // There not much we can do in that case
  870. title = "";
  871. }
  872. }
  873. Utils.startWithFragment(this, fragmentClass, args, resultTo, resultRequestCode,
  874. titleRes, title, mIsShortcut);
  875. }
  876.  
  877. /**
  878. * Start a new fragment in a new activity containing a preference panel for a given user. If the
  879. * preferences are being displayed in multi-pane mode, the given fragment class will be
  880. * instantiated and placed in the appropriate pane. If running in single-pane mode, a new
  881. * activity will be launched in which to show the fragment.
  882. *
  883. * @param fragmentClass Full name of the class implementing the fragment.
  884. * @param args Any desired arguments to supply to the fragment.
  885. * @param titleRes Optional resource identifier of the title of this fragment.
  886. * @param titleText Optional text of the title of this fragment.
  887. * @param userHandle The user for which the panel has to be started.
  888. */
  889. public void startPreferencePanelAsUser(String fragmentClass, Bundle args, int titleRes,
  890. CharSequence titleText, UserHandle userHandle) {
  891. String title = null;
  892. if (titleRes < 0) {
  893. if (titleText != null) {
  894. title = titleText.toString();
  895. } else {
  896. // There not much we can do in that case
  897. title = "";
  898. }
  899. }
  900. Utils.startWithFragmentAsUser(this, fragmentClass, args,
  901. titleRes, title, mIsShortcut, userHandle);
  902. }
  903.  
  904. /**
  905. * Called by a preference panel fragment to finish itself.
  906. *
  907. * @param caller The fragment that is asking to be finished.
  908. * @param resultCode Optional result code to send back to the original
  909. * launching fragment.
  910. * @param resultData Optional result data to send back to the original
  911. * launching fragment.
  912. */
  913. public void finishPreferencePanel(Fragment caller, int resultCode, Intent resultData) {
  914. setResult(resultCode, resultData);
  915. finish();
  916. }
  917.  
  918. /**
  919. * Start a new fragment.
  920. *
  921. * @param fragment The fragment to start
  922. * @param push If true, the current fragment will be pushed onto the back stack. If false,
  923. * the current fragment will be replaced.
  924. */
  925. public void startPreferenceFragment(Fragment fragment, boolean push) {
  926. FragmentTransaction transaction = getFragmentManager().beginTransaction();
  927. transaction.replace(R.id.main_content, fragment);
  928. if (push) {
  929. transaction.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN);
  930. transaction.addToBackStack(BACK_STACK_PREFS);
  931. } else {
  932. transaction.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_FADE);
  933. }
  934. transaction.commitAllowingStateLoss();
  935. }
  936.  
  937. /**
  938. * Switch to a specific Fragment with taking care of validation, Title and BackStack
  939. */
  940. private Fragment switchToFragment(String fragmentName, Bundle args, boolean validate,
  941. boolean addToBackStack, int titleResId, CharSequence title, boolean withTransition) {
  942. if (validate && !isValidFragment(fragmentName)) {
  943. throw new IllegalArgumentException("Invalid fragment for this activity: "
  944. + fragmentName);
  945. }
  946. Fragment f = Fragment.instantiate(this, fragmentName, args);
  947. FragmentTransaction transaction = getFragmentManager().beginTransaction();
  948. transaction.replace(R.id.main_content, f);
  949. if (withTransition) {
  950. TransitionManager.beginDelayedTransition(mContent);
  951. }
  952. if (addToBackStack) {
  953. transaction.addToBackStack(SettingsActivity.BACK_STACK_PREFS);
  954. }
  955. if (titleResId > 0) {
  956. transaction.setBreadCrumbTitle(titleResId);
  957. } else if (title != null) {
  958. transaction.setBreadCrumbTitle(title);
  959. }
  960. transaction.commitAllowingStateLoss();
  961. getFragmentManager().executePendingTransactions();
  962. return f;
  963. }
  964.  
  965. /**
  966. * Called when the activity needs its list of categories/tiles built.
  967. *
  968. * @param categories The list in which to place the tiles categories.
  969. */
  970. private void buildDashboardCategories(List<DashboardCategory> categories) {
  971. categories.clear();
  972. loadCategoriesFromResource(R.xml.dashboard_categories, categories);
  973. updateTilesList(categories);
  974. }
  975.  
  976. /**
  977. * Parse the given XML file as a categories description, adding each
  978. * parsed categories and tiles into the target list.
  979. *
  980. * @param resid The XML resource to load and parse.
  981. * @param target The list in which the parsed categories and tiles should be placed.
  982. */
  983. private void loadCategoriesFromResource(int resid, List<DashboardCategory> target) {
  984. XmlResourceParser parser = null;
  985. try {
  986. parser = getResources().getXml(resid);
  987. AttributeSet attrs = Xml.asAttributeSet(parser);
  988.  
  989. int type;
  990. while ((type=parser.next()) != XmlPullParser.END_DOCUMENT
  991. && type != XmlPullParser.START_TAG) {
  992. // Parse next until start tag is found
  993. }
  994.  
  995. String nodeName = parser.getName();
  996. if (!"dashboard-categories".equals(nodeName)) {
  997. throw new RuntimeException(
  998. "XML document must start with <preference-categories> tag; found"
  999. + nodeName + " at " + parser.getPositionDescription());
  1000. }
  1001.  
  1002. Bundle curBundle = null;
  1003.  
  1004. final int outerDepth = parser.getDepth();
  1005. while ((type=parser.next()) != XmlPullParser.END_DOCUMENT
  1006. && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) {
  1007. if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) {
  1008. continue;
  1009. }
  1010.  
  1011. nodeName = parser.getName();
  1012. if ("dashboard-category".equals(nodeName)) {
  1013. DashboardCategory category = new DashboardCategory();
  1014.  
  1015. TypedArray sa = obtainStyledAttributes(
  1016. attrs, com.android.internal.R.styleable.PreferenceHeader);
  1017. category.id = sa.getResourceId(
  1018. com.android.internal.R.styleable.PreferenceHeader_id,
  1019. (int)DashboardCategory.CAT_ID_UNDEFINED);
  1020.  
  1021. TypedValue tv = sa.peekValue(
  1022. com.android.internal.R.styleable.PreferenceHeader_title);
  1023. if (tv != null && tv.type == TypedValue.TYPE_STRING) {
  1024. if (tv.resourceId != 0) {
  1025. category.titleRes = tv.resourceId;
  1026. } else {
  1027. category.title = tv.string;
  1028. }
  1029. }
  1030. sa.recycle();
  1031.  
  1032. final int innerDepth = parser.getDepth();
  1033. while ((type=parser.next()) != XmlPullParser.END_DOCUMENT
  1034. && (type != XmlPullParser.END_TAG || parser.getDepth() > innerDepth)) {
  1035. if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) {
  1036. continue;
  1037. }
  1038.  
  1039. String innerNodeName = parser.getName();
  1040. if (innerNodeName.equals("dashboard-tile")) {
  1041. DashboardTile tile = new DashboardTile();
  1042.  
  1043. sa = obtainStyledAttributes(
  1044. attrs, com.android.internal.R.styleable.PreferenceHeader);
  1045. tile.id = sa.getResourceId(
  1046. com.android.internal.R.styleable.PreferenceHeader_id,
  1047. (int)TILE_ID_UNDEFINED);
  1048. tv = sa.peekValue(
  1049. com.android.internal.R.styleable.PreferenceHeader_title);
  1050. if (tv != null && tv.type == TypedValue.TYPE_STRING) {
  1051. if (tv.resourceId != 0) {
  1052. tile.titleRes = tv.resourceId;
  1053. } else {
  1054. tile.title = tv.string;
  1055. }
  1056. }
  1057. tv = sa.peekValue(
  1058. com.android.internal.R.styleable.PreferenceHeader_summary);
  1059. if (tv != null && tv.type == TypedValue.TYPE_STRING) {
  1060. if (tv.resourceId != 0) {
  1061. tile.summaryRes = tv.resourceId;
  1062. } else {
  1063. tile.summary = tv.string;
  1064. }
  1065. }
  1066. tile.iconRes = sa.getResourceId(
  1067. com.android.internal.R.styleable.PreferenceHeader_icon, 0);
  1068. tile.fragment = sa.getString(
  1069. com.android.internal.R.styleable.PreferenceHeader_fragment);
  1070. sa.recycle();
  1071.  
  1072. if (curBundle == null) {
  1073. curBundle = new Bundle();
  1074. }
  1075.  
  1076. final int innerDepth2 = parser.getDepth();
  1077. while ((type=parser.next()) != XmlPullParser.END_DOCUMENT
  1078. && (type != XmlPullParser.END_TAG || parser.getDepth() > innerDepth2)) {
  1079. if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) {
  1080. continue;
  1081. }
  1082.  
  1083. String innerNodeName2 = parser.getName();
  1084. if (innerNodeName2.equals("extra")) {
  1085. getResources().parseBundleExtra("extra", attrs, curBundle);
  1086. XmlUtils.skipCurrentTag(parser);
  1087.  
  1088. } else if (innerNodeName2.equals("intent")) {
  1089. tile.intent = Intent.parseIntent(getResources(), parser, attrs);
  1090.  
  1091. } else {
  1092. XmlUtils.skipCurrentTag(parser);
  1093. }
  1094. }
  1095.  
  1096. if (curBundle.size() > 0) {
  1097. tile.fragmentArguments = curBundle;
  1098. curBundle = null;
  1099. }
  1100.  
  1101. // Show the SIM Cards setting if there are more than 2 SIMs installed.
  1102. if(tile.id != R.id.sim_settings || Utils.showSimCardTile(this)){
  1103. category.addTile(tile);
  1104. }
  1105.  
  1106. } else {
  1107. XmlUtils.skipCurrentTag(parser);
  1108. }
  1109. }
  1110.  
  1111. target.add(category);
  1112. } else {
  1113. XmlUtils.skipCurrentTag(parser);
  1114. }
  1115. }
  1116.  
  1117. } catch (XmlPullParserException e) {
  1118. throw new RuntimeException("Error parsing categories", e);
  1119. } catch (IOException e) {
  1120. throw new RuntimeException("Error parsing categories", e);
  1121. } finally {
  1122. if (parser != null) parser.close();
  1123. }
  1124. }
  1125.  
  1126. private void updateTilesList(List<DashboardCategory> target) {
  1127. final boolean showDev = mDevelopmentPreferences.getBoolean(
  1128. DevelopmentSettings.PREF_SHOW,
  1129. android.os.Build.TYPE.equals("eng") || android.os.Build.TYPE.equals("userdebug"));
  1130.  
  1131. final UserManager um = (UserManager) getSystemService(Context.USER_SERVICE);
  1132.  
  1133. final int size = target.size();
  1134. for (int i = 0; i < size; i++) {
  1135.  
  1136. DashboardCategory category = target.get(i);
  1137.  
  1138. // Ids are integers, so downcasting is ok
  1139. int id = (int) category.id;
  1140. int n = category.getTilesCount() - 1;
  1141. while (n >= 0) {
  1142.  
  1143. DashboardTile tile = category.getTile(n);
  1144. boolean removeTile = false;
  1145. id = (int) tile.id;
  1146. if (id == R.id.operator_settings || id == R.id.manufacturer_settings) {
  1147. if (!Utils.updateTileToSpecificActivityFromMetaDataOrRemove(this, tile)) {
  1148. removeTile = true;
  1149. }
  1150. } else if (id == R.id.wifi_settings) {
  1151. // Remove WiFi Settings if WiFi service is not available.
  1152. if (!getPackageManager().hasSystemFeature(PackageManager.FEATURE_WIFI)) {
  1153. removeTile = true;
  1154. }
  1155. } else if (id == R.id.bluetooth_settings) {
  1156. // Remove Bluetooth Settings if Bluetooth service is not available.
  1157. if (!getPackageManager().hasSystemFeature(PackageManager.FEATURE_BLUETOOTH)) {
  1158. removeTile = true;
  1159. }
  1160. } else if (id == R.id.data_usage_settings) {
  1161. // Remove data usage when kernel module not enabled
  1162. final INetworkManagementService netManager = INetworkManagementService.Stub
  1163. .asInterface(ServiceManager.getService(Context.NETWORKMANAGEMENT_SERVICE));
  1164. try {
  1165. if (!netManager.isBandwidthControlEnabled()) {
  1166. removeTile = true;
  1167. }
  1168. } catch (RemoteException e) {
  1169. // ignored
  1170. }
  1171. } else if (id == R.id.battery_settings) {
  1172. // Remove battery settings when battery is not available. (e.g. TV)
  1173.  
  1174. if (!mBatteryPresent) {
  1175. removeTile = true;
  1176. }
  1177. } else if (id == R.id.home_settings) {
  1178. if (!updateHomeSettingTiles(tile)) {
  1179. removeTile = true;
  1180. }
  1181. } else if (id == R.id.user_settings) {
  1182. boolean hasMultipleUsers =
  1183. ((UserManager) getSystemService(Context.USER_SERVICE))
  1184. .getUserCount() > 1;
  1185. if (!UserHandle.MU_ENABLED
  1186. || (!UserManager.supportsMultipleUsers()
  1187. && !hasMultipleUsers)
  1188. || Utils.isMonkeyRunning()) {
  1189. removeTile = true;
  1190. }
  1191. } else if (id == R.id.nfc_payment_settings) {
  1192. if (!getPackageManager().hasSystemFeature(PackageManager.FEATURE_NFC)) {
  1193. removeTile = true;
  1194. } else {
  1195. // Only show if NFC is on and we have the HCE feature
  1196. NfcAdapter adapter = NfcAdapter.getDefaultAdapter(this);
  1197. if (adapter == null || !adapter.isEnabled() ||
  1198. !getPackageManager().hasSystemFeature(
  1199. PackageManager.FEATURE_NFC_HOST_CARD_EMULATION)) {
  1200. removeTile = true;
  1201. }
  1202. }
  1203. } else if (id == R.id.print_settings) {
  1204. boolean hasPrintingSupport = getPackageManager().hasSystemFeature(
  1205. PackageManager.FEATURE_PRINTING);
  1206. if (!hasPrintingSupport) {
  1207. removeTile = true;
  1208. }
  1209. } else if (id == R.id.development_settings) {
  1210. if (!showDev || um.hasUserRestriction(
  1211. UserManager.DISALLOW_DEBUGGING_FEATURES)) {
  1212. removeTile = true;
  1213. }
  1214. } else if (id == R.id.supersu_settings) {
  1215. // Embedding into Settings is supported from SuperSU v1.85 and up
  1216. boolean supported = false;
  1217. try {
  1218. supported = (getPackageManager().getPackageInfo("eu.chainfire.supersu", 0).versionCode >= 185);
  1219. } catch (PackageManager.NameNotFoundException e) {
  1220. }
  1221. if (!supported) {
  1222. removeTile = true;
  1223. }
  1224. } else if (id == R.id.button_settings) {
  1225. boolean hasDeviceKeys = getResources().getInteger(
  1226. com.android.internal.R.integer.config_deviceHardwareKeys) != 0;
  1227. if (!hasDeviceKeys) {
  1228. removeTile = true;
  1229. }
  1230. } else if (id == R.id.equalizer_settings) {
  1231. // Embedding into Settings only if app exists (user could manually remove it)
  1232. boolean supported = false;
  1233. try {
  1234. supported = (getPackageManager().getPackageInfo("com.vipercn.viper4android_v2", 0).versionCode >= 18);
  1235. } catch (PackageManager.NameNotFoundException e) {
  1236.  
  1237. }
  1238. if (!supported) {
  1239. removeTile = true;
  1240. }
  1241. }
  1242. if (UserHandle.MU_ENABLED && UserHandle.myUserId() != 0
  1243. && !ArrayUtils.contains(SETTINGS_FOR_RESTRICTED, id)) {
  1244. removeTile = true;
  1245. }
  1246.  
  1247. if (removeTile && n < category.getTilesCount()) {
  1248. category.removeTile(n);
  1249. }
  1250. n--;
  1251. }
  1252. }
  1253. }
  1254.  
  1255. private boolean updateHomeSettingTiles(DashboardTile tile) {
  1256. // Once we decide to show Home settings, keep showing it forever
  1257. SharedPreferences sp = getSharedPreferences(HomeSettings.HOME_PREFS, Context.MODE_PRIVATE);
  1258. if (sp.getBoolean(HomeSettings.HOME_PREFS_DO_SHOW, false)) {
  1259. return true;
  1260. }
  1261.  
  1262. try {
  1263. mHomeActivitiesCount = getHomeActivitiesCount();
  1264. if (mHomeActivitiesCount < 2) {
  1265. // When there's only one available home app, omit this settings
  1266. // category entirely at the top level UI. If the user just
  1267. // uninstalled the penultimate home app candidiate, we also
  1268. // now tell them about why they aren't seeing 'Home' in the list.
  1269. if (sShowNoHomeNotice) {
  1270. sShowNoHomeNotice = false;
  1271. NoHomeDialogFragment.show(this);
  1272. }
  1273. return false;
  1274. } else {
  1275. // Okay, we're allowing the Home settings category. Tell it, when
  1276. // invoked via this front door, that we'll need to be told about the
  1277. // case when the user uninstalls all but one home app.
  1278. if (tile.fragmentArguments == null) {
  1279. tile.fragmentArguments = new Bundle();
  1280. }
  1281. tile.fragmentArguments.putBoolean(HomeSettings.HOME_SHOW_NOTICE, true);
  1282. }
  1283. } catch (Exception e) {
  1284. // Can't look up the home activity; bail on configuring the icon
  1285. Log.w(LOG_TAG, "Problem looking up home activity!", e);
  1286. }
  1287.  
  1288. sp.edit().putBoolean(HomeSettings.HOME_PREFS_DO_SHOW, true).apply();
  1289. return true;
  1290. }
  1291.  
  1292. private void getMetaData() {
  1293. try {
  1294. ActivityInfo ai = getPackageManager().getActivityInfo(getComponentName(),
  1295. PackageManager.GET_META_DATA);
  1296. if (ai == null || ai.metaData == null) return;
  1297. mFragmentClass = ai.metaData.getString(META_DATA_KEY_FRAGMENT_CLASS);
  1298. } catch (NameNotFoundException nnfe) {
  1299. // No recovery
  1300. Log.d(LOG_TAG, "Cannot get Metadata for: " + getComponentName().toString());
  1301. }
  1302. }
  1303.  
  1304. // give subclasses access to the Next button
  1305. public boolean hasNextButton() {
  1306. return mNextButton != null;
  1307. }
  1308.  
  1309. public Button getNextButton() {
  1310. return mNextButton;
  1311. }
  1312.  
  1313. @Override
  1314. public boolean shouldUpRecreateTask(Intent targetIntent) {
  1315. return super.shouldUpRecreateTask(new Intent(this, SettingsActivity.class));
  1316. }
  1317.  
  1318. public static void requestHomeNotice() {
  1319. sShowNoHomeNotice = true;
  1320. }
  1321.  
  1322. @Override
  1323. public boolean onQueryTextSubmit(String query) {
  1324. switchToSearchResultsFragmentIfNeeded();
  1325. mSearchQuery = query;
  1326. return mSearchResultsFragment.onQueryTextSubmit(query);
  1327. }
  1328.  
  1329. @Override
  1330. public boolean onQueryTextChange(String newText) {
  1331. mSearchQuery = newText;
  1332. if (mSearchResultsFragment == null) {
  1333. return false;
  1334. }
  1335. return mSearchResultsFragment.onQueryTextChange(newText);
  1336. }
  1337.  
  1338. @Override
  1339. public boolean onClose() {
  1340. return false;
  1341. }
  1342.  
  1343. @Override
  1344. public boolean onMenuItemActionExpand(MenuItem item) {
  1345. if (item.getItemId() == mSearchMenuItem.getItemId()) {
  1346. switchToSearchResultsFragmentIfNeeded();
  1347. }
  1348. return true;
  1349. }
  1350.  
  1351. @Override
  1352. public boolean onMenuItemActionCollapse(MenuItem item) {
  1353. if (item.getItemId() == mSearchMenuItem.getItemId()) {
  1354. if (mSearchMenuItemExpanded) {
  1355. revertToInitialFragment();
  1356. }
  1357. }
  1358. return true;
  1359. }
  1360.  
  1361. private void switchToSearchResultsFragmentIfNeeded() {
  1362. if (mSearchResultsFragment != null) {
  1363. return;
  1364. }
  1365. Fragment current = getFragmentManager().findFragmentById(R.id.main_content);
  1366. if (current != null && current instanceof SearchResultsSummary) {
  1367. mSearchResultsFragment = (SearchResultsSummary) current;
  1368. } else {
  1369. mSearchResultsFragment = (SearchResultsSummary) switchToFragment(
  1370. SearchResultsSummary.class.getName(), null, false, true,
  1371. R.string.search_results_title, null, true);
  1372. }
  1373. mSearchResultsFragment.setSearchView(mSearchView);
  1374. mSearchMenuItemExpanded = true;
  1375. }
  1376.  
  1377. public void needToRevertToInitialFragment() {
  1378. mNeedToRevertToInitialFragment = true;
  1379. }
  1380.  
  1381. private void revertToInitialFragment() {
  1382. mNeedToRevertToInitialFragment = false;
  1383. mSearchResultsFragment = null;
  1384. mSearchMenuItemExpanded = false;
  1385. getFragmentManager().popBackStackImmediate(SettingsActivity.BACK_STACK_PREFS,
  1386. FragmentManager.POP_BACK_STACK_INCLUSIVE);
  1387. if (mSearchMenuItem != null) {
  1388. mSearchMenuItem.collapseActionView();
  1389. }
  1390. }
  1391.  
  1392. public Intent getResultIntentData() {
  1393. return mResultIntentData;
  1394. }
  1395.  
  1396. public void setResultIntentData(Intent resultIntentData) {
  1397. mResultIntentData = resultIntentData;
  1398. }
  1399.  
  1400. public void setNfcProfileCallback(NFCProfileTagCallback callback) {
  1401. mNfcProfileCallback = callback;
  1402. }
  1403.  
  1404. @Override
  1405. protected void onNewIntent(Intent intent) {
  1406. if (NfcAdapter.ACTION_TAG_DISCOVERED.equals(intent.getAction())) {
  1407. Tag detectedTag = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG);
  1408. if (mNfcProfileCallback != null) {
  1409. mNfcProfileCallback.onTagRead(detectedTag);
  1410. }
  1411. return;
  1412. }
  1413. super.onNewIntent(intent);
  1414. }
  1415.  
  1416. }
Advertisement
Add Comment
Please, Sign In to add comment