diff options
-rwxr-xr-x | res/layout/manage_applications_item.xml | 25 | ||||
-rw-r--r-- | res/values/strings.xml | 8 | ||||
-rw-r--r-- | src/com/android/settings/applications/InstalledAppDetails.java | 115 | ||||
-rw-r--r-- | src/com/android/settings/applications/ManageApplications.java | 13 |
4 files changed, 128 insertions, 33 deletions
diff --git a/res/layout/manage_applications_item.xml b/res/layout/manage_applications_item.xml index 48274ce..5d8d91b 100755 --- a/res/layout/manage_applications_item.xml +++ b/res/layout/manage_applications_item.xml @@ -47,12 +47,27 @@ android:singleLine="true" android:ellipsize="marquee" android:layout_marginBottom="2dip" /> - <TextView android:id="@+id/app_size" - android:layout_marginTop="-4dip" - android:layout_gravity="center_vertical" - android:layout_width="wrap_content" + <LinearLayout + android:orientation="horizontal" + android:layout_width="match_parent" android:layout_height="wrap_content" - android:textAppearance="?android:attr/textAppearanceSmall" /> + android:baselineAlignedChildIndex="0" > + <TextView android:id="@+id/app_size" + android:layout_marginTop="-4dip" + android:layout_gravity="center_vertical|left" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_weight="1" + android:textAppearance="?android:attr/textAppearanceSmall" /> + <TextView android:id="@+id/app_disabled" + android:layout_marginTop="-4dip" + android:layout_gravity="center_vertical|right" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_weight="0" + android:textAppearance="?android:attr/textAppearanceSmall" + android:text="@string/disabled" /> + </LinearLayout> </LinearLayout> </LinearLayout> diff --git a/res/values/strings.xml b/res/values/strings.xml index f2300b0..705fdb3 100644 --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -1647,6 +1647,10 @@ <string name="data_size_label">Data</string> <!-- Manage applications, individual application info screen, button label under Storage heading. Button to remove the application from the system. --> <string name="uninstall_text">Uninstall</string> + <!-- Manage applications, individual application info screen, button label under Storage heading. Button to disable an existing application. --> + <string name="disable_text">Disable</string> + <!-- Manage applications, individual application info screen, button label under Storage heading. Button to re-enable an existing application. --> + <string name="enable_text">Enable</string> <!-- Manage applications, individual application info screen, button label under Storage heading. Button to clear all data associated with tis app (for exampel, remove all cached emails for an Email app) --> <string name="clear_user_data_text">Clear data</string> <!-- Manage applications, restore updated system application to factory version --> @@ -1681,6 +1685,8 @@ <!-- Text for filter option in ManageApps screen to display list of packages installed on sdcard. --> <string name="filter_apps_onsdcard">On SD card</string> + <!-- Manage applications, text telling using an application is disabled. --> + <string name="disabled">Disabled</string> <string name="loading">Loading\u2026</string> <!-- Manage app screen, shown when the activity is busy recomputing the size of each app --> <string name="recompute_size">Recomputing size\u2026</string> @@ -1734,7 +1740,7 @@ found in the list of installed applications.</string> <string name="force_stop_dlg_title">Force stop</string> <!-- Manage applications, text for dialog when killing persistent apps--> - <string name="force_stop_dlg_text">This application will be restarted right way. Are you sure you want to force stop?</string> + <string name="force_stop_dlg_text">Force stopping an application can cause it to misbehave. Are you sure?</string> <!-- Manage applications, text for dialog when moving an app --> <string name="move_app_failed_dlg_title">Move application</string> <!-- Manage applications, text for dialog moving an app --> diff --git a/src/com/android/settings/applications/InstalledAppDetails.java b/src/com/android/settings/applications/InstalledAppDetails.java index 92fe9d2..07a76ab 100644 --- a/src/com/android/settings/applications/InstalledAppDetails.java +++ b/src/com/android/settings/applications/InstalledAppDetails.java @@ -1,5 +1,3 @@ - - /** * Copyright (C) 2007 The Android Open Source Project * @@ -42,8 +40,10 @@ import android.content.pm.PackageInfo; import android.content.pm.PackageManager; import android.content.pm.PackageParser; import android.content.pm.PackageStats; +import android.content.pm.ResolveInfo; import android.content.pm.PackageManager.NameNotFoundException; import android.net.Uri; +import android.os.AsyncTask; import android.os.Bundle; import android.os.Handler; import android.os.IBinder; @@ -53,6 +53,8 @@ import android.os.ServiceManager; import android.os.storage.IMountService; import android.text.format.Formatter; import android.util.Log; + +import java.lang.ref.WeakReference; import java.util.ArrayList; import java.util.List; import android.content.ComponentName; @@ -74,7 +76,6 @@ import android.widget.TextView; */ public class InstalledAppDetails extends Activity implements View.OnClickListener { private static final String TAG="InstalledAppDetails"; - private static final int _UNKNOWN_APP=R.string.unknown; private ApplicationInfo mAppInfo; private Button mUninstallButton; private boolean mMoveInProgress = false; @@ -281,11 +282,39 @@ public class InstalledAppDetails extends Activity implements View.OnClickListene if (mUpdatedSysApp) { mUninstallButton.setText(R.string.app_factory_reset); } else { - if ((mAppInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0){ - // Disable button for system applications. + if ((mAppInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0) { enabled = false; + try { + // Try to prevent the user from bricking their phone + // by not allowing disabling of apps signed with the + // system cert and any launcher app in the system. + PackageInfo pi = mPm.getPackageInfo(mAppInfo.packageName, + PackageManager.GET_DISABLED_COMPONENTS | + PackageManager.GET_UNINSTALLED_PACKAGES | + PackageManager.GET_SIGNATURES); + PackageInfo sys = mPm.getPackageInfo("android", + PackageManager.GET_SIGNATURES); + Intent intent = new Intent(Intent.ACTION_MAIN); + intent.addCategory(Intent.CATEGORY_HOME); + intent.setPackage(mAppInfo.packageName); + List<ResolveInfo> homes = mPm.queryIntentActivities(intent, 0); + if ((homes != null && homes.size() > 0) + || sys.signatures[0].equals(pi.signatures[0])) { + // Disable button for core system applications. + mUninstallButton.setText(R.string.disable_text); + } else if (mAppInfo.enabled) { + mUninstallButton.setText(R.string.disable_text); + enabled = true; + } else { + mUninstallButton.setText(R.string.enable_text); + enabled = true; + } + } catch (PackageManager.NameNotFoundException e) { + Log.w(TAG, "Unable to get package info", e); + } + } else { + mUninstallButton.setText(R.string.uninstall_text); } - mUninstallButton.setText(R.string.uninstall_text); } mUninstallButton.setEnabled(enabled); if (enabled) { @@ -521,6 +550,7 @@ public class InstalledAppDetails extends Activity implements View.OnClickListene } else { mClearDataButton.setEnabled(true); } + checkForceStop(); } private void refreshButtons() { @@ -642,13 +672,13 @@ public class InstalledAppDetails extends Activity implements View.OnClickListene } }) .create(); - case DLG_FORCE_STOP: - return new AlertDialog.Builder(this) - .setTitle(getString(R.string.force_stop_dlg_title)) - .setIcon(android.R.drawable.ic_dialog_alert) - .setMessage(getString(R.string.force_stop_dlg_text)) - .setPositiveButton(R.string.dlg_ok, - new DialogInterface.OnClickListener() { + case DLG_FORCE_STOP: + return new AlertDialog.Builder(this) + .setTitle(getString(R.string.force_stop_dlg_title)) + .setIcon(android.R.drawable.ic_dialog_alert) + .setMessage(getString(R.string.force_stop_dlg_text)) + .setPositiveButton(R.string.dlg_ok, + new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int which) { // Force stop forceStopPackage(mAppInfo.packageName); @@ -656,15 +686,15 @@ public class InstalledAppDetails extends Activity implements View.OnClickListene }) .setNegativeButton(R.string.dlg_cancel, null) .create(); - case DLG_MOVE_FAILED: - CharSequence msg = getString(R.string.move_app_failed_dlg_text, - getMoveErrMsg(mMoveErrorCode)); - return new AlertDialog.Builder(this) - .setTitle(getString(R.string.move_app_failed_dlg_title)) - .setIcon(android.R.drawable.ic_dialog_alert) - .setMessage(msg) - .setNeutralButton(R.string.dlg_ok, null) - .create(); + case DLG_MOVE_FAILED: + CharSequence msg = getString(R.string.move_app_failed_dlg_text, + getMoveErrMsg(mMoveErrorCode)); + return new AlertDialog.Builder(this) + .setTitle(getString(R.string.move_app_failed_dlg_title)) + .setIcon(android.R.drawable.ic_dialog_alert) + .setMessage(msg) + .setNeutralButton(R.string.dlg_ok, null) + .create(); } return null; } @@ -701,6 +731,36 @@ public class InstalledAppDetails extends Activity implements View.OnClickListene Activity.RESULT_CANCELED, null, null); } + static class DisableChanger extends AsyncTask<Object, Object, Object> { + final PackageManager mPm; + final WeakReference<InstalledAppDetails> mActivity; + final ApplicationInfo mInfo; + final int mState; + + DisableChanger(InstalledAppDetails activity, ApplicationInfo info, int state) { + mPm = activity.mPm; + mActivity = new WeakReference<InstalledAppDetails>(activity); + mInfo = info; + mState = state; + } + + @Override + protected Object doInBackground(Object... params) { + mPm.setApplicationEnabledSetting(mInfo.packageName, mState, 0); + return null; + } + + @Override + protected void onPostExecute(Object result) { + InstalledAppDetails activity = mActivity.get(); + if (activity != null) { + activity.initAppInfo(mInfo.packageName); + activity.checkForceStop(); + activity.refreshButtons(); + } + } + } + /* * Method implementing functionality of buttons clicked * @see android.view.View.OnClickListener#onClick(android.view.View) @@ -711,7 +771,13 @@ public class InstalledAppDetails extends Activity implements View.OnClickListene if (mUpdatedSysApp) { showDialogInner(DLG_FACTORY_RESET); } else { - uninstallPkg(packageName); + if ((mAppInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0) { + new DisableChanger(this, mAppInfo, mAppInfo.enabled ? + PackageManager.COMPONENT_ENABLED_STATE_DISABLED + : PackageManager.COMPONENT_ENABLED_STATE_DEFAULT).execute((Object)null); + } else { + uninstallPkg(packageName); + } } } else if(v == mActivitiesButton) { mPm.clearPackagePreferredActivities(packageName); @@ -731,7 +797,8 @@ public class InstalledAppDetails extends Activity implements View.OnClickListene } mPm.deleteApplicationCacheFiles(packageName, mClearCacheObserver); } else if (v == mForceStopButton) { - forceStopPackage(mAppInfo.packageName); + showDialogInner(DLG_FORCE_STOP); + //forceStopPackage(mAppInfo.packageName); } else if (v == mMoveAppButton) { if (mPackageMoveObserver == null) { mPackageMoveObserver = new PackageMoveObserver(); diff --git a/src/com/android/settings/applications/ManageApplications.java b/src/com/android/settings/applications/ManageApplications.java index 52ea376..03ae68a 100644 --- a/src/com/android/settings/applications/ManageApplications.java +++ b/src/com/android/settings/applications/ManageApplications.java @@ -616,7 +616,8 @@ public class ManageApplications extends TabActivity implements List<ApplicationInfo> getInstalledApps(int filterOption) { List<ApplicationInfo> installedAppList = mPm.getInstalledApplications( - PackageManager.GET_UNINSTALLED_PACKAGES); + PackageManager.GET_UNINSTALLED_PACKAGES | + PackageManager.GET_DISABLED_COMPONENTS); if (installedAppList == null) { return new ArrayList<ApplicationInfo> (); } @@ -903,6 +904,7 @@ public class ManageApplications extends TabActivity implements TextView appName; ImageView appIcon; TextView appSize; + TextView disabled; } /* @@ -1076,6 +1078,7 @@ public class ManageApplications extends TabActivity implements holder.appName = (TextView) convertView.findViewById(R.id.app_name); holder.appIcon = (ImageView) convertView.findViewById(R.id.app_icon); holder.appSize = (TextView) convertView.findViewById(R.id.app_size); + holder.disabled = (TextView) convertView.findViewById(R.id.app_disabled); convertView.setTag(holder); } else { // Get the ViewHolder back to get fast access to the TextView @@ -1087,15 +1090,19 @@ public class ManageApplications extends TabActivity implements ApplicationInfo appInfo = mAppLocalList.get(position); AppInfo mInfo = mCache.getEntry(appInfo.packageName); if(mInfo != null) { - if(mInfo.appName != null) { + if (mInfo.appName != null) { holder.appName.setText(mInfo.appName); + holder.appName.setTextColor(getResources().getColorStateList( + appInfo.enabled ? android.R.color.primary_text_dark + : android.R.color.secondary_text_dark)); } - if(mInfo.appIcon != null) { + if (mInfo.appIcon != null) { holder.appIcon.setImageDrawable(mInfo.appIcon); } if (mInfo.appSize != null) { holder.appSize.setText(mInfo.appSize); } + holder.disabled.setVisibility(appInfo.enabled ? View.GONE : View.VISIBLE); } else { Log.w(TAG, "No info for package:"+appInfo.packageName+" in property map"); } |