InstalledAppDetails.java revision 07025891683aef83d850b0a91b37aa75b11ce33c
1/** 2 * Copyright (C) 2007 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); you may not 5 * use this file except in compliance with the License. You may obtain a copy 6 * 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, WITHOUT 12 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 * License for the specific language governing permissions and limitations 14 * under the License. 15 */ 16 17package com.android.settings.applications; 18 19import android.app.Activity; 20import android.app.ActivityManager; 21import android.app.AlertDialog; 22import android.content.BroadcastReceiver; 23import android.content.ComponentName; 24import android.content.Context; 25import android.content.DialogInterface; 26import android.content.Intent; 27import android.content.pm.ApplicationInfo; 28import android.content.pm.PackageInfo; 29import android.content.pm.PackageManager; 30import android.content.pm.PackageManager.NameNotFoundException; 31import android.content.pm.ResolveInfo; 32import android.net.Uri; 33import android.os.AsyncTask; 34import android.os.Bundle; 35import android.os.UserHandle; 36import android.preference.Preference; 37import android.preference.Preference.OnPreferenceClickListener; 38import android.provider.Settings; 39import android.view.Menu; 40import android.view.MenuInflater; 41import android.view.MenuItem; 42import android.view.View; 43import android.widget.Button; 44import android.widget.ImageView; 45import android.widget.TextView; 46 47import com.android.settings.R; 48import com.android.settings.SettingsActivity; 49import com.android.settings.Utils; 50import com.android.settings.applications.ApplicationsState.AppEntry; 51import com.android.settings.notification.NotificationAppList; 52import com.android.settings.notification.NotificationAppList.AppRow; 53import com.android.settings.notification.NotificationAppList.Backend; 54 55import java.lang.ref.WeakReference; 56import java.util.ArrayList; 57import java.util.HashSet; 58import java.util.List; 59 60/** 61 * Activity to display application information from Settings. This activity presents 62 * extended information associated with a package like code, data, total size, permissions 63 * used by the application and also the set of default launchable activities. 64 * For system applications, an option to clear user data is displayed only if data size is > 0. 65 * System applications that do not want clear user data do not have this option. 66 * For non-system applications, there is no option to clear data. Instead there is an option to 67 * uninstall the application. 68 */ 69public class InstalledAppDetails extends AppInfoBase 70 implements View.OnClickListener, OnPreferenceClickListener { 71 72 // Menu identifiers 73 public static final int UNINSTALL_ALL_USERS_MENU = 1; 74 75 // Result code identifiers 76 public static final int REQUEST_UNINSTALL = 0; 77 private static final int SUB_INFO_FRAGMENT = 1; 78 79 private static final int DLG_FORCE_STOP = DLG_BASE + 1; 80 private static final int DLG_DISABLE = DLG_BASE + 2; 81 private static final int DLG_SPECIAL_DISABLE = DLG_BASE + 3; 82 private static final int DLG_FACTORY_RESET = DLG_BASE + 4; 83 84 private static final String KEY_HEADER = "header_view"; 85 private static final String KEY_NOTIFICATION = "notification_settings"; 86 private static final String KEY_STORAGE = "storage_settings"; 87 private static final String KEY_PERMISSION = "permission_settings"; 88 private static final String KEY_DATA = "data_settings"; 89 private static final String KEY_LAUNCH = "preferred_settings"; 90 91 private final HashSet<String> mHomePackages = new HashSet<String>(); 92 93 private boolean mInitialized; 94 private boolean mShowUninstalled; 95 private HeaderPreference mHeader; 96 private Button mUninstallButton; 97 private View mMoreControlButtons; 98 private Button mSpecialDisableButton; 99 private boolean mUpdatedSysApp = false; 100 private TextView mAppVersion; 101 private Button mForceStopButton; 102 private Preference mNotificationPreference; 103 private Preference mStoragePreference; 104 private Preference mPermissionsPreference; 105 private Preference mLaunchPreference; 106 private Preference mDataPreference; 107 108 private boolean mDisableAfterUninstall; 109 // Used for updating notification preference. 110 private final Backend mBackend = new Backend(); 111 112 private boolean handleDisableable(Button button) { 113 boolean disableable = false; 114 // Try to prevent the user from bricking their phone 115 // by not allowing disabling of apps signed with the 116 // system cert and any launcher app in the system. 117 if (mHomePackages.contains(mAppEntry.info.packageName) 118 || Utils.isSystemPackage(mPm, mPackageInfo)) { 119 // Disable button for core system applications. 120 button.setText(R.string.disable_text); 121 } else if (mAppEntry.info.enabled) { 122 button.setText(R.string.disable_text); 123 disableable = true; 124 } else { 125 button.setText(R.string.enable_text); 126 disableable = true; 127 } 128 129 return disableable; 130 } 131 132 private void initUninstallButtons() { 133 mUpdatedSysApp = (mAppEntry.info.flags & ApplicationInfo.FLAG_UPDATED_SYSTEM_APP) != 0; 134 final boolean isBundled = (mAppEntry.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0; 135 boolean enabled = true; 136 if (mUpdatedSysApp) { 137 mUninstallButton.setText(R.string.app_factory_reset); 138 boolean showSpecialDisable = false; 139 if (isBundled) { 140 showSpecialDisable = handleDisableable(mSpecialDisableButton); 141 mSpecialDisableButton.setOnClickListener(this); 142 } 143 if (mAppControlRestricted) { 144 showSpecialDisable = false; 145 } 146 mMoreControlButtons.setVisibility(showSpecialDisable ? View.VISIBLE : View.GONE); 147 } else { 148 mMoreControlButtons.setVisibility(View.GONE); 149 if (isBundled) { 150 enabled = handleDisableable(mUninstallButton); 151 } else if ((mPackageInfo.applicationInfo.flags 152 & ApplicationInfo.FLAG_INSTALLED) == 0 153 && mUserManager.getUsers().size() >= 2) { 154 // When we have multiple users, there is a separate menu 155 // to uninstall for all users. 156 mUninstallButton.setText(R.string.uninstall_text); 157 enabled = false; 158 } else { 159 mUninstallButton.setText(R.string.uninstall_text); 160 } 161 } 162 // If this is a device admin, it can't be uninstalled or disabled. 163 // We do this here so the text of the button is still set correctly. 164 if (mDpm.packageHasActiveAdmins(mPackageInfo.packageName)) { 165 enabled = false; 166 } 167 168 // Home apps need special handling. Bundled ones we don't risk downgrading 169 // because that can interfere with home-key resolution. Furthermore, we 170 // can't allow uninstallation of the only home app, and we don't want to 171 // allow uninstallation of an explicitly preferred one -- the user can go 172 // to Home settings and pick a different one, after which we'll permit 173 // uninstallation of the now-not-default one. 174 if (enabled && mHomePackages.contains(mPackageInfo.packageName)) { 175 if (isBundled) { 176 enabled = false; 177 } else { 178 ArrayList<ResolveInfo> homeActivities = new ArrayList<ResolveInfo>(); 179 ComponentName currentDefaultHome = mPm.getHomeActivities(homeActivities); 180 if (currentDefaultHome == null) { 181 // No preferred default, so permit uninstall only when 182 // there is more than one candidate 183 enabled = (mHomePackages.size() > 1); 184 } else { 185 // There is an explicit default home app -- forbid uninstall of 186 // that one, but permit it for installed-but-inactive ones. 187 enabled = !mPackageInfo.packageName.equals(currentDefaultHome.getPackageName()); 188 } 189 } 190 } 191 192 if (mAppControlRestricted) { 193 enabled = false; 194 } 195 196 mUninstallButton.setEnabled(enabled); 197 if (enabled) { 198 // Register listener 199 mUninstallButton.setOnClickListener(this); 200 } 201 } 202 203 /** Called when the activity is first created. */ 204 @Override 205 public void onCreate(Bundle icicle) { 206 super.onCreate(icicle); 207 208 setHasOptionsMenu(true); 209 addPreferencesFromResource(R.xml.installed_app_details); 210 } 211 212 public void onActivityCreated(Bundle savedInstanceState) { 213 super.onActivityCreated(savedInstanceState); 214 handleHeader(); 215 216 mNotificationPreference = findPreference(KEY_NOTIFICATION); 217 mNotificationPreference.setOnPreferenceClickListener(this); 218 mStoragePreference = findPreference(KEY_STORAGE); 219 mStoragePreference.setOnPreferenceClickListener(this); 220 mPermissionsPreference = findPreference(KEY_PERMISSION); 221 mPermissionsPreference.setOnPreferenceClickListener(this); 222 mLaunchPreference = findPreference(KEY_LAUNCH); 223 mLaunchPreference.setOnPreferenceClickListener(this); 224 mDataPreference = findPreference(KEY_DATA); 225 mDataPreference.setOnPreferenceClickListener(this); 226 // Data isn't ready, lets just pull it for now. 227 getPreferenceScreen().removePreference(mDataPreference); 228 } 229 230 private void handleHeader() { 231 mHeader = (HeaderPreference) findPreference(KEY_HEADER); 232 233 // Get Control button panel 234 View btnPanel = mHeader.findViewById(R.id.control_buttons_panel); 235 mForceStopButton = (Button) btnPanel.findViewById(R.id.right_button); 236 mForceStopButton.setText(R.string.force_stop); 237 mUninstallButton = (Button) btnPanel.findViewById(R.id.left_button); 238 mForceStopButton.setEnabled(false); 239 240 // Get More Control button panel 241 mMoreControlButtons = mHeader.findViewById(R.id.more_control_buttons_panel); 242 mMoreControlButtons.findViewById(R.id.right_button).setVisibility(View.INVISIBLE); 243 mSpecialDisableButton = (Button) mMoreControlButtons.findViewById(R.id.left_button); 244 mMoreControlButtons.setVisibility(View.GONE); 245 } 246 247 @Override 248 public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) { 249 menu.add(0, UNINSTALL_ALL_USERS_MENU, 1, R.string.uninstall_all_users_text) 250 .setShowAsAction(MenuItem.SHOW_AS_ACTION_NEVER); 251 } 252 253 @Override 254 public void onPrepareOptionsMenu(Menu menu) { 255 boolean showIt = true; 256 if (mUpdatedSysApp) { 257 showIt = false; 258 } else if (mAppEntry == null) { 259 showIt = false; 260 } else if ((mAppEntry.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) { 261 showIt = false; 262 } else if (mPackageInfo == null || mDpm.packageHasActiveAdmins(mPackageInfo.packageName)) { 263 showIt = false; 264 } else if (UserHandle.myUserId() != 0) { 265 showIt = false; 266 } else if (mUserManager.getUsers().size() < 2) { 267 showIt = false; 268 } 269 menu.findItem(UNINSTALL_ALL_USERS_MENU).setVisible(showIt); 270 } 271 272 @Override 273 public boolean onOptionsItemSelected(MenuItem item) { 274 int menuId = item.getItemId(); 275 if (menuId == UNINSTALL_ALL_USERS_MENU) { 276 uninstallPkg(mAppEntry.info.packageName, true, false); 277 return true; 278 } 279 return false; 280 } 281 282 @Override 283 public void onActivityResult(int requestCode, int resultCode, Intent data) { 284 super.onActivityResult(requestCode, resultCode, data); 285 if (requestCode == REQUEST_UNINSTALL) { 286 if (mDisableAfterUninstall) { 287 mDisableAfterUninstall = false; 288 try { 289 ApplicationInfo ainfo = getActivity().getPackageManager().getApplicationInfo( 290 mAppEntry.info.packageName, PackageManager.GET_UNINSTALLED_PACKAGES 291 | PackageManager.GET_DISABLED_COMPONENTS); 292 if ((ainfo.flags & ApplicationInfo.FLAG_UPDATED_SYSTEM_APP) == 0) { 293 new DisableChanger(this, mAppEntry.info, 294 PackageManager.COMPONENT_ENABLED_STATE_DISABLED_USER) 295 .execute((Object)null); 296 } 297 } catch (NameNotFoundException e) { 298 } 299 } 300 if (!refreshUi()) { 301 setIntentAndFinish(true, true); 302 } 303 } 304 } 305 306 // Utility method to set application label and icon. 307 private void setAppLabelAndIcon(PackageInfo pkgInfo) { 308 final View appSnippet = mHeader.findViewById(R.id.app_snippet); 309 appSnippet.setPaddingRelative(0, appSnippet.getPaddingTop(), 0, 310 appSnippet.getPaddingBottom()); 311 312 ImageView icon = (ImageView) appSnippet.findViewById(R.id.app_icon); 313 mState.ensureIcon(mAppEntry); 314 icon.setImageDrawable(mAppEntry.icon); 315 // Set application name. 316 TextView label = (TextView) appSnippet.findViewById(R.id.app_name); 317 label.setText(mAppEntry.label); 318 // Version number of application 319 mAppVersion = (TextView) appSnippet.findViewById(R.id.app_size); 320 321 if (pkgInfo != null && pkgInfo.versionName != null) { 322 mAppVersion.setVisibility(View.VISIBLE); 323 mAppVersion.setText(getActivity().getString(R.string.version_text, 324 String.valueOf(pkgInfo.versionName))); 325 } else { 326 mAppVersion.setVisibility(View.INVISIBLE); 327 } 328 } 329 330 private boolean signaturesMatch(String pkg1, String pkg2) { 331 if (pkg1 != null && pkg2 != null) { 332 try { 333 final int match = mPm.checkSignatures(pkg1, pkg2); 334 if (match >= PackageManager.SIGNATURE_MATCH) { 335 return true; 336 } 337 } catch (Exception e) { 338 // e.g. named alternate package not found during lookup; 339 // this is an expected case sometimes 340 } 341 } 342 return false; 343 } 344 345 @Override 346 protected boolean refreshUi() { 347 retrieveAppEntry(); 348 if (mAppEntry == null) { 349 return false; // onCreate must have failed, make sure to exit 350 } 351 352 if (mPackageInfo == null) { 353 return false; // onCreate must have failed, make sure to exit 354 } 355 356 // Get list of "home" apps and trace through any meta-data references 357 List<ResolveInfo> homeActivities = new ArrayList<ResolveInfo>(); 358 mPm.getHomeActivities(homeActivities); 359 mHomePackages.clear(); 360 for (int i = 0; i< homeActivities.size(); i++) { 361 ResolveInfo ri = homeActivities.get(i); 362 final String activityPkg = ri.activityInfo.packageName; 363 mHomePackages.add(activityPkg); 364 365 // Also make sure to include anything proxying for the home app 366 final Bundle metadata = ri.activityInfo.metaData; 367 if (metadata != null) { 368 final String metaPkg = metadata.getString(ActivityManager.META_HOME_ALTERNATE); 369 if (signaturesMatch(metaPkg, activityPkg)) { 370 mHomePackages.add(metaPkg); 371 } 372 } 373 } 374 375 checkForceStop(); 376 setAppLabelAndIcon(mPackageInfo); 377 initUninstallButtons(); 378 379 // Update the preference summaries. 380 Activity context = getActivity(); 381 mStoragePreference.setSummary(AppStorageSettings.getSummary(mAppEntry, context)); 382 mPermissionsPreference.setSummary(AppPermissionSettings.getSummary(mAppEntry, context)); 383 mLaunchPreference.setSummary(AppLaunchSettings.getSummary(mAppEntry, mUsbManager, 384 mPm, context)); 385 mNotificationPreference.setSummary(getNotificationSummary(mAppEntry, context, 386 mBackend)); 387 388 if (!mInitialized) { 389 // First time init: are we displaying an uninstalled app? 390 mInitialized = true; 391 mShowUninstalled = (mAppEntry.info.flags&ApplicationInfo.FLAG_INSTALLED) == 0; 392 } else { 393 // All other times: if the app no longer exists then we want 394 // to go away. 395 try { 396 ApplicationInfo ainfo = context.getPackageManager().getApplicationInfo( 397 mAppEntry.info.packageName, PackageManager.GET_UNINSTALLED_PACKAGES 398 | PackageManager.GET_DISABLED_COMPONENTS); 399 if (!mShowUninstalled) { 400 // If we did not start out with the app uninstalled, then 401 // it transitioning to the uninstalled state for the current 402 // user means we should go away as well. 403 return (ainfo.flags&ApplicationInfo.FLAG_INSTALLED) != 0; 404 } 405 } catch (NameNotFoundException e) { 406 return false; 407 } 408 } 409 410 return true; 411 } 412 413 @Override 414 protected AlertDialog createDialog(int id, int errorCode) { 415 switch (id) { 416 case DLG_DISABLE: 417 return new AlertDialog.Builder(getActivity()) 418 .setTitle(getActivity().getText(R.string.app_disable_dlg_title)) 419 .setMessage(getActivity().getText(R.string.app_disable_dlg_text)) 420 .setPositiveButton(R.string.dlg_ok, new DialogInterface.OnClickListener() { 421 public void onClick(DialogInterface dialog, int which) { 422 // Disable the app 423 new DisableChanger(InstalledAppDetails.this, mAppEntry.info, 424 PackageManager.COMPONENT_ENABLED_STATE_DISABLED_USER) 425 .execute((Object)null); 426 } 427 }) 428 .setNegativeButton(R.string.dlg_cancel, null) 429 .create(); 430 case DLG_SPECIAL_DISABLE: 431 return new AlertDialog.Builder(getActivity()) 432 .setTitle(getActivity().getText(R.string.app_special_disable_dlg_title)) 433 .setMessage(getActivity().getText(R.string.app_special_disable_dlg_text)) 434 .setPositiveButton(R.string.dlg_ok, new DialogInterface.OnClickListener() { 435 public void onClick(DialogInterface dialog, int which) { 436 // Clear user data here 437 uninstallPkg(mAppEntry.info.packageName, 438 false, true); 439 } 440 }) 441 .setNegativeButton(R.string.dlg_cancel, null) 442 .create(); 443 case DLG_FORCE_STOP: 444 return new AlertDialog.Builder(getActivity()) 445 .setTitle(getActivity().getText(R.string.force_stop_dlg_title)) 446 .setMessage(getActivity().getText(R.string.force_stop_dlg_text)) 447 .setPositiveButton(R.string.dlg_ok, new DialogInterface.OnClickListener() { 448 public void onClick(DialogInterface dialog, int which) { 449 // Force stop 450 forceStopPackage(mAppEntry.info.packageName); 451 } 452 }) 453 .setNegativeButton(R.string.dlg_cancel, null) 454 .create(); 455 case DLG_FACTORY_RESET: 456 return new AlertDialog.Builder(getActivity()) 457 .setTitle(getActivity().getText(R.string.app_factory_reset_dlg_title)) 458 .setMessage(getActivity().getText(R.string.app_factory_reset_dlg_text)) 459 .setPositiveButton(R.string.dlg_ok, new DialogInterface.OnClickListener() { 460 public void onClick(DialogInterface dialog, int which) { 461 // Clear user data here 462 uninstallPkg(mAppEntry.info.packageName, 463 false, false); 464 } 465 }) 466 .setNegativeButton(R.string.dlg_cancel, null) 467 .create(); 468 } 469 return null; 470 } 471 472 private void uninstallPkg(String packageName, boolean allUsers, boolean andDisable) { 473 // Create new intent to launch Uninstaller activity 474 Uri packageURI = Uri.parse("package:"+packageName); 475 Intent uninstallIntent = new Intent(Intent.ACTION_UNINSTALL_PACKAGE, packageURI); 476 uninstallIntent.putExtra(Intent.EXTRA_UNINSTALL_ALL_USERS, allUsers); 477 startActivityForResult(uninstallIntent, REQUEST_UNINSTALL); 478 mDisableAfterUninstall = andDisable; 479 } 480 481 private void forceStopPackage(String pkgName) { 482 ActivityManager am = (ActivityManager)getActivity().getSystemService( 483 Context.ACTIVITY_SERVICE); 484 am.forceStopPackage(pkgName); 485 int userId = UserHandle.getUserId(mAppEntry.info.uid); 486 mState.invalidatePackage(pkgName, userId); 487 ApplicationsState.AppEntry newEnt = mState.getEntry(pkgName, userId); 488 if (newEnt != null) { 489 mAppEntry = newEnt; 490 } 491 checkForceStop(); 492 } 493 494 private void updateForceStopButton(boolean enabled) { 495 if (mAppControlRestricted) { 496 mForceStopButton.setEnabled(false); 497 } else { 498 mForceStopButton.setEnabled(enabled); 499 mForceStopButton.setOnClickListener(InstalledAppDetails.this); 500 } 501 } 502 503 private void checkForceStop() { 504 if (mDpm.packageHasActiveAdmins(mPackageInfo.packageName)) { 505 // User can't force stop device admin. 506 updateForceStopButton(false); 507 } else if ((mAppEntry.info.flags&ApplicationInfo.FLAG_STOPPED) == 0) { 508 // If the app isn't explicitly stopped, then always show the 509 // force stop button. 510 updateForceStopButton(true); 511 } else { 512 Intent intent = new Intent(Intent.ACTION_QUERY_PACKAGE_RESTART, 513 Uri.fromParts("package", mAppEntry.info.packageName, null)); 514 intent.putExtra(Intent.EXTRA_PACKAGES, new String[] { mAppEntry.info.packageName }); 515 intent.putExtra(Intent.EXTRA_UID, mAppEntry.info.uid); 516 intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(mAppEntry.info.uid)); 517 getActivity().sendOrderedBroadcastAsUser(intent, UserHandle.CURRENT, null, 518 mCheckKillProcessesReceiver, null, Activity.RESULT_CANCELED, null, null); 519 } 520 } 521 522 private void startAppInfoFragment(Class<? extends AppInfoBase> fragment, CharSequence title) { 523 // start new fragment to display extended information 524 Bundle args = new Bundle(); 525 args.putString(InstalledAppDetails.ARG_PACKAGE_NAME, mAppEntry.info.packageName); 526 527 SettingsActivity sa = (SettingsActivity) getActivity(); 528 sa.startPreferencePanel(fragment.getName(), args, -1, title, this, SUB_INFO_FRAGMENT); 529 } 530 531 private void startNotifications() { 532 // start new fragment to display extended information 533 getActivity().startActivity(new Intent(Settings.ACTION_APP_NOTIFICATION_SETTINGS) 534 .addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP) 535 .putExtra(Settings.EXTRA_APP_PACKAGE, mAppEntry.info.packageName) 536 .putExtra(Settings.EXTRA_APP_UID, mAppEntry.info.uid)); 537 } 538 539 /* 540 * Method implementing functionality of buttons clicked 541 * @see android.view.View.OnClickListener#onClick(android.view.View) 542 */ 543 public void onClick(View v) { 544 String packageName = mAppEntry.info.packageName; 545 if(v == mUninstallButton) { 546 if (mUpdatedSysApp) { 547 showDialogInner(DLG_FACTORY_RESET, 0); 548 } else { 549 if ((mAppEntry.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) { 550 if (mAppEntry.info.enabled) { 551 showDialogInner(DLG_DISABLE, 0); 552 } else { 553 new DisableChanger(this, mAppEntry.info, 554 PackageManager.COMPONENT_ENABLED_STATE_DEFAULT) 555 .execute((Object)null); 556 } 557 } else if ((mAppEntry.info.flags & ApplicationInfo.FLAG_INSTALLED) == 0) { 558 uninstallPkg(packageName, true, false); 559 } else { 560 uninstallPkg(packageName, false, false); 561 } 562 } 563 } else if(v == mSpecialDisableButton) { 564 showDialogInner(DLG_SPECIAL_DISABLE, 0); 565 } else if (v == mForceStopButton) { 566 showDialogInner(DLG_FORCE_STOP, 0); 567 //forceStopPackage(mAppInfo.packageName); 568 } 569 } 570 571 @Override 572 public boolean onPreferenceClick(Preference preference) { 573 if (preference == mStoragePreference) { 574 startAppInfoFragment(AppStorageSettings.class, mStoragePreference.getTitle()); 575 } else if (preference == mNotificationPreference) { 576 startNotifications(); 577 } else if (preference == mPermissionsPreference) { 578 startAppInfoFragment(AppPermissionSettings.class, mPermissionsPreference.getTitle()); 579 } else if (preference == mLaunchPreference) { 580 startAppInfoFragment(AppLaunchSettings.class, mLaunchPreference.getTitle()); 581 } else if (preference == mDataPreference) { 582 // Not yet. 583 } else { 584 return false; 585 } 586 return true; 587 } 588 589 public static CharSequence getNotificationSummary(AppEntry appEntry, Context context) { 590 return getNotificationSummary(appEntry, context, new Backend()); 591 } 592 593 public static CharSequence getNotificationSummary(AppEntry appEntry, Context context, 594 Backend backend) { 595 AppRow appRow = NotificationAppList.loadAppRow(context.getPackageManager(), appEntry.info, 596 backend); 597 if (appRow.banned) { 598 return context.getString(R.string.notifications_disabled); 599 } else if (appRow.priority) { 600 if (appRow.sensitive) { 601 return context.getString(R.string.notifications_priority_sensitive); 602 } 603 return context.getString(R.string.notifications_priority); 604 } else if (appRow.sensitive) { 605 return context.getString(R.string.notifications_sensitive); 606 } 607 return context.getString(R.string.notifications_enabled); 608 } 609 610 static class DisableChanger extends AsyncTask<Object, Object, Object> { 611 final PackageManager mPm; 612 final WeakReference<InstalledAppDetails> mActivity; 613 final ApplicationInfo mInfo; 614 final int mState; 615 616 DisableChanger(InstalledAppDetails activity, ApplicationInfo info, int state) { 617 mPm = activity.mPm; 618 mActivity = new WeakReference<InstalledAppDetails>(activity); 619 mInfo = info; 620 mState = state; 621 } 622 623 @Override 624 protected Object doInBackground(Object... params) { 625 mPm.setApplicationEnabledSetting(mInfo.packageName, mState, 0); 626 return null; 627 } 628 } 629 630 private final BroadcastReceiver mCheckKillProcessesReceiver = new BroadcastReceiver() { 631 @Override 632 public void onReceive(Context context, Intent intent) { 633 updateForceStopButton(getResultCode() != Activity.RESULT_CANCELED); 634 } 635 }; 636} 637 638 639