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