SettingsActivity.java revision 976bb3f45915bdd5165d9a50402d4c1163dae809
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.pm.ResolveInfo; 33import android.content.res.Configuration; 34import android.nfc.NfcAdapter; 35import android.os.AsyncTask; 36import android.os.Bundle; 37import android.os.UserHandle; 38import android.os.UserManager; 39import android.support.v14.preference.PreferenceFragment; 40import android.support.v7.preference.Preference; 41import android.support.v7.preference.PreferenceManager; 42import android.text.TextUtils; 43import android.transition.TransitionManager; 44import android.util.Log; 45import android.view.Menu; 46import android.view.MenuInflater; 47import android.view.MenuItem; 48import android.view.View; 49import android.view.View.OnClickListener; 50import android.view.ViewGroup; 51import android.widget.Button; 52import android.widget.SearchView; 53import com.android.internal.util.ArrayUtils; 54import com.android.settings.Settings.WifiSettingsActivity; 55import com.android.settings.accessibility.AccessibilitySettings; 56import com.android.settings.accessibility.AccessibilitySettingsForSetupWizard; 57import com.android.settings.accessibility.CaptionPropertiesFragment; 58import com.android.settings.accounts.AccountSettings; 59import com.android.settings.accounts.AccountSyncSettings; 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.ManageDefaultApps; 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.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.Tile; 118import com.android.settingslib.drawer.SettingsDrawerActivity; 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 ZenModeSettings.class.getName(), 297 SoundSettings.class.getName(), 298 ConfigureNotificationSettings.class.getName(), 299 ChooseLockPassword.ChooseLockPasswordFragment.class.getName(), 300 ChooseLockPattern.ChooseLockPatternFragment.class.getName(), 301 InstalledAppDetails.class.getName(), 302 BatterySaverSettings.class.getName(), 303 AppNotificationSettings.class.getName(), 304 OtherSoundSettings.class.getName(), 305 ApnSettings.class.getName(), 306 WifiCallingSettings.class.getName(), 307 ZenModePrioritySettings.class.getName(), 308 ZenModeAutomationSettings.class.getName(), 309 ZenModeScheduleRuleSettings.class.getName(), 310 ZenModeEventRuleSettings.class.getName(), 311 ZenModeVisualInterruptionSettings.class.getName(), 312 ProcessStatsUi.class.getName(), 313 PowerUsageDetail.class.getName(), 314 ProcessStatsSummary.class.getName(), 315 DrawOverlayDetails.class.getName(), 316 WriteSettingsDetails.class.getName(), 317 ManageDefaultApps.class.getName(), 318 }; 319 320 321 private static final String[] LIKE_SHORTCUT_INTENT_ACTION_ARRAY = { 322 "android.settings.APPLICATION_DETAILS_SETTINGS" 323 }; 324 325 private SharedPreferences mDevelopmentPreferences; 326 private SharedPreferences.OnSharedPreferenceChangeListener mDevelopmentPreferencesListener; 327 328 private boolean mBatteryPresent = true; 329 private BroadcastReceiver mBatteryInfoReceiver = new BroadcastReceiver() { 330 @Override 331 public void onReceive(Context context, Intent intent) { 332 String action = intent.getAction(); 333 if (Intent.ACTION_BATTERY_CHANGED.equals(action)) { 334 boolean batteryPresent = Utils.isBatteryPresent(intent); 335 336 if (mBatteryPresent != batteryPresent) { 337 mBatteryPresent = batteryPresent; 338 updateTilesList(); 339 } 340 } 341 } 342 }; 343 344 private final BroadcastReceiver mUserAddRemoveReceiver = new BroadcastReceiver() { 345 @Override 346 public void onReceive(Context context, Intent intent) { 347 String action = intent.getAction(); 348 if (action.equals(Intent.ACTION_USER_ADDED) 349 || action.equals(Intent.ACTION_USER_REMOVED)) { 350 Index.getInstance(getApplicationContext()).update(); 351 } 352 } 353 }; 354 355 private final DynamicIndexableContentMonitor mDynamicIndexableContentMonitor = 356 new DynamicIndexableContentMonitor(); 357 358 private ActionBar mActionBar; 359 private SwitchBar mSwitchBar; 360 361 private Button mNextButton; 362 363 private boolean mDisplayHomeAsUpEnabled; 364 private boolean mDisplaySearch; 365 366 private boolean mIsShowingDashboard; 367 private boolean mIsShortcut; 368 369 private ViewGroup mContent; 370 371 private SearchView mSearchView; 372 private MenuItem mSearchMenuItem; 373 private boolean mSearchMenuItemExpanded = false; 374 private SearchResultsSummary mSearchResultsFragment; 375 private String mSearchQuery; 376 377 // Categories 378 private ArrayList<DashboardCategory> mCategories = new ArrayList<DashboardCategory>(); 379 380 private static final String MSG_DATA_FORCE_REFRESH = "msg_data_force_refresh"; 381 382 private boolean mNeedToRevertToInitialFragment = false; 383 private int mHomeActivitiesCount = 1; 384 385 private Intent mResultIntentData; 386 private ComponentName mCurrentSuggestion; 387 388 public SwitchBar getSwitchBar() { 389 return mSwitchBar; 390 } 391 392 @Override 393 public boolean onPreferenceStartFragment(PreferenceFragment caller, Preference pref) { 394 // Override the fragment title for Wallpaper settings 395 CharSequence title = pref.getTitle(); 396 if (pref.getFragment().equals(WallpaperTypeSettings.class.getName())) { 397 title = getString(R.string.wallpaper_settings_fragment_title); 398 } 399 startPreferencePanel(pref.getFragment(), pref.getExtras(), -1, title, 400 null, 0); 401 return true; 402 } 403 404 @Override 405 public boolean onPreferenceTreeClick(Preference preference) { 406 return false; 407 } 408 409 @Override 410 public void onConfigurationChanged(Configuration newConfig) { 411 super.onConfigurationChanged(newConfig); 412 Index.getInstance(this).update(); 413 } 414 415 @Override 416 protected void onStart() { 417 super.onStart(); 418 419 if (mNeedToRevertToInitialFragment) { 420 revertToInitialFragment(); 421 } 422 } 423 424 @Override 425 public boolean onCreateOptionsMenu(Menu menu) { 426 if (!mDisplaySearch) { 427 return false; 428 } 429 430 MenuInflater inflater = getMenuInflater(); 431 inflater.inflate(R.menu.options_menu, menu); 432 433 // Cache the search query (can be overriden by the OnQueryTextListener) 434 final String query = mSearchQuery; 435 436 mSearchMenuItem = menu.findItem(R.id.search); 437 mSearchView = (SearchView) mSearchMenuItem.getActionView(); 438 439 if (mSearchMenuItem == null || mSearchView == null) { 440 return false; 441 } 442 443 if (mSearchResultsFragment != null) { 444 mSearchResultsFragment.setSearchView(mSearchView); 445 } 446 447 mSearchMenuItem.setOnActionExpandListener(this); 448 mSearchView.setOnQueryTextListener(this); 449 mSearchView.setOnCloseListener(this); 450 451 if (mSearchMenuItemExpanded) { 452 mSearchMenuItem.expandActionView(); 453 } 454 mSearchView.setQuery(query, true /* submit */); 455 456 return true; 457 } 458 459 private static boolean isShortCutIntent(final Intent intent) { 460 Set<String> categories = intent.getCategories(); 461 return (categories != null) && categories.contains("com.android.settings.SHORTCUT"); 462 } 463 464 private static boolean isLikeShortCutIntent(final Intent intent) { 465 String action = intent.getAction(); 466 if (action == null) { 467 return false; 468 } 469 for (int i = 0; i < LIKE_SHORTCUT_INTENT_ACTION_ARRAY.length; i++) { 470 if (LIKE_SHORTCUT_INTENT_ACTION_ARRAY[i].equals(action)) return true; 471 } 472 return false; 473 } 474 475 @Override 476 protected void onCreate(Bundle savedState) { 477 super.onCreate(savedState); 478 long startTime = System.currentTimeMillis(); 479 480 // Should happen before any call to getIntent() 481 getMetaData(); 482 483 final Intent intent = getIntent(); 484 if (intent.hasExtra(EXTRA_UI_OPTIONS)) { 485 getWindow().setUiOptions(intent.getIntExtra(EXTRA_UI_OPTIONS, 0)); 486 } 487 488 mDevelopmentPreferences = getSharedPreferences(DevelopmentSettings.PREF_FILE, 489 Context.MODE_PRIVATE); 490 491 // Getting Intent properties can only be done after the super.onCreate(...) 492 final String initialFragmentName = intent.getStringExtra(EXTRA_SHOW_FRAGMENT); 493 494 mIsShortcut = isShortCutIntent(intent) || isLikeShortCutIntent(intent) || 495 intent.getBooleanExtra(EXTRA_SHOW_FRAGMENT_AS_SHORTCUT, false); 496 497 final ComponentName cn = intent.getComponent(); 498 final String className = cn.getClassName(); 499 500 mIsShowingDashboard = className.equals(Settings.class.getName()) 501 || className.equals(Settings.WirelessSettings.class.getName()) 502 || className.equals(Settings.DeviceSettings.class.getName()) 503 || className.equals(Settings.PersonalSettings.class.getName()) 504 || className.equals(Settings.WirelessSettings.class.getName()); 505 506 // This is a "Sub Settings" when: 507 // - this is a real SubSettings 508 // - or :settings:show_fragment_as_subsetting is passed to the Intent 509 final boolean isSubSettings = this instanceof SubSettings || 510 intent.getBooleanExtra(EXTRA_SHOW_FRAGMENT_AS_SUBSETTING, false); 511 512 // If this is a sub settings, then apply the SubSettings Theme for the ActionBar content insets 513 if (isSubSettings) { 514 // Check also that we are not a Theme Dialog as we don't want to override them 515 final int themeResId = getThemeResId(); 516 if (themeResId != R.style.Theme_DialogWhenLarge && 517 themeResId != R.style.Theme_SubSettingsDialogWhenLarge) { 518 setTheme(R.style.Theme_SubSettings); 519 } 520 } 521 522 setContentView(mIsShowingDashboard ? 523 R.layout.settings_main_dashboard : R.layout.settings_main_prefs); 524 525 mContent = (ViewGroup) findViewById(R.id.main_content); 526 527 getFragmentManager().addOnBackStackChangedListener(this); 528 529 if (mIsShowingDashboard) { 530 // Run the Index update only if we have some space 531 if (!Utils.isLowStorage(this)) { 532 long indexStartTime = System.currentTimeMillis(); 533 AsyncTask.execute(new Runnable() { 534 @Override 535 public void run() { 536 Index.getInstance(getApplicationContext()).update(); 537 } 538 }); 539 if (DEBUG_TIMING) Log.d(LOG_TAG, "Index.update() took " 540 + (System.currentTimeMillis() - indexStartTime) + " ms"); 541 } else { 542 Log.w(LOG_TAG, "Cannot update the Indexer as we are running low on storage space!"); 543 } 544 } 545 546 if (savedState != null) { 547 // We are restarting from a previous saved state; used that to initialize, instead 548 // of starting fresh. 549 mSearchMenuItemExpanded = savedState.getBoolean(SAVE_KEY_SEARCH_MENU_EXPANDED); 550 mSearchQuery = savedState.getString(SAVE_KEY_SEARCH_QUERY); 551 552 setTitleFromIntent(intent); 553 554 ArrayList<DashboardCategory> categories = 555 savedState.getParcelableArrayList(SAVE_KEY_CATEGORIES); 556 if (categories != null) { 557 mCategories.clear(); 558 mCategories.addAll(categories); 559 setTitleFromBackStack(); 560 } 561 562 mDisplayHomeAsUpEnabled = savedState.getBoolean(SAVE_KEY_SHOW_HOME_AS_UP); 563 mDisplaySearch = savedState.getBoolean(SAVE_KEY_SHOW_SEARCH); 564 mHomeActivitiesCount = savedState.getInt(SAVE_KEY_HOME_ACTIVITIES_COUNT, 565 1 /* one home activity by default */); 566 } else { 567 if (!mIsShowingDashboard) { 568 mDisplaySearch = false; 569 // UP will be shown only if it is a sub settings 570 if (mIsShortcut) { 571 mDisplayHomeAsUpEnabled = isSubSettings; 572 } else if (isSubSettings) { 573 mDisplayHomeAsUpEnabled = true; 574 } else { 575 mDisplayHomeAsUpEnabled = false; 576 } 577 setTitleFromIntent(intent); 578 579 Bundle initialArguments = intent.getBundleExtra(EXTRA_SHOW_FRAGMENT_ARGUMENTS); 580 switchToFragment(initialFragmentName, initialArguments, true, false, 581 mInitialTitleResId, mInitialTitle, false); 582 } else { 583 // No UP affordance if we are displaying the main Dashboard 584 mDisplayHomeAsUpEnabled = false; 585 // Show Search affordance 586 mDisplaySearch = true; 587 mInitialTitleResId = R.string.dashboard_title; 588 switchToFragment(DashboardSummary.class.getName(), null, false, false, 589 mInitialTitleResId, mInitialTitle, false); 590 } 591 } 592 593 mActionBar = getActionBar(); 594 if (mActionBar != null) { 595 mActionBar.setDisplayHomeAsUpEnabled(mDisplayHomeAsUpEnabled); 596 mActionBar.setHomeButtonEnabled(mDisplayHomeAsUpEnabled); 597 } 598 mSwitchBar = (SwitchBar) findViewById(R.id.switch_bar); 599 600 // see if we should show Back/Next buttons 601 if (intent.getBooleanExtra(EXTRA_PREFS_SHOW_BUTTON_BAR, false)) { 602 603 View buttonBar = findViewById(R.id.button_bar); 604 if (buttonBar != null) { 605 buttonBar.setVisibility(View.VISIBLE); 606 607 Button backButton = (Button)findViewById(R.id.back_button); 608 backButton.setOnClickListener(new OnClickListener() { 609 public void onClick(View v) { 610 setResult(RESULT_CANCELED, getResultIntentData()); 611 finish(); 612 } 613 }); 614 Button skipButton = (Button)findViewById(R.id.skip_button); 615 skipButton.setOnClickListener(new OnClickListener() { 616 public void onClick(View v) { 617 setResult(RESULT_OK, getResultIntentData()); 618 finish(); 619 } 620 }); 621 mNextButton = (Button)findViewById(R.id.next_button); 622 mNextButton.setOnClickListener(new OnClickListener() { 623 public void onClick(View v) { 624 setResult(RESULT_OK, getResultIntentData()); 625 finish(); 626 } 627 }); 628 629 // set our various button parameters 630 if (intent.hasExtra(EXTRA_PREFS_SET_NEXT_TEXT)) { 631 String buttonText = intent.getStringExtra(EXTRA_PREFS_SET_NEXT_TEXT); 632 if (TextUtils.isEmpty(buttonText)) { 633 mNextButton.setVisibility(View.GONE); 634 } 635 else { 636 mNextButton.setText(buttonText); 637 } 638 } 639 if (intent.hasExtra(EXTRA_PREFS_SET_BACK_TEXT)) { 640 String buttonText = intent.getStringExtra(EXTRA_PREFS_SET_BACK_TEXT); 641 if (TextUtils.isEmpty(buttonText)) { 642 backButton.setVisibility(View.GONE); 643 } 644 else { 645 backButton.setText(buttonText); 646 } 647 } 648 if (intent.getBooleanExtra(EXTRA_PREFS_SHOW_SKIP, false)) { 649 skipButton.setVisibility(View.VISIBLE); 650 } 651 } 652 } 653 654 mHomeActivitiesCount = getHomeActivitiesCount(); 655 if (DEBUG_TIMING) Log.d(LOG_TAG, "onCreate took " + (System.currentTimeMillis() - startTime) 656 + " ms"); 657 } 658 659 private int getHomeActivitiesCount() { 660 final ArrayList<ResolveInfo> homeApps = new ArrayList<ResolveInfo>(); 661 getPackageManager().getHomeActivities(homeApps); 662 return homeApps.size(); 663 } 664 665 private void setTitleFromIntent(Intent intent) { 666 final int initialTitleResId = intent.getIntExtra(EXTRA_SHOW_FRAGMENT_TITLE_RESID, -1); 667 if (initialTitleResId > 0) { 668 mInitialTitle = null; 669 mInitialTitleResId = initialTitleResId; 670 671 final String initialTitleResPackageName = intent.getStringExtra( 672 EXTRA_SHOW_FRAGMENT_TITLE_RES_PACKAGE_NAME); 673 if (initialTitleResPackageName != null) { 674 try { 675 Context authContext = createPackageContextAsUser(initialTitleResPackageName, 676 0 /* flags */, new UserHandle(UserHandle.myUserId())); 677 mInitialTitle = authContext.getResources().getText(mInitialTitleResId); 678 setTitle(mInitialTitle); 679 mInitialTitleResId = -1; 680 return; 681 } catch (NameNotFoundException e) { 682 Log.w(LOG_TAG, "Could not find package" + initialTitleResPackageName); 683 } 684 } else { 685 setTitle(mInitialTitleResId); 686 } 687 } else { 688 mInitialTitleResId = -1; 689 final String initialTitle = intent.getStringExtra(EXTRA_SHOW_FRAGMENT_TITLE); 690 mInitialTitle = (initialTitle != null) ? initialTitle : getTitle(); 691 setTitle(mInitialTitle); 692 } 693 } 694 695 @Override 696 public void onBackStackChanged() { 697 setTitleFromBackStack(); 698 } 699 700 private int setTitleFromBackStack() { 701 final int count = getFragmentManager().getBackStackEntryCount(); 702 703 if (count == 0) { 704 if (mInitialTitleResId > 0) { 705 setTitle(mInitialTitleResId); 706 } else { 707 setTitle(mInitialTitle); 708 } 709 return 0; 710 } 711 712 FragmentManager.BackStackEntry bse = getFragmentManager().getBackStackEntryAt(count - 1); 713 setTitleFromBackStackEntry(bse); 714 715 return count; 716 } 717 718 private void setTitleFromBackStackEntry(FragmentManager.BackStackEntry bse) { 719 final CharSequence title; 720 final int titleRes = bse.getBreadCrumbTitleRes(); 721 if (titleRes > 0) { 722 title = getText(titleRes); 723 } else { 724 title = bse.getBreadCrumbTitle(); 725 } 726 if (title != null) { 727 setTitle(title); 728 } 729 } 730 731 @Override 732 protected void onSaveInstanceState(Bundle outState) { 733 super.onSaveInstanceState(outState); 734 735 if (mCategories.size() > 0) { 736 outState.putParcelableArrayList(SAVE_KEY_CATEGORIES, mCategories); 737 } 738 739 outState.putBoolean(SAVE_KEY_SHOW_HOME_AS_UP, mDisplayHomeAsUpEnabled); 740 outState.putBoolean(SAVE_KEY_SHOW_SEARCH, mDisplaySearch); 741 742 if (mDisplaySearch) { 743 // The option menus are created if the ActionBar is visible and they are also created 744 // asynchronously. If you launch Settings with an Intent action like 745 // android.intent.action.POWER_USAGE_SUMMARY and at the same time your device is locked 746 // thru a LockScreen, onCreateOptionsMenu() is not yet called and references to the search 747 // menu item and search view are null. 748 boolean isExpanded = (mSearchMenuItem != null) && mSearchMenuItem.isActionViewExpanded(); 749 outState.putBoolean(SAVE_KEY_SEARCH_MENU_EXPANDED, isExpanded); 750 751 String query = (mSearchView != null) ? mSearchView.getQuery().toString() : EMPTY_QUERY; 752 outState.putString(SAVE_KEY_SEARCH_QUERY, query); 753 } 754 755 outState.putInt(SAVE_KEY_HOME_ACTIVITIES_COUNT, mHomeActivitiesCount); 756 } 757 758 @Override 759 protected void onResume() { 760 super.onResume(); 761 762 mDevelopmentPreferencesListener = new SharedPreferences.OnSharedPreferenceChangeListener() { 763 @Override 764 public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) { 765 updateTilesList(); 766 } 767 }; 768 mDevelopmentPreferences.registerOnSharedPreferenceChangeListener( 769 mDevelopmentPreferencesListener); 770 771 registerReceiver(mBatteryInfoReceiver, new IntentFilter(Intent.ACTION_BATTERY_CHANGED)); 772 registerReceiver(mUserAddRemoveReceiver, new IntentFilter(Intent.ACTION_USER_ADDED)); 773 registerReceiver(mUserAddRemoveReceiver, new IntentFilter(Intent.ACTION_USER_REMOVED)); 774 775 mDynamicIndexableContentMonitor.register(this); 776 777 if(mDisplaySearch && !TextUtils.isEmpty(mSearchQuery)) { 778 onQueryTextSubmit(mSearchQuery); 779 } 780 updateTilesList(); 781 } 782 783 @Override 784 protected void onPause() { 785 super.onPause(); 786 unregisterReceiver(mBatteryInfoReceiver); 787 unregisterReceiver(mUserAddRemoveReceiver); 788 mDynamicIndexableContentMonitor.unregister(); 789 } 790 791 @Override 792 public void onDestroy() { 793 super.onDestroy(); 794 795 mDevelopmentPreferences.unregisterOnSharedPreferenceChangeListener( 796 mDevelopmentPreferencesListener); 797 mDevelopmentPreferencesListener = null; 798 } 799 800 protected boolean isValidFragment(String fragmentName) { 801 // Almost all fragments are wrapped in this, 802 // except for a few that have their own activities. 803 for (int i = 0; i < ENTRY_FRAGMENTS.length; i++) { 804 if (ENTRY_FRAGMENTS[i].equals(fragmentName)) return true; 805 } 806 return false; 807 } 808 809 @Override 810 public Intent getIntent() { 811 Intent superIntent = super.getIntent(); 812 String startingFragment = getStartingFragmentClass(superIntent); 813 // This is called from super.onCreate, isMultiPane() is not yet reliable 814 // Do not use onIsHidingHeaders either, which relies itself on this method 815 if (startingFragment != null) { 816 Intent modIntent = new Intent(superIntent); 817 modIntent.putExtra(EXTRA_SHOW_FRAGMENT, startingFragment); 818 Bundle args = superIntent.getExtras(); 819 if (args != null) { 820 args = new Bundle(args); 821 } else { 822 args = new Bundle(); 823 } 824 args.putParcelable("intent", superIntent); 825 modIntent.putExtra(EXTRA_SHOW_FRAGMENT_ARGUMENTS, args); 826 return modIntent; 827 } 828 return superIntent; 829 } 830 831 /** 832 * Checks if the component name in the intent is different from the Settings class and 833 * returns the class name to load as a fragment. 834 */ 835 private String getStartingFragmentClass(Intent intent) { 836 if (mFragmentClass != null) return mFragmentClass; 837 838 String intentClass = intent.getComponent().getClassName(); 839 if (intentClass.equals(getClass().getName())) return null; 840 841 if ("com.android.settings.ManageApplications".equals(intentClass) 842 || "com.android.settings.RunningServices".equals(intentClass) 843 || "com.android.settings.applications.StorageUse".equals(intentClass)) { 844 // Old names of manage apps. 845 intentClass = com.android.settings.applications.ManageApplications.class.getName(); 846 } 847 848 return intentClass; 849 } 850 851 /** 852 * Start a new fragment containing a preference panel. If the preferences 853 * are being displayed in multi-pane mode, the given fragment class will 854 * be instantiated and placed in the appropriate pane. If running in 855 * single-pane mode, a new activity will be launched in which to show the 856 * fragment. 857 * 858 * @param fragmentClass Full name of the class implementing the fragment. 859 * @param args Any desired arguments to supply to the fragment. 860 * @param titleRes Optional resource identifier of the title of this 861 * fragment. 862 * @param titleText Optional text of the title of this fragment. 863 * @param resultTo Optional fragment that result data should be sent to. 864 * If non-null, resultTo.onActivityResult() will be called when this 865 * preference panel is done. The launched panel must use 866 * {@link #finishPreferencePanel(Fragment, int, Intent)} when done. 867 * @param resultRequestCode If resultTo is non-null, this is the caller's 868 * request code to be received with the result. 869 */ 870 public void startPreferencePanel(String fragmentClass, Bundle args, int titleRes, 871 CharSequence titleText, Fragment resultTo, int resultRequestCode) { 872 String title = null; 873 if (titleRes < 0) { 874 if (titleText != null) { 875 title = titleText.toString(); 876 } else { 877 // There not much we can do in that case 878 title = ""; 879 } 880 } 881 Utils.startWithFragment(this, fragmentClass, args, resultTo, resultRequestCode, 882 titleRes, title, mIsShortcut); 883 } 884 885 /** 886 * Start a new fragment in a new activity containing a preference panel for a given user. If the 887 * preferences are being displayed in multi-pane mode, the given fragment class will be 888 * instantiated and placed in the appropriate pane. If running in single-pane mode, a new 889 * activity will be launched in which to show the fragment. 890 * 891 * @param fragmentClass Full name of the class implementing the fragment. 892 * @param args Any desired arguments to supply to the fragment. 893 * @param titleRes Optional resource identifier of the title of this fragment. 894 * @param titleText Optional text of the title of this fragment. 895 * @param userHandle The user for which the panel has to be started. 896 */ 897 public void startPreferencePanelAsUser(String fragmentClass, Bundle args, int titleRes, 898 CharSequence titleText, UserHandle userHandle) { 899 // This is a workaround. 900 // 901 // Calling startWithFragmentAsUser() without specifying FLAG_ACTIVITY_NEW_TASK to the intent 902 // starting the fragment could cause a native stack corruption. See b/17523189. However, 903 // adding that flag and start the preference panel with the same UserHandler will make it 904 // impossible to use back button to return to the previous screen. See b/20042570. 905 // 906 // We work around this issue by adding FLAG_ACTIVITY_NEW_TASK to the intent, while doing 907 // another check here to call startPreferencePanel() instead of startWithFragmentAsUser() 908 // when we're calling it as the same user. 909 if (userHandle.getIdentifier() == UserHandle.myUserId()) { 910 startPreferencePanel(fragmentClass, args, titleRes, titleText, null, 0); 911 } else { 912 String title = null; 913 if (titleRes < 0) { 914 if (titleText != null) { 915 title = titleText.toString(); 916 } else { 917 // There not much we can do in that case 918 title = ""; 919 } 920 } 921 Utils.startWithFragmentAsUser(this, fragmentClass, args, 922 titleRes, title, mIsShortcut, userHandle); 923 } 924 } 925 926 /** 927 * Called by a preference panel fragment to finish itself. 928 * 929 * @param caller The fragment that is asking to be finished. 930 * @param resultCode Optional result code to send back to the original 931 * launching fragment. 932 * @param resultData Optional result data to send back to the original 933 * launching fragment. 934 */ 935 public void finishPreferencePanel(Fragment caller, int resultCode, Intent resultData) { 936 setResult(resultCode, resultData); 937 finish(); 938 } 939 940 /** 941 * Start a new fragment. 942 * 943 * @param fragment The fragment to start 944 * @param push If true, the current fragment will be pushed onto the back stack. If false, 945 * the current fragment will be replaced. 946 */ 947 public void startPreferenceFragment(Fragment fragment, boolean push) { 948 FragmentTransaction transaction = getFragmentManager().beginTransaction(); 949 transaction.replace(R.id.main_content, fragment); 950 if (push) { 951 transaction.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN); 952 transaction.addToBackStack(BACK_STACK_PREFS); 953 } else { 954 transaction.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_FADE); 955 } 956 transaction.commitAllowingStateLoss(); 957 } 958 959 /** 960 * Switch to a specific Fragment with taking care of validation, Title and BackStack 961 */ 962 private Fragment switchToFragment(String fragmentName, Bundle args, boolean validate, 963 boolean addToBackStack, int titleResId, CharSequence title, boolean withTransition) { 964 if (validate && !isValidFragment(fragmentName)) { 965 throw new IllegalArgumentException("Invalid fragment for this activity: " 966 + fragmentName); 967 } 968 Fragment f = Fragment.instantiate(this, fragmentName, args); 969 FragmentTransaction transaction = getFragmentManager().beginTransaction(); 970 transaction.replace(R.id.main_content, f); 971 if (withTransition) { 972 TransitionManager.beginDelayedTransition(mContent); 973 } 974 if (addToBackStack) { 975 transaction.addToBackStack(SettingsActivity.BACK_STACK_PREFS); 976 } 977 if (titleResId > 0) { 978 transaction.setBreadCrumbTitle(titleResId); 979 } else if (title != null) { 980 transaction.setBreadCrumbTitle(title); 981 } 982 transaction.commitAllowingStateLoss(); 983 getFragmentManager().executePendingTransactions(); 984 return f; 985 } 986 987 private void updateTilesList() { 988 // Generally the items that are will be changing from these updates will 989 // not be in the top list of tiles, so run it in the background and the 990 // SettingsDrawerActivity will pick up on the updates automatically. 991 AsyncTask.execute(new Runnable() { 992 @Override 993 public void run() { 994 doUpdateTilesList(); 995 } 996 }); 997 } 998 999 private void doUpdateTilesList() { 1000 PackageManager pm = getPackageManager(); 1001 final UserManager um = UserManager.get(this); 1002 final boolean isAdmin = um.isAdminUser(); 1003 1004 String packageName = getPackageName(); 1005 setTileEnabled(new ComponentName(packageName, WifiSettingsActivity.class.getName()), 1006 pm.hasSystemFeature(PackageManager.FEATURE_WIFI), isAdmin, pm); 1007 1008 setTileEnabled(new ComponentName(packageName, 1009 Settings.BluetoothSettingsActivity.class.getName()), 1010 pm.hasSystemFeature(PackageManager.FEATURE_BLUETOOTH), isAdmin, pm); 1011 1012 setTileEnabled(new ComponentName(packageName, 1013 Settings.DataUsageSummaryActivity.class.getName()), 1014 Utils.isBandwidthControlEnabled(), isAdmin, pm); 1015 1016 setTileEnabled(new ComponentName(packageName, 1017 Settings.SimSettingsActivity.class.getName()), 1018 Utils.showSimCardTile(this), isAdmin, pm); 1019 1020 setTileEnabled(new ComponentName(packageName, 1021 Settings.PowerUsageSummaryActivity.class.getName()), 1022 mBatteryPresent, isAdmin, pm); 1023 1024 setTileEnabled(new ComponentName(packageName, 1025 Settings.HomeSettingsActivity.class.getName()), 1026 updateHomeSettingTiles(), isAdmin, pm); 1027 1028 setTileEnabled(new ComponentName(packageName, 1029 Settings.UserSettingsActivity.class.getName()), 1030 UserHandle.MU_ENABLED && UserManager.supportsMultipleUsers() 1031 && !Utils.isMonkeyRunning(), isAdmin, pm); 1032 1033 NfcAdapter adapter = NfcAdapter.getDefaultAdapter(this); 1034 setTileEnabled(new ComponentName(packageName, 1035 Settings.PaymentSettingsActivity.class.getName()), 1036 pm.hasSystemFeature(PackageManager.FEATURE_NFC) 1037 && pm.hasSystemFeature(PackageManager.FEATURE_NFC_HOST_CARD_EMULATION) 1038 && adapter != null && adapter.isEnabled(), isAdmin, pm); 1039 1040 setTileEnabled(new ComponentName(packageName, 1041 Settings.PrintSettingsActivity.class.getName()), 1042 pm.hasSystemFeature(PackageManager.FEATURE_PRINTING), isAdmin, pm); 1043 1044 final boolean showDev = mDevelopmentPreferences.getBoolean( 1045 DevelopmentSettings.PREF_SHOW, 1046 android.os.Build.TYPE.equals("eng")); 1047 setTileEnabled(new ComponentName(packageName, 1048 Settings.DevelopmentSettingsActivity.class.getName()), 1049 showDev && !um.hasUserRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES), 1050 isAdmin, pm); 1051 1052 if (UserHandle.MU_ENABLED && !isAdmin) { 1053 // When on restricted users, disable all extra categories (but only the settings ones). 1054 List<DashboardCategory> categories = getDashboardCategories(); 1055 for (DashboardCategory category : categories) { 1056 for (Tile tile : category.tiles) { 1057 ComponentName component = tile.intent.getComponent(); 1058 if (packageName.equals(component)&& !ArrayUtils.contains( 1059 SETTINGS_FOR_RESTRICTED, component.getClassName())) { 1060 setTileEnabled(component, false, isAdmin, pm); 1061 } 1062 } 1063 } 1064 } 1065 } 1066 1067 private void setTileEnabled(ComponentName component, boolean enabled, boolean isAdmin, 1068 PackageManager pm) { 1069 if (UserHandle.MU_ENABLED && !isAdmin 1070 && !ArrayUtils.contains(SETTINGS_FOR_RESTRICTED, component.getClassName())) { 1071 enabled = false; 1072 } 1073 int state = pm.getComponentEnabledSetting(component); 1074 boolean isEnabled = state == PackageManager.COMPONENT_ENABLED_STATE_DEFAULT 1075 || state == PackageManager.COMPONENT_ENABLED_STATE_ENABLED; 1076 if (isEnabled != enabled) { 1077 pm.setComponentEnabledSetting(component, enabled 1078 ? PackageManager.COMPONENT_ENABLED_STATE_ENABLED 1079 : PackageManager.COMPONENT_ENABLED_STATE_DISABLED, 1080 PackageManager.DONT_KILL_APP); 1081 } 1082 } 1083 1084 private boolean updateHomeSettingTiles() { 1085 // Once we decide to show Home settings, keep showing it forever 1086 SharedPreferences sp = getSharedPreferences(HomeSettings.HOME_PREFS, Context.MODE_PRIVATE); 1087 if (sp.getBoolean(HomeSettings.HOME_PREFS_DO_SHOW, false)) { 1088 return true; 1089 } 1090 1091 try { 1092 mHomeActivitiesCount = getHomeActivitiesCount(); 1093 if (mHomeActivitiesCount < 2) { 1094 return false; 1095 } 1096 } catch (Exception e) { 1097 // Can't look up the home activity; bail on configuring the icon 1098 Log.w(LOG_TAG, "Problem looking up home activity!", e); 1099 } 1100 1101 sp.edit().putBoolean(HomeSettings.HOME_PREFS_DO_SHOW, true).apply(); 1102 return true; 1103 } 1104 1105 private void getMetaData() { 1106 try { 1107 ActivityInfo ai = getPackageManager().getActivityInfo(getComponentName(), 1108 PackageManager.GET_META_DATA); 1109 if (ai == null || ai.metaData == null) return; 1110 mFragmentClass = ai.metaData.getString(META_DATA_KEY_FRAGMENT_CLASS); 1111 } catch (NameNotFoundException nnfe) { 1112 // No recovery 1113 Log.d(LOG_TAG, "Cannot get Metadata for: " + getComponentName().toString()); 1114 } 1115 } 1116 1117 // give subclasses access to the Next button 1118 public boolean hasNextButton() { 1119 return mNextButton != null; 1120 } 1121 1122 public Button getNextButton() { 1123 return mNextButton; 1124 } 1125 1126 @Override 1127 public boolean shouldUpRecreateTask(Intent targetIntent) { 1128 return super.shouldUpRecreateTask(new Intent(this, SettingsActivity.class)); 1129 } 1130 1131 @Override 1132 public boolean onQueryTextSubmit(String query) { 1133 switchToSearchResultsFragmentIfNeeded(); 1134 mSearchQuery = query; 1135 return mSearchResultsFragment.onQueryTextSubmit(query); 1136 } 1137 1138 @Override 1139 public boolean onQueryTextChange(String newText) { 1140 mSearchQuery = newText; 1141 if (mSearchResultsFragment == null) { 1142 return false; 1143 } 1144 return mSearchResultsFragment.onQueryTextChange(newText); 1145 } 1146 1147 @Override 1148 public boolean onClose() { 1149 return false; 1150 } 1151 1152 @Override 1153 public boolean onMenuItemActionExpand(MenuItem item) { 1154 if (item.getItemId() == mSearchMenuItem.getItemId()) { 1155 switchToSearchResultsFragmentIfNeeded(); 1156 } 1157 return true; 1158 } 1159 1160 @Override 1161 public boolean onMenuItemActionCollapse(MenuItem item) { 1162 if (item.getItemId() == mSearchMenuItem.getItemId()) { 1163 if (mSearchMenuItemExpanded) { 1164 revertToInitialFragment(); 1165 } 1166 } 1167 return true; 1168 } 1169 1170 @Override 1171 protected void onTileClicked(Tile tile) { 1172 if (mIsShowingDashboard) { 1173 // If on dashboard, don't finish so the back comes back to here. 1174 openTile(tile); 1175 } else { 1176 super.onTileClicked(tile); 1177 } 1178 } 1179 1180 @Override 1181 public void onProfileTileOpen() { 1182 if (!mIsShowingDashboard) { 1183 finish(); 1184 } 1185 } 1186 1187 private void switchToSearchResultsFragmentIfNeeded() { 1188 if (mSearchResultsFragment != null) { 1189 return; 1190 } 1191 Fragment current = getFragmentManager().findFragmentById(R.id.main_content); 1192 if (current != null && current instanceof SearchResultsSummary) { 1193 mSearchResultsFragment = (SearchResultsSummary) current; 1194 } else { 1195 mSearchResultsFragment = (SearchResultsSummary) switchToFragment( 1196 SearchResultsSummary.class.getName(), null, false, true, 1197 R.string.search_results_title, null, true); 1198 } 1199 mSearchResultsFragment.setSearchView(mSearchView); 1200 mSearchMenuItemExpanded = true; 1201 } 1202 1203 public void needToRevertToInitialFragment() { 1204 mNeedToRevertToInitialFragment = true; 1205 } 1206 1207 private void revertToInitialFragment() { 1208 mNeedToRevertToInitialFragment = false; 1209 mSearchResultsFragment = null; 1210 mSearchMenuItemExpanded = false; 1211 getFragmentManager().popBackStackImmediate(SettingsActivity.BACK_STACK_PREFS, 1212 FragmentManager.POP_BACK_STACK_INCLUSIVE); 1213 if (mSearchMenuItem != null) { 1214 mSearchMenuItem.collapseActionView(); 1215 } 1216 } 1217 1218 public Intent getResultIntentData() { 1219 return mResultIntentData; 1220 } 1221 1222 public void setResultIntentData(Intent resultIntentData) { 1223 mResultIntentData = resultIntentData; 1224 } 1225 1226 public void startSuggestion(Intent intent) { 1227 mCurrentSuggestion = intent.getComponent(); 1228 startActivityForResult(intent, REQUEST_SUGGESTION); 1229 } 1230 1231 @Override 1232 protected void onActivityResult(int requestCode, int resultCode, Intent data) { 1233 if (requestCode == REQUEST_SUGGESTION && mCurrentSuggestion != null 1234 && resultCode != RESULT_CANCELED) { 1235 getPackageManager().setComponentEnabledSetting(mCurrentSuggestion, 1236 PackageManager.COMPONENT_ENABLED_STATE_DISABLED, PackageManager.DONT_KILL_APP); 1237 } 1238 super.onActivityResult(requestCode, resultCode, data); 1239 } 1240 1241} 1242