SettingsActivity.java revision a2d47fcf59f03d091edaf5895fd3b651e1f499e1
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 17package com.android.settings; 18 19import android.app.ActionBar; 20import android.app.Fragment; 21import android.app.FragmentManager; 22import android.app.FragmentTransaction; 23import android.content.BroadcastReceiver; 24import android.content.ComponentName; 25import android.content.Context; 26import android.content.Intent; 27import android.content.IntentFilter; 28import android.content.SharedPreferences; 29import android.content.pm.ActivityInfo; 30import android.content.pm.PackageManager; 31import android.content.pm.PackageManager.NameNotFoundException; 32import android.content.res.Configuration; 33import android.nfc.NfcAdapter; 34import android.os.AsyncTask; 35import android.os.Bundle; 36import android.os.UserHandle; 37import android.os.UserManager; 38import android.support.v14.preference.PreferenceFragment; 39import android.support.v7.preference.Preference; 40import android.support.v7.preference.PreferenceManager; 41import android.text.TextUtils; 42import android.transition.TransitionManager; 43import android.util.Log; 44import android.view.Menu; 45import android.view.MenuInflater; 46import android.view.MenuItem; 47import android.view.View; 48import android.view.View.OnClickListener; 49import android.view.ViewGroup; 50import android.widget.Button; 51import android.widget.SearchView; 52import com.android.internal.util.ArrayUtils; 53import com.android.settings.Settings.WifiSettingsActivity; 54import com.android.settings.accessibility.AccessibilitySettings; 55import com.android.settings.accessibility.AccessibilitySettingsForSetupWizard; 56import com.android.settings.accessibility.CaptionPropertiesFragment; 57import com.android.settings.accounts.AccountSettings; 58import com.android.settings.accounts.AccountSyncSettings; 59import com.android.settings.applications.AdvancedAppSettings; 60import com.android.settings.applications.DrawOverlayDetails; 61import com.android.settings.applications.InstalledAppDetails; 62import com.android.settings.applications.ManageApplications; 63import com.android.settings.applications.ManageAssist; 64import com.android.settings.applications.NotificationApps; 65import com.android.settings.applications.ProcessStatsSummary; 66import com.android.settings.applications.ProcessStatsUi; 67import com.android.settings.applications.UsageAccessDetails; 68import com.android.settings.applications.WriteSettingsDetails; 69import com.android.settings.bluetooth.BluetoothSettings; 70import com.android.settings.dashboard.DashboardSummary; 71import com.android.settings.dashboard.SearchResultsSummary; 72import com.android.settings.datausage.DataUsageSummary; 73import com.android.settings.deviceinfo.PrivateVolumeForget; 74import com.android.settings.deviceinfo.PrivateVolumeSettings; 75import com.android.settings.deviceinfo.PublicVolumeSettings; 76import com.android.settings.deviceinfo.StorageSettings; 77import com.android.settings.fuelgauge.BatterySaverSettings; 78import com.android.settings.fuelgauge.PowerUsageDetail; 79import com.android.settings.fuelgauge.PowerUsageSummary; 80import com.android.settings.inputmethod.AvailableVirtualKeyboardFragment; 81import com.android.settings.inputmethod.InputMethodAndLanguageSettings; 82import com.android.settings.inputmethod.KeyboardLayoutPickerFragment; 83import com.android.settings.inputmethod.KeyboardLayoutPickerFragment2; 84import com.android.settings.inputmethod.SpellCheckersSettings; 85import com.android.settings.inputmethod.UserDictionaryList; 86import com.android.settings.localepicker.LocaleListEditor; 87import com.android.settings.location.LocationSettings; 88import com.android.settings.nfc.AndroidBeam; 89import com.android.settings.nfc.PaymentSettings; 90import com.android.settings.notification.AppNotificationSettings; 91import com.android.settings.notification.ConfigureNotificationSettings; 92import com.android.settings.notification.NotificationAccessSettings; 93import com.android.settings.notification.NotificationStation; 94import com.android.settings.notification.OtherSoundSettings; 95import com.android.settings.notification.SoundSettings; 96import com.android.settings.notification.ZenAccessSettings; 97import com.android.settings.notification.ZenModeAutomationSettings; 98import com.android.settings.notification.ZenModeEventRuleSettings; 99import com.android.settings.notification.ZenModePrioritySettings; 100import com.android.settings.notification.ZenModeScheduleRuleSettings; 101import com.android.settings.notification.ZenModeSettings; 102import com.android.settings.notification.ZenModeVisualInterruptionSettings; 103import com.android.settings.print.PrintJobSettingsFragment; 104import com.android.settings.print.PrintSettingsFragment; 105import com.android.settings.search.DynamicIndexableContentMonitor; 106import com.android.settings.search.Index; 107import com.android.settings.sim.SimSettings; 108import com.android.settings.tts.TextToSpeechSettings; 109import com.android.settings.users.UserSettings; 110import com.android.settings.vpn2.VpnSettings; 111import com.android.settings.wfd.WifiDisplaySettings; 112import com.android.settings.widget.SwitchBar; 113import com.android.settings.wifi.AdvancedWifiSettings; 114import com.android.settings.wifi.SavedAccessPointsWifiSettings; 115import com.android.settings.wifi.WifiSettings; 116import com.android.settings.wifi.p2p.WifiP2pSettings; 117import com.android.settingslib.drawer.DashboardCategory; 118import com.android.settingslib.drawer.SettingsDrawerActivity; 119import com.android.settingslib.drawer.Tile; 120 121import java.util.ArrayList; 122import java.util.List; 123import java.util.Set; 124 125public class SettingsActivity extends SettingsDrawerActivity 126 implements PreferenceManager.OnPreferenceTreeClickListener, 127 PreferenceFragment.OnPreferenceStartFragmentCallback, 128 ButtonBarHandler, FragmentManager.OnBackStackChangedListener, 129 SearchView.OnQueryTextListener, SearchView.OnCloseListener, 130 MenuItem.OnActionExpandListener { 131 132 private static final String LOG_TAG = "Settings"; 133 134 // Constants for state save/restore 135 private static final String SAVE_KEY_CATEGORIES = ":settings:categories"; 136 private static final String SAVE_KEY_SEARCH_MENU_EXPANDED = ":settings:search_menu_expanded"; 137 private static final String SAVE_KEY_SEARCH_QUERY = ":settings:search_query"; 138 private static final String SAVE_KEY_SHOW_HOME_AS_UP = ":settings:show_home_as_up"; 139 private static final String SAVE_KEY_SHOW_SEARCH = ":settings:show_search"; 140 private static final String SAVE_KEY_HOME_ACTIVITIES_COUNT = ":settings:home_activities_count"; 141 142 /** 143 * When starting this activity, the invoking Intent can contain this extra 144 * string to specify which fragment should be initially displayed. 145 * <p/>Starting from Key Lime Pie, when this argument is passed in, the activity 146 * will call isValidFragment() to confirm that the fragment class name is valid for this 147 * activity. 148 */ 149 public static final String EXTRA_SHOW_FRAGMENT = ":settings:show_fragment"; 150 151 /** 152 * When starting this activity and using {@link #EXTRA_SHOW_FRAGMENT}, 153 * this extra can also be specified to supply a Bundle of arguments to pass 154 * to that fragment when it is instantiated during the initial creation 155 * of the activity. 156 */ 157 public static final String EXTRA_SHOW_FRAGMENT_ARGUMENTS = ":settings:show_fragment_args"; 158 159 /** 160 * Fragment "key" argument passed thru {@link #EXTRA_SHOW_FRAGMENT_ARGUMENTS} 161 */ 162 public static final String EXTRA_FRAGMENT_ARG_KEY = ":settings:fragment_args_key"; 163 164 public static final String BACK_STACK_PREFS = ":settings:prefs"; 165 166 // extras that allow any preference activity to be launched as part of a wizard 167 168 // show Back and Next buttons? takes boolean parameter 169 // Back will then return RESULT_CANCELED and Next RESULT_OK 170 protected static final String EXTRA_PREFS_SHOW_BUTTON_BAR = "extra_prefs_show_button_bar"; 171 172 // add a Skip button? 173 private static final String EXTRA_PREFS_SHOW_SKIP = "extra_prefs_show_skip"; 174 175 // specify custom text for the Back or Next buttons, or cause a button to not appear 176 // at all by setting it to null 177 protected static final String EXTRA_PREFS_SET_NEXT_TEXT = "extra_prefs_set_next_text"; 178 protected static final String EXTRA_PREFS_SET_BACK_TEXT = "extra_prefs_set_back_text"; 179 180 /** 181 * When starting this activity and using {@link #EXTRA_SHOW_FRAGMENT}, 182 * those extra can also be specify to supply the title or title res id to be shown for 183 * that fragment. 184 */ 185 public static final String EXTRA_SHOW_FRAGMENT_TITLE = ":settings:show_fragment_title"; 186 /** 187 * The package name used to resolve the title resource id. 188 */ 189 public static final String EXTRA_SHOW_FRAGMENT_TITLE_RES_PACKAGE_NAME = 190 ":settings:show_fragment_title_res_package_name"; 191 public static final String EXTRA_SHOW_FRAGMENT_TITLE_RESID = 192 ":settings:show_fragment_title_resid"; 193 public static final String EXTRA_SHOW_FRAGMENT_AS_SHORTCUT = 194 ":settings:show_fragment_as_shortcut"; 195 196 public static final String EXTRA_SHOW_FRAGMENT_AS_SUBSETTING = 197 ":settings:show_fragment_as_subsetting"; 198 199 public static final String META_DATA_KEY_FRAGMENT_CLASS = 200 "com.android.settings.FRAGMENT_CLASS"; 201 202 private static final String EXTRA_UI_OPTIONS = "settings:ui_options"; 203 204 private static final String EMPTY_QUERY = ""; 205 206 private static final int REQUEST_SUGGESTION = 42; 207 208 private String mFragmentClass; 209 210 private CharSequence mInitialTitle; 211 private int mInitialTitleResId; 212 213 // Show only these settings for restricted users 214 private String[] SETTINGS_FOR_RESTRICTED = { 215 //wireless_section 216 WifiSettingsActivity.class.getName(), 217 Settings.BluetoothSettingsActivity.class.getName(), 218 Settings.DataUsageSummaryActivity.class.getName(), 219 Settings.SimSettingsActivity.class.getName(), 220 Settings.WirelessSettingsActivity.class.getName(), 221 //device_section 222 Settings.HomeSettingsActivity.class.getName(), 223 Settings.SoundSettingsActivity.class.getName(), 224 Settings.DisplaySettingsActivity.class.getName(), 225 Settings.StorageSettingsActivity.class.getName(), 226 Settings.ManageApplicationsActivity.class.getName(), 227 Settings.PowerUsageSummaryActivity.class.getName(), 228 //personal_section 229 Settings.LocationSettingsActivity.class.getName(), 230 Settings.SecuritySettingsActivity.class.getName(), 231 Settings.InputMethodAndLanguageSettingsActivity.class.getName(), 232 Settings.UserSettingsActivity.class.getName(), 233 Settings.AccountSettingsActivity.class.getName(), 234 //system_section 235 Settings.DateTimeSettingsActivity.class.getName(), 236 Settings.DeviceInfoSettingsActivity.class.getName(), 237 Settings.AccessibilitySettingsActivity.class.getName(), 238 Settings.PrintSettingsActivity.class.getName(), 239 Settings.PaymentSettingsActivity.class.getName(), 240 }; 241 242 private static final String[] ENTRY_FRAGMENTS = { 243 WirelessSettings.class.getName(), 244 WifiSettings.class.getName(), 245 AdvancedWifiSettings.class.getName(), 246 SavedAccessPointsWifiSettings.class.getName(), 247 BluetoothSettings.class.getName(), 248 SimSettings.class.getName(), 249 TetherSettings.class.getName(), 250 WifiP2pSettings.class.getName(), 251 VpnSettings.class.getName(), 252 DateTimeSettings.class.getName(), 253 LocaleListEditor.class.getName(), 254 InputMethodAndLanguageSettings.class.getName(), 255 AvailableVirtualKeyboardFragment.class.getName(), 256 SpellCheckersSettings.class.getName(), 257 UserDictionaryList.class.getName(), 258 UserDictionarySettings.class.getName(), 259 HomeSettings.class.getName(), 260 DisplaySettings.class.getName(), 261 DeviceInfoSettings.class.getName(), 262 ManageApplications.class.getName(), 263 NotificationApps.class.getName(), 264 ManageAssist.class.getName(), 265 ProcessStatsUi.class.getName(), 266 NotificationStation.class.getName(), 267 LocationSettings.class.getName(), 268 SecuritySettings.class.getName(), 269 UsageAccessDetails.class.getName(), 270 PrivacySettings.class.getName(), 271 DeviceAdminSettings.class.getName(), 272 AccessibilitySettings.class.getName(), 273 AccessibilitySettingsForSetupWizard.class.getName(), 274 CaptionPropertiesFragment.class.getName(), 275 com.android.settings.accessibility.ToggleDaltonizerPreferenceFragment.class.getName(), 276 TextToSpeechSettings.class.getName(), 277 StorageSettings.class.getName(), 278 PrivateVolumeForget.class.getName(), 279 PrivateVolumeSettings.class.getName(), 280 PublicVolumeSettings.class.getName(), 281 DevelopmentSettings.class.getName(), 282 AndroidBeam.class.getName(), 283 WifiDisplaySettings.class.getName(), 284 PowerUsageSummary.class.getName(), 285 AccountSyncSettings.class.getName(), 286 AccountSettings.class.getName(), 287 CryptKeeperSettings.class.getName(), 288 DataUsageSummary.class.getName(), 289 DreamSettings.class.getName(), 290 UserSettings.class.getName(), 291 NotificationAccessSettings.class.getName(), 292 ZenAccessSettings.class.getName(), 293 PrintSettingsFragment.class.getName(), 294 PrintJobSettingsFragment.class.getName(), 295 TrustedCredentialsSettings.class.getName(), 296 PaymentSettings.class.getName(), 297 KeyboardLayoutPickerFragment.class.getName(), 298 KeyboardLayoutPickerFragment2.class.getName(), 299 ZenModeSettings.class.getName(), 300 SoundSettings.class.getName(), 301 ConfigureNotificationSettings.class.getName(), 302 ChooseLockPassword.ChooseLockPasswordFragment.class.getName(), 303 ChooseLockPattern.ChooseLockPatternFragment.class.getName(), 304 InstalledAppDetails.class.getName(), 305 BatterySaverSettings.class.getName(), 306 AppNotificationSettings.class.getName(), 307 OtherSoundSettings.class.getName(), 308 ApnSettings.class.getName(), 309 WifiCallingSettings.class.getName(), 310 ZenModePrioritySettings.class.getName(), 311 ZenModeAutomationSettings.class.getName(), 312 ZenModeScheduleRuleSettings.class.getName(), 313 ZenModeEventRuleSettings.class.getName(), 314 ZenModeVisualInterruptionSettings.class.getName(), 315 ProcessStatsUi.class.getName(), 316 PowerUsageDetail.class.getName(), 317 ProcessStatsSummary.class.getName(), 318 DrawOverlayDetails.class.getName(), 319 WriteSettingsDetails.class.getName(), 320 AdvancedAppSettings.class.getName(), 321 WallpaperTypeSettings.class.getName(), 322 }; 323 324 325 private static final String[] LIKE_SHORTCUT_INTENT_ACTION_ARRAY = { 326 "android.settings.APPLICATION_DETAILS_SETTINGS" 327 }; 328 329 private SharedPreferences mDevelopmentPreferences; 330 private SharedPreferences.OnSharedPreferenceChangeListener mDevelopmentPreferencesListener; 331 332 private boolean mBatteryPresent = true; 333 private BroadcastReceiver mBatteryInfoReceiver = new BroadcastReceiver() { 334 @Override 335 public void onReceive(Context context, Intent intent) { 336 String action = intent.getAction(); 337 if (Intent.ACTION_BATTERY_CHANGED.equals(action)) { 338 boolean batteryPresent = Utils.isBatteryPresent(intent); 339 340 if (mBatteryPresent != batteryPresent) { 341 mBatteryPresent = batteryPresent; 342 updateTilesList(); 343 } 344 } 345 } 346 }; 347 348 private final BroadcastReceiver mUserAddRemoveReceiver = new BroadcastReceiver() { 349 @Override 350 public void onReceive(Context context, Intent intent) { 351 String action = intent.getAction(); 352 if (action.equals(Intent.ACTION_USER_ADDED) 353 || action.equals(Intent.ACTION_USER_REMOVED)) { 354 Index.getInstance(getApplicationContext()).update(); 355 } 356 } 357 }; 358 359 private final DynamicIndexableContentMonitor mDynamicIndexableContentMonitor = 360 new DynamicIndexableContentMonitor(); 361 362 private ActionBar mActionBar; 363 private SwitchBar mSwitchBar; 364 365 private Button mNextButton; 366 367 private boolean mDisplayHomeAsUpEnabled; 368 private boolean mDisplaySearch; 369 370 private boolean mIsShowingDashboard; 371 private boolean mIsShortcut; 372 373 private ViewGroup mContent; 374 375 private SearchView mSearchView; 376 private MenuItem mSearchMenuItem; 377 private boolean mSearchMenuItemExpanded = false; 378 private SearchResultsSummary mSearchResultsFragment; 379 private String mSearchQuery; 380 381 // Categories 382 private ArrayList<DashboardCategory> mCategories = new ArrayList<DashboardCategory>(); 383 384 private static final String MSG_DATA_FORCE_REFRESH = "msg_data_force_refresh"; 385 386 private boolean mNeedToRevertToInitialFragment = false; 387 388 private Intent mResultIntentData; 389 private ComponentName mCurrentSuggestion; 390 391 public SwitchBar getSwitchBar() { 392 return mSwitchBar; 393 } 394 395 @Override 396 public boolean onPreferenceStartFragment(PreferenceFragment caller, Preference pref) { 397 // Override the fragment title for Wallpaper settings 398 CharSequence title = pref.getTitle(); 399 if (pref.getFragment().equals(WallpaperTypeSettings.class.getName())) { 400 title = getString(R.string.wallpaper_settings_fragment_title); 401 } 402 startPreferencePanel(pref.getFragment(), pref.getExtras(), -1, title, 403 null, 0); 404 return true; 405 } 406 407 @Override 408 public boolean onPreferenceTreeClick(Preference preference) { 409 return false; 410 } 411 412 @Override 413 public void onConfigurationChanged(Configuration newConfig) { 414 super.onConfigurationChanged(newConfig); 415 Index.getInstance(this).update(); 416 } 417 418 @Override 419 protected void onStart() { 420 super.onStart(); 421 422 if (mNeedToRevertToInitialFragment) { 423 revertToInitialFragment(); 424 } 425 } 426 427 @Override 428 public boolean onCreateOptionsMenu(Menu menu) { 429 if (!mDisplaySearch) { 430 return false; 431 } 432 433 MenuInflater inflater = getMenuInflater(); 434 inflater.inflate(R.menu.options_menu, menu); 435 436 // Cache the search query (can be overriden by the OnQueryTextListener) 437 final String query = mSearchQuery; 438 439 mSearchMenuItem = menu.findItem(R.id.search); 440 mSearchView = (SearchView) mSearchMenuItem.getActionView(); 441 442 if (mSearchMenuItem == null || mSearchView == null) { 443 return false; 444 } 445 446 if (mSearchResultsFragment != null) { 447 mSearchResultsFragment.setSearchView(mSearchView); 448 } 449 450 mSearchMenuItem.setOnActionExpandListener(this); 451 mSearchView.setOnQueryTextListener(this); 452 mSearchView.setOnCloseListener(this); 453 454 if (mSearchMenuItemExpanded) { 455 mSearchMenuItem.expandActionView(); 456 } 457 mSearchView.setQuery(query, true /* submit */); 458 459 return true; 460 } 461 462 @Override 463 public SharedPreferences getSharedPreferences(String name, int mode) { 464 if (name.equals(getPackageName() + "_preferences")) { 465 return new SharedPreferencesLogger(this, getMetricsTag()); 466 } 467 return super.getSharedPreferences(name, mode); 468 } 469 470 private String getMetricsTag() { 471 String tag = getClass().getName(); 472 if (getIntent() != null && getIntent().hasExtra(EXTRA_SHOW_FRAGMENT)) { 473 tag = getIntent().getStringExtra(EXTRA_SHOW_FRAGMENT); 474 } 475 if (tag.startsWith("com.android.settings.")) { 476 tag = tag.replace("com.android.settings.", ""); 477 } 478 return tag; 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 long startTime = System.currentTimeMillis(); 501 502 // Should happen before any call to getIntent() 503 getMetaData(); 504 505 final Intent intent = getIntent(); 506 if (intent.hasExtra(EXTRA_UI_OPTIONS)) { 507 getWindow().setUiOptions(intent.getIntExtra(EXTRA_UI_OPTIONS, 0)); 508 } 509 510 mDevelopmentPreferences = getSharedPreferences(DevelopmentSettings.PREF_FILE, 511 Context.MODE_PRIVATE); 512 513 // Getting Intent properties can only be done after the super.onCreate(...) 514 final String initialFragmentName = intent.getStringExtra(EXTRA_SHOW_FRAGMENT); 515 516 mIsShortcut = isShortCutIntent(intent) || isLikeShortCutIntent(intent) || 517 intent.getBooleanExtra(EXTRA_SHOW_FRAGMENT_AS_SHORTCUT, false); 518 519 final ComponentName cn = intent.getComponent(); 520 final String className = cn.getClassName(); 521 522 mIsShowingDashboard = className.equals(Settings.class.getName()) 523 || className.equals(Settings.WirelessSettings.class.getName()) 524 || className.equals(Settings.DeviceSettings.class.getName()) 525 || className.equals(Settings.PersonalSettings.class.getName()) 526 || className.equals(Settings.WirelessSettings.class.getName()); 527 528 // This is a "Sub Settings" when: 529 // - this is a real SubSettings 530 // - or :settings:show_fragment_as_subsetting is passed to the Intent 531 final boolean isSubSettings = this instanceof SubSettings || 532 intent.getBooleanExtra(EXTRA_SHOW_FRAGMENT_AS_SUBSETTING, false); 533 534 // If this is a sub settings, then apply the SubSettings Theme for the ActionBar content insets 535 if (isSubSettings) { 536 // Check also that we are not a Theme Dialog as we don't want to override them 537 final int themeResId = getThemeResId(); 538 if (themeResId != R.style.Theme_DialogWhenLarge && 539 themeResId != R.style.Theme_SubSettingsDialogWhenLarge) { 540 setTheme(R.style.Theme_SubSettings); 541 } 542 } 543 544 setContentView(mIsShowingDashboard ? 545 R.layout.settings_main_dashboard : R.layout.settings_main_prefs); 546 547 mContent = (ViewGroup) findViewById(R.id.main_content); 548 549 getFragmentManager().addOnBackStackChangedListener(this); 550 551 if (mIsShowingDashboard) { 552 // Run the Index update only if we have some space 553 if (!Utils.isLowStorage(this)) { 554 long indexStartTime = System.currentTimeMillis(); 555 AsyncTask.execute(new Runnable() { 556 @Override 557 public void run() { 558 Index.getInstance(getApplicationContext()).update(); 559 } 560 }); 561 if (DEBUG_TIMING) Log.d(LOG_TAG, "Index.update() took " 562 + (System.currentTimeMillis() - indexStartTime) + " ms"); 563 } else { 564 Log.w(LOG_TAG, "Cannot update the Indexer as we are running low on storage space!"); 565 } 566 } 567 568 if (savedState != null) { 569 // We are restarting from a previous saved state; used that to initialize, instead 570 // of starting fresh. 571 mSearchMenuItemExpanded = savedState.getBoolean(SAVE_KEY_SEARCH_MENU_EXPANDED); 572 mSearchQuery = savedState.getString(SAVE_KEY_SEARCH_QUERY); 573 574 setTitleFromIntent(intent); 575 576 ArrayList<DashboardCategory> categories = 577 savedState.getParcelableArrayList(SAVE_KEY_CATEGORIES); 578 if (categories != null) { 579 mCategories.clear(); 580 mCategories.addAll(categories); 581 setTitleFromBackStack(); 582 } 583 584 mDisplayHomeAsUpEnabled = savedState.getBoolean(SAVE_KEY_SHOW_HOME_AS_UP); 585 mDisplaySearch = savedState.getBoolean(SAVE_KEY_SHOW_SEARCH); 586 } else { 587 if (!mIsShowingDashboard) { 588 mDisplaySearch = false; 589 // UP will be shown only if it is a sub settings 590 if (mIsShortcut) { 591 mDisplayHomeAsUpEnabled = isSubSettings; 592 } else if (isSubSettings) { 593 mDisplayHomeAsUpEnabled = true; 594 } else { 595 mDisplayHomeAsUpEnabled = false; 596 } 597 setTitleFromIntent(intent); 598 599 Bundle initialArguments = intent.getBundleExtra(EXTRA_SHOW_FRAGMENT_ARGUMENTS); 600 switchToFragment(initialFragmentName, initialArguments, true, false, 601 mInitialTitleResId, mInitialTitle, false); 602 } else { 603 // No UP affordance if we are displaying the main Dashboard 604 mDisplayHomeAsUpEnabled = false; 605 // Show Search affordance 606 mDisplaySearch = true; 607 mInitialTitleResId = R.string.dashboard_title; 608 switchToFragment(DashboardSummary.class.getName(), null, false, false, 609 mInitialTitleResId, mInitialTitle, false); 610 } 611 } 612 613 mActionBar = getActionBar(); 614 if (mActionBar != null) { 615 mActionBar.setDisplayHomeAsUpEnabled(mDisplayHomeAsUpEnabled); 616 mActionBar.setHomeButtonEnabled(mDisplayHomeAsUpEnabled); 617 } 618 mSwitchBar = (SwitchBar) findViewById(R.id.switch_bar); 619 if (mSwitchBar != null) { 620 mSwitchBar.setMetricsTag(getMetricsTag()); 621 } 622 623 // see if we should show Back/Next buttons 624 if (intent.getBooleanExtra(EXTRA_PREFS_SHOW_BUTTON_BAR, false)) { 625 626 View buttonBar = findViewById(R.id.button_bar); 627 if (buttonBar != null) { 628 buttonBar.setVisibility(View.VISIBLE); 629 630 Button backButton = (Button)findViewById(R.id.back_button); 631 backButton.setOnClickListener(new OnClickListener() { 632 public void onClick(View v) { 633 setResult(RESULT_CANCELED, getResultIntentData()); 634 finish(); 635 } 636 }); 637 Button skipButton = (Button)findViewById(R.id.skip_button); 638 skipButton.setOnClickListener(new OnClickListener() { 639 public void onClick(View v) { 640 setResult(RESULT_OK, getResultIntentData()); 641 finish(); 642 } 643 }); 644 mNextButton = (Button)findViewById(R.id.next_button); 645 mNextButton.setOnClickListener(new OnClickListener() { 646 public void onClick(View v) { 647 setResult(RESULT_OK, getResultIntentData()); 648 finish(); 649 } 650 }); 651 652 // set our various button parameters 653 if (intent.hasExtra(EXTRA_PREFS_SET_NEXT_TEXT)) { 654 String buttonText = intent.getStringExtra(EXTRA_PREFS_SET_NEXT_TEXT); 655 if (TextUtils.isEmpty(buttonText)) { 656 mNextButton.setVisibility(View.GONE); 657 } 658 else { 659 mNextButton.setText(buttonText); 660 } 661 } 662 if (intent.hasExtra(EXTRA_PREFS_SET_BACK_TEXT)) { 663 String buttonText = intent.getStringExtra(EXTRA_PREFS_SET_BACK_TEXT); 664 if (TextUtils.isEmpty(buttonText)) { 665 backButton.setVisibility(View.GONE); 666 } 667 else { 668 backButton.setText(buttonText); 669 } 670 } 671 if (intent.getBooleanExtra(EXTRA_PREFS_SHOW_SKIP, false)) { 672 skipButton.setVisibility(View.VISIBLE); 673 } 674 } 675 } 676 677 if (DEBUG_TIMING) Log.d(LOG_TAG, "onCreate took " + (System.currentTimeMillis() - startTime) 678 + " ms"); 679 } 680 681 private void setTitleFromIntent(Intent intent) { 682 final int initialTitleResId = intent.getIntExtra(EXTRA_SHOW_FRAGMENT_TITLE_RESID, -1); 683 if (initialTitleResId > 0) { 684 mInitialTitle = null; 685 mInitialTitleResId = initialTitleResId; 686 687 final String initialTitleResPackageName = intent.getStringExtra( 688 EXTRA_SHOW_FRAGMENT_TITLE_RES_PACKAGE_NAME); 689 if (initialTitleResPackageName != null) { 690 try { 691 Context authContext = createPackageContextAsUser(initialTitleResPackageName, 692 0 /* flags */, new UserHandle(UserHandle.myUserId())); 693 mInitialTitle = authContext.getResources().getText(mInitialTitleResId); 694 setTitle(mInitialTitle); 695 mInitialTitleResId = -1; 696 return; 697 } catch (NameNotFoundException e) { 698 Log.w(LOG_TAG, "Could not find package" + initialTitleResPackageName); 699 } 700 } else { 701 setTitle(mInitialTitleResId); 702 } 703 } else { 704 mInitialTitleResId = -1; 705 final String initialTitle = intent.getStringExtra(EXTRA_SHOW_FRAGMENT_TITLE); 706 mInitialTitle = (initialTitle != null) ? initialTitle : getTitle(); 707 setTitle(mInitialTitle); 708 } 709 } 710 711 @Override 712 public void onBackStackChanged() { 713 setTitleFromBackStack(); 714 } 715 716 private int setTitleFromBackStack() { 717 final int count = getFragmentManager().getBackStackEntryCount(); 718 719 if (count == 0) { 720 if (mInitialTitleResId > 0) { 721 setTitle(mInitialTitleResId); 722 } else { 723 setTitle(mInitialTitle); 724 } 725 return 0; 726 } 727 728 FragmentManager.BackStackEntry bse = getFragmentManager().getBackStackEntryAt(count - 1); 729 setTitleFromBackStackEntry(bse); 730 731 return count; 732 } 733 734 private void setTitleFromBackStackEntry(FragmentManager.BackStackEntry bse) { 735 final CharSequence title; 736 final int titleRes = bse.getBreadCrumbTitleRes(); 737 if (titleRes > 0) { 738 title = getText(titleRes); 739 } else { 740 title = bse.getBreadCrumbTitle(); 741 } 742 if (title != null) { 743 setTitle(title); 744 } 745 } 746 747 @Override 748 protected void onSaveInstanceState(Bundle outState) { 749 super.onSaveInstanceState(outState); 750 751 if (mCategories.size() > 0) { 752 outState.putParcelableArrayList(SAVE_KEY_CATEGORIES, mCategories); 753 } 754 755 outState.putBoolean(SAVE_KEY_SHOW_HOME_AS_UP, mDisplayHomeAsUpEnabled); 756 outState.putBoolean(SAVE_KEY_SHOW_SEARCH, mDisplaySearch); 757 758 if (mDisplaySearch) { 759 // The option menus are created if the ActionBar is visible and they are also created 760 // asynchronously. If you launch Settings with an Intent action like 761 // android.intent.action.POWER_USAGE_SUMMARY and at the same time your device is locked 762 // thru a LockScreen, onCreateOptionsMenu() is not yet called and references to the search 763 // menu item and search view are null. 764 boolean isExpanded = (mSearchMenuItem != null) && mSearchMenuItem.isActionViewExpanded(); 765 outState.putBoolean(SAVE_KEY_SEARCH_MENU_EXPANDED, isExpanded); 766 767 String query = (mSearchView != null) ? mSearchView.getQuery().toString() : EMPTY_QUERY; 768 outState.putString(SAVE_KEY_SEARCH_QUERY, query); 769 } 770 } 771 772 @Override 773 protected void onResume() { 774 super.onResume(); 775 776 mDevelopmentPreferencesListener = new SharedPreferences.OnSharedPreferenceChangeListener() { 777 @Override 778 public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) { 779 updateTilesList(); 780 } 781 }; 782 mDevelopmentPreferences.registerOnSharedPreferenceChangeListener( 783 mDevelopmentPreferencesListener); 784 785 registerReceiver(mBatteryInfoReceiver, new IntentFilter(Intent.ACTION_BATTERY_CHANGED)); 786 registerReceiver(mUserAddRemoveReceiver, new IntentFilter(Intent.ACTION_USER_ADDED)); 787 registerReceiver(mUserAddRemoveReceiver, new IntentFilter(Intent.ACTION_USER_REMOVED)); 788 789 mDynamicIndexableContentMonitor.register(this); 790 791 if(mDisplaySearch && !TextUtils.isEmpty(mSearchQuery)) { 792 onQueryTextSubmit(mSearchQuery); 793 } 794 updateTilesList(); 795 } 796 797 @Override 798 protected void onPause() { 799 super.onPause(); 800 unregisterReceiver(mBatteryInfoReceiver); 801 unregisterReceiver(mUserAddRemoveReceiver); 802 mDynamicIndexableContentMonitor.unregister(); 803 } 804 805 @Override 806 public void onDestroy() { 807 super.onDestroy(); 808 809 mDevelopmentPreferences.unregisterOnSharedPreferenceChangeListener( 810 mDevelopmentPreferencesListener); 811 mDevelopmentPreferencesListener = null; 812 } 813 814 protected boolean isValidFragment(String fragmentName) { 815 // Almost all fragments are wrapped in this, 816 // except for a few that have their own activities. 817 for (int i = 0; i < ENTRY_FRAGMENTS.length; i++) { 818 if (ENTRY_FRAGMENTS[i].equals(fragmentName)) return true; 819 } 820 return false; 821 } 822 823 @Override 824 public Intent getIntent() { 825 Intent superIntent = super.getIntent(); 826 String startingFragment = getStartingFragmentClass(superIntent); 827 // This is called from super.onCreate, isMultiPane() is not yet reliable 828 // Do not use onIsHidingHeaders either, which relies itself on this method 829 if (startingFragment != null) { 830 Intent modIntent = new Intent(superIntent); 831 modIntent.putExtra(EXTRA_SHOW_FRAGMENT, startingFragment); 832 Bundle args = superIntent.getExtras(); 833 if (args != null) { 834 args = new Bundle(args); 835 } else { 836 args = new Bundle(); 837 } 838 args.putParcelable("intent", superIntent); 839 modIntent.putExtra(EXTRA_SHOW_FRAGMENT_ARGUMENTS, args); 840 return modIntent; 841 } 842 return superIntent; 843 } 844 845 /** 846 * Checks if the component name in the intent is different from the Settings class and 847 * returns the class name to load as a fragment. 848 */ 849 private String getStartingFragmentClass(Intent intent) { 850 if (mFragmentClass != null) return mFragmentClass; 851 852 String intentClass = intent.getComponent().getClassName(); 853 if (intentClass.equals(getClass().getName())) return null; 854 855 if ("com.android.settings.ManageApplications".equals(intentClass) 856 || "com.android.settings.RunningServices".equals(intentClass) 857 || "com.android.settings.applications.StorageUse".equals(intentClass)) { 858 // Old names of manage apps. 859 intentClass = com.android.settings.applications.ManageApplications.class.getName(); 860 } 861 862 return intentClass; 863 } 864 865 /** 866 * Start a new fragment containing a preference panel. If the preferences 867 * are being displayed in multi-pane mode, the given fragment class will 868 * be instantiated and placed in the appropriate pane. If running in 869 * single-pane mode, a new activity will be launched in which to show the 870 * fragment. 871 * 872 * @param fragmentClass Full name of the class implementing the fragment. 873 * @param args Any desired arguments to supply to the fragment. 874 * @param titleRes Optional resource identifier of the title of this 875 * fragment. 876 * @param titleText Optional text of the title of this fragment. 877 * @param resultTo Optional fragment that result data should be sent to. 878 * If non-null, resultTo.onActivityResult() will be called when this 879 * preference panel is done. The launched panel must use 880 * {@link #finishPreferencePanel(Fragment, int, Intent)} when done. 881 * @param resultRequestCode If resultTo is non-null, this is the caller's 882 * request code to be received with the result. 883 */ 884 public void startPreferencePanel(String fragmentClass, Bundle args, int titleRes, 885 CharSequence titleText, Fragment resultTo, int resultRequestCode) { 886 String title = null; 887 if (titleRes < 0) { 888 if (titleText != null) { 889 title = titleText.toString(); 890 } else { 891 // There not much we can do in that case 892 title = ""; 893 } 894 } 895 Utils.startWithFragment(this, fragmentClass, args, resultTo, resultRequestCode, 896 titleRes, title, mIsShortcut); 897 } 898 899 /** 900 * Start a new fragment in a new activity containing a preference panel for a given user. If the 901 * preferences are being displayed in multi-pane mode, the given fragment class will be 902 * instantiated and placed in the appropriate pane. If running in single-pane mode, a new 903 * activity will be launched in which to show the fragment. 904 * 905 * @param fragmentClass Full name of the class implementing the fragment. 906 * @param args Any desired arguments to supply to the fragment. 907 * @param titleRes Optional resource identifier of the title of this fragment. 908 * @param titleText Optional text of the title of this fragment. 909 * @param userHandle The user for which the panel has to be started. 910 */ 911 public void startPreferencePanelAsUser(String fragmentClass, Bundle args, int titleRes, 912 CharSequence titleText, UserHandle userHandle) { 913 // This is a workaround. 914 // 915 // Calling startWithFragmentAsUser() without specifying FLAG_ACTIVITY_NEW_TASK to the intent 916 // starting the fragment could cause a native stack corruption. See b/17523189. However, 917 // adding that flag and start the preference panel with the same UserHandler will make it 918 // impossible to use back button to return to the previous screen. See b/20042570. 919 // 920 // We work around this issue by adding FLAG_ACTIVITY_NEW_TASK to the intent, while doing 921 // another check here to call startPreferencePanel() instead of startWithFragmentAsUser() 922 // when we're calling it as the same user. 923 if (userHandle.getIdentifier() == UserHandle.myUserId()) { 924 startPreferencePanel(fragmentClass, args, titleRes, titleText, null, 0); 925 } else { 926 String title = null; 927 if (titleRes < 0) { 928 if (titleText != null) { 929 title = titleText.toString(); 930 } else { 931 // There not much we can do in that case 932 title = ""; 933 } 934 } 935 Utils.startWithFragmentAsUser(this, fragmentClass, args, 936 titleRes, title, mIsShortcut, userHandle); 937 } 938 } 939 940 /** 941 * Called by a preference panel fragment to finish itself. 942 * 943 * @param caller The fragment that is asking to be finished. 944 * @param resultCode Optional result code to send back to the original 945 * launching fragment. 946 * @param resultData Optional result data to send back to the original 947 * launching fragment. 948 */ 949 public void finishPreferencePanel(Fragment caller, int resultCode, Intent resultData) { 950 setResult(resultCode, resultData); 951 finish(); 952 } 953 954 /** 955 * Start a new fragment. 956 * 957 * @param fragment The fragment to start 958 * @param push If true, the current fragment will be pushed onto the back stack. If false, 959 * the current fragment will be replaced. 960 */ 961 public void startPreferenceFragment(Fragment fragment, boolean push) { 962 FragmentTransaction transaction = getFragmentManager().beginTransaction(); 963 transaction.replace(R.id.main_content, fragment); 964 if (push) { 965 transaction.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN); 966 transaction.addToBackStack(BACK_STACK_PREFS); 967 } else { 968 transaction.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_FADE); 969 } 970 transaction.commitAllowingStateLoss(); 971 } 972 973 /** 974 * Switch to a specific Fragment with taking care of validation, Title and BackStack 975 */ 976 private Fragment switchToFragment(String fragmentName, Bundle args, boolean validate, 977 boolean addToBackStack, int titleResId, CharSequence title, boolean withTransition) { 978 if (validate && !isValidFragment(fragmentName)) { 979 throw new IllegalArgumentException("Invalid fragment for this activity: " 980 + fragmentName); 981 } 982 Fragment f = Fragment.instantiate(this, fragmentName, args); 983 FragmentTransaction transaction = getFragmentManager().beginTransaction(); 984 transaction.replace(R.id.main_content, f); 985 if (withTransition) { 986 TransitionManager.beginDelayedTransition(mContent); 987 } 988 if (addToBackStack) { 989 transaction.addToBackStack(SettingsActivity.BACK_STACK_PREFS); 990 } 991 if (titleResId > 0) { 992 transaction.setBreadCrumbTitle(titleResId); 993 } else if (title != null) { 994 transaction.setBreadCrumbTitle(title); 995 } 996 transaction.commitAllowingStateLoss(); 997 getFragmentManager().executePendingTransactions(); 998 return f; 999 } 1000 1001 private void updateTilesList() { 1002 // Generally the items that are will be changing from these updates will 1003 // not be in the top list of tiles, so run it in the background and the 1004 // SettingsDrawerActivity will pick up on the updates automatically. 1005 AsyncTask.execute(new Runnable() { 1006 @Override 1007 public void run() { 1008 doUpdateTilesList(); 1009 } 1010 }); 1011 } 1012 1013 private void doUpdateTilesList() { 1014 PackageManager pm = getPackageManager(); 1015 final UserManager um = UserManager.get(this); 1016 final boolean isAdmin = um.isAdminUser(); 1017 1018 String packageName = getPackageName(); 1019 setTileEnabled(new ComponentName(packageName, WifiSettingsActivity.class.getName()), 1020 pm.hasSystemFeature(PackageManager.FEATURE_WIFI), isAdmin, pm); 1021 1022 setTileEnabled(new ComponentName(packageName, 1023 Settings.BluetoothSettingsActivity.class.getName()), 1024 pm.hasSystemFeature(PackageManager.FEATURE_BLUETOOTH), isAdmin, pm); 1025 1026 setTileEnabled(new ComponentName(packageName, 1027 Settings.DataUsageSummaryActivity.class.getName()), 1028 Utils.isBandwidthControlEnabled(), isAdmin, pm); 1029 1030 setTileEnabled(new ComponentName(packageName, 1031 Settings.SimSettingsActivity.class.getName()), 1032 Utils.showSimCardTile(this), isAdmin, pm); 1033 1034 setTileEnabled(new ComponentName(packageName, 1035 Settings.PowerUsageSummaryActivity.class.getName()), 1036 mBatteryPresent, isAdmin, pm); 1037 1038 setTileEnabled(new ComponentName(packageName, 1039 Settings.UserSettingsActivity.class.getName()), 1040 UserHandle.MU_ENABLED && UserManager.supportsMultipleUsers() 1041 && !Utils.isMonkeyRunning(), isAdmin, pm); 1042 1043 NfcAdapter adapter = NfcAdapter.getDefaultAdapter(this); 1044 setTileEnabled(new ComponentName(packageName, 1045 Settings.PaymentSettingsActivity.class.getName()), 1046 pm.hasSystemFeature(PackageManager.FEATURE_NFC) 1047 && pm.hasSystemFeature(PackageManager.FEATURE_NFC_HOST_CARD_EMULATION) 1048 && adapter != null && adapter.isEnabled(), isAdmin, pm); 1049 1050 setTileEnabled(new ComponentName(packageName, 1051 Settings.PrintSettingsActivity.class.getName()), 1052 pm.hasSystemFeature(PackageManager.FEATURE_PRINTING), isAdmin, pm); 1053 1054 final boolean showDev = mDevelopmentPreferences.getBoolean( 1055 DevelopmentSettings.PREF_SHOW, 1056 android.os.Build.TYPE.equals("eng")); 1057 setTileEnabled(new ComponentName(packageName, 1058 Settings.DevelopmentSettingsActivity.class.getName()), 1059 showDev && !um.hasUserRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES), 1060 isAdmin, pm); 1061 1062 if (UserHandle.MU_ENABLED && !isAdmin) { 1063 // When on restricted users, disable all extra categories (but only the settings ones). 1064 List<DashboardCategory> categories = getDashboardCategories(); 1065 for (DashboardCategory category : categories) { 1066 for (Tile tile : category.tiles) { 1067 ComponentName component = tile.intent.getComponent(); 1068 if (packageName.equals(component)&& !ArrayUtils.contains( 1069 SETTINGS_FOR_RESTRICTED, component.getClassName())) { 1070 setTileEnabled(component, false, isAdmin, pm); 1071 } 1072 } 1073 } 1074 } 1075 } 1076 1077 private void setTileEnabled(ComponentName component, boolean enabled, boolean isAdmin, 1078 PackageManager pm) { 1079 if (UserHandle.MU_ENABLED && !isAdmin 1080 && !ArrayUtils.contains(SETTINGS_FOR_RESTRICTED, component.getClassName())) { 1081 enabled = false; 1082 } 1083 int state = pm.getComponentEnabledSetting(component); 1084 boolean isEnabled = state == PackageManager.COMPONENT_ENABLED_STATE_DEFAULT 1085 || state == PackageManager.COMPONENT_ENABLED_STATE_ENABLED; 1086 if (isEnabled != enabled) { 1087 pm.setComponentEnabledSetting(component, enabled 1088 ? PackageManager.COMPONENT_ENABLED_STATE_ENABLED 1089 : PackageManager.COMPONENT_ENABLED_STATE_DISABLED, 1090 PackageManager.DONT_KILL_APP); 1091 } 1092 } 1093 1094 private void getMetaData() { 1095 try { 1096 ActivityInfo ai = getPackageManager().getActivityInfo(getComponentName(), 1097 PackageManager.GET_META_DATA); 1098 if (ai == null || ai.metaData == null) return; 1099 mFragmentClass = ai.metaData.getString(META_DATA_KEY_FRAGMENT_CLASS); 1100 } catch (NameNotFoundException nnfe) { 1101 // No recovery 1102 Log.d(LOG_TAG, "Cannot get Metadata for: " + getComponentName().toString()); 1103 } 1104 } 1105 1106 // give subclasses access to the Next button 1107 public boolean hasNextButton() { 1108 return mNextButton != null; 1109 } 1110 1111 public Button getNextButton() { 1112 return mNextButton; 1113 } 1114 1115 @Override 1116 public boolean shouldUpRecreateTask(Intent targetIntent) { 1117 return super.shouldUpRecreateTask(new Intent(this, SettingsActivity.class)); 1118 } 1119 1120 @Override 1121 public boolean onQueryTextSubmit(String query) { 1122 switchToSearchResultsFragmentIfNeeded(); 1123 mSearchQuery = query; 1124 return mSearchResultsFragment.onQueryTextSubmit(query); 1125 } 1126 1127 @Override 1128 public boolean onQueryTextChange(String newText) { 1129 mSearchQuery = newText; 1130 if (mSearchResultsFragment == null) { 1131 return false; 1132 } 1133 return mSearchResultsFragment.onQueryTextChange(newText); 1134 } 1135 1136 @Override 1137 public boolean onClose() { 1138 return false; 1139 } 1140 1141 @Override 1142 public boolean onMenuItemActionExpand(MenuItem item) { 1143 if (item.getItemId() == mSearchMenuItem.getItemId()) { 1144 switchToSearchResultsFragmentIfNeeded(); 1145 } 1146 return true; 1147 } 1148 1149 @Override 1150 public boolean onMenuItemActionCollapse(MenuItem item) { 1151 if (item.getItemId() == mSearchMenuItem.getItemId()) { 1152 if (mSearchMenuItemExpanded) { 1153 revertToInitialFragment(); 1154 } 1155 } 1156 return true; 1157 } 1158 1159 @Override 1160 protected void onTileClicked(Tile tile) { 1161 if (mIsShowingDashboard) { 1162 // If on dashboard, don't finish so the back comes back to here. 1163 openTile(tile); 1164 } else { 1165 super.onTileClicked(tile); 1166 } 1167 } 1168 1169 @Override 1170 public void onProfileTileOpen() { 1171 if (!mIsShowingDashboard) { 1172 finish(); 1173 } 1174 } 1175 1176 private void switchToSearchResultsFragmentIfNeeded() { 1177 if (mSearchResultsFragment != null) { 1178 return; 1179 } 1180 Fragment current = getFragmentManager().findFragmentById(R.id.main_content); 1181 if (current != null && current instanceof SearchResultsSummary) { 1182 mSearchResultsFragment = (SearchResultsSummary) current; 1183 } else { 1184 mSearchResultsFragment = (SearchResultsSummary) switchToFragment( 1185 SearchResultsSummary.class.getName(), null, false, true, 1186 R.string.search_results_title, null, true); 1187 } 1188 mSearchResultsFragment.setSearchView(mSearchView); 1189 mSearchMenuItemExpanded = true; 1190 } 1191 1192 public void needToRevertToInitialFragment() { 1193 mNeedToRevertToInitialFragment = true; 1194 } 1195 1196 private void revertToInitialFragment() { 1197 mNeedToRevertToInitialFragment = false; 1198 mSearchResultsFragment = null; 1199 mSearchMenuItemExpanded = false; 1200 getFragmentManager().popBackStackImmediate(SettingsActivity.BACK_STACK_PREFS, 1201 FragmentManager.POP_BACK_STACK_INCLUSIVE); 1202 if (mSearchMenuItem != null) { 1203 mSearchMenuItem.collapseActionView(); 1204 } 1205 } 1206 1207 public Intent getResultIntentData() { 1208 return mResultIntentData; 1209 } 1210 1211 public void setResultIntentData(Intent resultIntentData) { 1212 mResultIntentData = resultIntentData; 1213 } 1214 1215 public void startSuggestion(Intent intent) { 1216 mCurrentSuggestion = intent.getComponent(); 1217 startActivityForResult(intent, REQUEST_SUGGESTION); 1218 } 1219 1220 @Override 1221 protected void onActivityResult(int requestCode, int resultCode, Intent data) { 1222 if (requestCode == REQUEST_SUGGESTION && mCurrentSuggestion != null 1223 && resultCode != RESULT_CANCELED) { 1224 getPackageManager().setComponentEnabledSetting(mCurrentSuggestion, 1225 PackageManager.COMPONENT_ENABLED_STATE_DISABLED, PackageManager.DONT_KILL_APP); 1226 } 1227 super.onActivityResult(requestCode, resultCode, data); 1228 } 1229 1230} 1231