am 3db54cb9
: Add app details menu item to uninstall an app for all users.
* commit '3db54cb97630fe83342c2ca189d13ff5a1a598d3': Add app details menu item to uninstall an app for all users.
This commit is contained in:
@@ -2438,6 +2438,8 @@
|
|||||||
<string name="external_data_size_label" product="default">SD card</string>
|
<string name="external_data_size_label" product="default">SD card</string>
|
||||||
<!-- Manage applications, individual application info screen, button label under Storage heading. Button to remove the application from the system. -->
|
<!-- 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>
|
<string name="uninstall_text">Uninstall</string>
|
||||||
|
<!-- Manage applications, individual application info screen, menu item to uninstall an application for all users. -->
|
||||||
|
<string name="uninstall_all_users_text">Uninstall for all users</string>
|
||||||
<!-- [CHAR LIMIT=NONE] Manage applications, individual application info screen, button label under Storage heading. Button to install an application for the user. -->
|
<!-- [CHAR LIMIT=NONE] Manage applications, individual application info screen, button label under Storage heading. Button to install an application for the user. -->
|
||||||
<string name="install_text">Install</string>
|
<string name="install_text">Install</string>
|
||||||
<!-- [CHAR LIMIT=25] Manage applications, individual application info screen, button label under Storage heading. Button to disable an existing application. -->
|
<!-- [CHAR LIMIT=25] Manage applications, individual application info screen, button label under Storage heading. Button to disable an existing application. -->
|
||||||
@@ -2509,6 +2511,8 @@
|
|||||||
<string name="filter_apps_onsdcard" product="default">On SD card</string>
|
<string name="filter_apps_onsdcard" product="default">On SD card</string>
|
||||||
<!-- [CHAR LIMIT=25] Manage applications, text telling using an application is disabled. -->
|
<!-- [CHAR LIMIT=25] Manage applications, text telling using an application is disabled. -->
|
||||||
<string name="disabled">Disabled</string>
|
<string name="disabled">Disabled</string>
|
||||||
|
<!-- [CHAR LIMIT=25] Manage applications, text telling using an application is not installed. -->
|
||||||
|
<string name="not_installed">Not installed</string>
|
||||||
<!-- [CHAR LIMIT=25] Text shown when there are no applications to display. -->
|
<!-- [CHAR LIMIT=25] Text shown when there are no applications to display. -->
|
||||||
<string name="no_applications">No apps.</string>
|
<string name="no_applications">No apps.</string>
|
||||||
<!-- [CHAR LIMIT=15] Manage applications, label for chart showing internal storage use. -->
|
<!-- [CHAR LIMIT=15] Manage applications, label for chart showing internal storage use. -->
|
||||||
|
@@ -163,8 +163,12 @@ public class ApplicationsState {
|
|||||||
private final Collator sCollator = Collator.getInstance();
|
private final Collator sCollator = Collator.getInstance();
|
||||||
@Override
|
@Override
|
||||||
public int compare(AppEntry object1, AppEntry object2) {
|
public int compare(AppEntry object1, AppEntry object2) {
|
||||||
if (object1.info.enabled != object2.info.enabled) {
|
final boolean normal1 = object1.info.enabled
|
||||||
return object1.info.enabled ? -1 : 1;
|
&& (object1.info.flags&ApplicationInfo.FLAG_INSTALLED) != 0;
|
||||||
|
final boolean normal2 = object2.info.enabled
|
||||||
|
&& (object2.info.flags&ApplicationInfo.FLAG_INSTALLED) != 0;
|
||||||
|
if (normal1 != normal2) {
|
||||||
|
return normal1 ? -1 : 1;
|
||||||
}
|
}
|
||||||
return sCollator.compare(object1.label, object2.label);
|
return sCollator.compare(object1.label, object2.label);
|
||||||
}
|
}
|
||||||
|
@@ -55,6 +55,8 @@ import android.os.IBinder;
|
|||||||
import android.os.Message;
|
import android.os.Message;
|
||||||
import android.os.RemoteException;
|
import android.os.RemoteException;
|
||||||
import android.os.ServiceManager;
|
import android.os.ServiceManager;
|
||||||
|
import android.os.UserHandle;
|
||||||
|
import android.os.UserManager;
|
||||||
import android.preference.PreferenceActivity;
|
import android.preference.PreferenceActivity;
|
||||||
import android.text.SpannableString;
|
import android.text.SpannableString;
|
||||||
import android.text.TextUtils;
|
import android.text.TextUtils;
|
||||||
@@ -66,6 +68,9 @@ import java.lang.ref.WeakReference;
|
|||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import android.view.LayoutInflater;
|
import android.view.LayoutInflater;
|
||||||
|
import android.view.Menu;
|
||||||
|
import android.view.MenuInflater;
|
||||||
|
import android.view.MenuItem;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.view.ViewGroup;
|
import android.view.ViewGroup;
|
||||||
import android.widget.AdapterView;
|
import android.widget.AdapterView;
|
||||||
@@ -92,12 +97,12 @@ public class InstalledAppDetails extends Fragment
|
|||||||
implements View.OnClickListener, CompoundButton.OnCheckedChangeListener,
|
implements View.OnClickListener, CompoundButton.OnCheckedChangeListener,
|
||||||
ApplicationsState.Callbacks {
|
ApplicationsState.Callbacks {
|
||||||
private static final String TAG="InstalledAppDetails";
|
private static final String TAG="InstalledAppDetails";
|
||||||
static final boolean SUPPORT_DISABLE_APPS = true;
|
|
||||||
private static final boolean localLOGV = false;
|
private static final boolean localLOGV = false;
|
||||||
|
|
||||||
public static final String ARG_PACKAGE_NAME = "package";
|
public static final String ARG_PACKAGE_NAME = "package";
|
||||||
|
|
||||||
private PackageManager mPm;
|
private PackageManager mPm;
|
||||||
|
private UserManager mUserManager;
|
||||||
private IUsbManager mUsbManager;
|
private IUsbManager mUsbManager;
|
||||||
private AppWidgetManager mAppWidgetManager;
|
private AppWidgetManager mAppWidgetManager;
|
||||||
private DevicePolicyManager mDpm;
|
private DevicePolicyManager mDpm;
|
||||||
@@ -167,7 +172,14 @@ public class InstalledAppDetails extends Fragment
|
|||||||
private static final int DLG_MOVE_FAILED = DLG_BASE + 6;
|
private static final int DLG_MOVE_FAILED = DLG_BASE + 6;
|
||||||
private static final int DLG_DISABLE = DLG_BASE + 7;
|
private static final int DLG_DISABLE = DLG_BASE + 7;
|
||||||
private static final int DLG_DISABLE_NOTIFICATIONS = DLG_BASE + 8;
|
private static final int DLG_DISABLE_NOTIFICATIONS = DLG_BASE + 8;
|
||||||
|
|
||||||
|
// Menu identifiers
|
||||||
|
public static final int UNINSTALL_ALL_USERS_MENU = 1;
|
||||||
|
|
||||||
|
// Result code identifiers
|
||||||
|
public static final int REQUEST_UNINSTALL = 1;
|
||||||
|
public static final int REQUEST_MANAGE_SPACE = 2;
|
||||||
|
|
||||||
private Handler mHandler = new Handler() {
|
private Handler mHandler = new Handler() {
|
||||||
public void handleMessage(Message msg) {
|
public void handleMessage(Message msg) {
|
||||||
// If the fragment is gone, don't process any more messages.
|
// If the fragment is gone, don't process any more messages.
|
||||||
@@ -303,30 +315,28 @@ public class InstalledAppDetails extends Fragment
|
|||||||
} else {
|
} else {
|
||||||
if ((mAppEntry.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
|
if ((mAppEntry.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
|
||||||
enabled = false;
|
enabled = false;
|
||||||
if (SUPPORT_DISABLE_APPS) {
|
try {
|
||||||
try {
|
// Try to prevent the user from bricking their phone
|
||||||
// Try to prevent the user from bricking their phone
|
// by not allowing disabling of apps signed with the
|
||||||
// by not allowing disabling of apps signed with the
|
// system cert and any launcher app in the system.
|
||||||
// system cert and any launcher app in the system.
|
PackageInfo sys = mPm.getPackageInfo("android",
|
||||||
PackageInfo sys = mPm.getPackageInfo("android",
|
PackageManager.GET_SIGNATURES);
|
||||||
PackageManager.GET_SIGNATURES);
|
Intent intent = new Intent(Intent.ACTION_MAIN);
|
||||||
Intent intent = new Intent(Intent.ACTION_MAIN);
|
intent.addCategory(Intent.CATEGORY_HOME);
|
||||||
intent.addCategory(Intent.CATEGORY_HOME);
|
intent.setPackage(mAppEntry.info.packageName);
|
||||||
intent.setPackage(mAppEntry.info.packageName);
|
List<ResolveInfo> homes = mPm.queryIntentActivities(intent, 0);
|
||||||
List<ResolveInfo> homes = mPm.queryIntentActivities(intent, 0);
|
if ((homes != null && homes.size() > 0) || isThisASystemPackage()) {
|
||||||
if ((homes != null && homes.size() > 0) || isThisASystemPackage()) {
|
// Disable button for core system applications.
|
||||||
// Disable button for core system applications.
|
mUninstallButton.setText(R.string.disable_text);
|
||||||
mUninstallButton.setText(R.string.disable_text);
|
} else if (mAppEntry.info.enabled) {
|
||||||
} else if (mAppEntry.info.enabled) {
|
mUninstallButton.setText(R.string.disable_text);
|
||||||
mUninstallButton.setText(R.string.disable_text);
|
enabled = true;
|
||||||
enabled = true;
|
} else {
|
||||||
} else {
|
mUninstallButton.setText(R.string.enable_text);
|
||||||
mUninstallButton.setText(R.string.enable_text);
|
enabled = true;
|
||||||
enabled = true;
|
|
||||||
}
|
|
||||||
} catch (PackageManager.NameNotFoundException e) {
|
|
||||||
Log.w(TAG, "Unable to get package info", e);
|
|
||||||
}
|
}
|
||||||
|
} catch (PackageManager.NameNotFoundException e) {
|
||||||
|
Log.w(TAG, "Unable to get package info", e);
|
||||||
}
|
}
|
||||||
} else if ((mPackageInfo.applicationInfo.flags
|
} else if ((mPackageInfo.applicationInfo.flags
|
||||||
& ApplicationInfo.FLAG_INSTALLED) == 0) {
|
& ApplicationInfo.FLAG_INSTALLED) == 0) {
|
||||||
@@ -370,9 +380,12 @@ public class InstalledAppDetails extends Fragment
|
|||||||
public void onCreate(Bundle icicle) {
|
public void onCreate(Bundle icicle) {
|
||||||
super.onCreate(icicle);
|
super.onCreate(icicle);
|
||||||
|
|
||||||
|
setHasOptionsMenu(true);
|
||||||
|
|
||||||
mState = ApplicationsState.getInstance(getActivity().getApplication());
|
mState = ApplicationsState.getInstance(getActivity().getApplication());
|
||||||
mSession = mState.newSession(this);
|
mSession = mState.newSession(this);
|
||||||
mPm = getActivity().getPackageManager();
|
mPm = getActivity().getPackageManager();
|
||||||
|
mUserManager = (UserManager)getActivity().getSystemService(Context.USER_SERVICE);
|
||||||
IBinder b = ServiceManager.getService(Context.USB_SERVICE);
|
IBinder b = ServiceManager.getService(Context.USB_SERVICE);
|
||||||
mUsbManager = IUsbManager.Stub.asInterface(b);
|
mUsbManager = IUsbManager.Stub.asInterface(b);
|
||||||
mAppWidgetManager = AppWidgetManager.getInstance(getActivity());
|
mAppWidgetManager = AppWidgetManager.getInstance(getActivity());
|
||||||
@@ -428,6 +441,49 @@ public class InstalledAppDetails extends Fragment
|
|||||||
return view;
|
return view;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
|
||||||
|
menu.add(0, UNINSTALL_ALL_USERS_MENU, 1, R.string.uninstall_all_users_text)
|
||||||
|
.setShowAsAction(MenuItem.SHOW_AS_ACTION_NEVER);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onPrepareOptionsMenu(Menu menu) {
|
||||||
|
boolean showIt = true;
|
||||||
|
if (mUpdatedSysApp) {
|
||||||
|
showIt = false;
|
||||||
|
} else if ((mAppEntry.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
|
||||||
|
showIt = false;
|
||||||
|
} else if (mDpm.packageHasActiveAdmins(mPackageInfo.packageName)) {
|
||||||
|
showIt = false;
|
||||||
|
} else if (UserHandle.myUserId() != 0) {
|
||||||
|
showIt = false;
|
||||||
|
} else if (mUserManager.getUsers().size() < 1) {
|
||||||
|
showIt = false;
|
||||||
|
}
|
||||||
|
menu.findItem(UNINSTALL_ALL_USERS_MENU).setVisible(showIt);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean onOptionsItemSelected(MenuItem item) {
|
||||||
|
int menuId = item.getItemId();
|
||||||
|
if (menuId == UNINSTALL_ALL_USERS_MENU) {
|
||||||
|
uninstallPkg(mAppEntry.info.packageName, true);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onActivityResult(int requestCode, int resultCode, Intent data) {
|
||||||
|
super.onActivityResult(requestCode, resultCode, data);
|
||||||
|
if (requestCode == REQUEST_UNINSTALL) {
|
||||||
|
if (!refreshUi()) {
|
||||||
|
setIntentAndFinish(true, true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Utility method to set applicaiton label and icon.
|
// Utility method to set applicaiton label and icon.
|
||||||
private void setAppLabelAndIcon(PackageInfo pkgInfo) {
|
private void setAppLabelAndIcon(PackageInfo pkgInfo) {
|
||||||
View appSnippet = mRootView.findViewById(R.id.app_snippet);
|
View appSnippet = mRootView.findViewById(R.id.app_snippet);
|
||||||
@@ -925,7 +981,7 @@ public class InstalledAppDetails extends Fragment
|
|||||||
new DialogInterface.OnClickListener() {
|
new DialogInterface.OnClickListener() {
|
||||||
public void onClick(DialogInterface dialog, int which) {
|
public void onClick(DialogInterface dialog, int which) {
|
||||||
// Clear user data here
|
// Clear user data here
|
||||||
getOwner().uninstallPkg(getOwner().mAppEntry.info.packageName);
|
getOwner().uninstallPkg(getOwner().mAppEntry.info.packageName, false);
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.setNegativeButton(R.string.dlg_cancel, null)
|
.setNegativeButton(R.string.dlg_cancel, null)
|
||||||
@@ -1021,12 +1077,12 @@ public class InstalledAppDetails extends Fragment
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void uninstallPkg(String packageName) {
|
private void uninstallPkg(String packageName, boolean allUsers) {
|
||||||
// Create new intent to launch Uninstaller activity
|
// Create new intent to launch Uninstaller activity
|
||||||
Uri packageURI = Uri.parse("package:"+packageName);
|
Uri packageURI = Uri.parse("package:"+packageName);
|
||||||
Intent uninstallIntent = new Intent(Intent.ACTION_DELETE, packageURI);
|
Intent uninstallIntent = new Intent(Intent.ACTION_UNINSTALL_PACKAGE, packageURI);
|
||||||
startActivity(uninstallIntent);
|
uninstallIntent.putExtra(Intent.EXTRA_UNINSTALL_ALL_USERS, allUsers);
|
||||||
setIntentAndFinish(true, true);
|
startActivityForResult(uninstallIntent, REQUEST_UNINSTALL);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void forceStopPackage(String pkgName) {
|
private void forceStopPackage(String pkgName) {
|
||||||
@@ -1139,7 +1195,7 @@ public class InstalledAppDetails extends Fragment
|
|||||||
} catch (NameNotFoundException e) {
|
} catch (NameNotFoundException e) {
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
uninstallPkg(packageName);
|
uninstallPkg(packageName, false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if(v == mActivitiesButton) {
|
} else if(v == mActivitiesButton) {
|
||||||
@@ -1160,7 +1216,7 @@ public class InstalledAppDetails extends Fragment
|
|||||||
Intent intent = new Intent(Intent.ACTION_DEFAULT);
|
Intent intent = new Intent(Intent.ACTION_DEFAULT);
|
||||||
intent.setClassName(mAppEntry.info.packageName,
|
intent.setClassName(mAppEntry.info.packageName,
|
||||||
mAppEntry.info.manageSpaceActivityName);
|
mAppEntry.info.manageSpaceActivityName);
|
||||||
startActivityForResult(intent, -1);
|
startActivityForResult(intent, REQUEST_MANAGE_SPACE);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
showDialogInner(DLG_CLEAR_DATA, 0);
|
showDialogInner(DLG_CLEAR_DATA, 0);
|
||||||
|
@@ -774,8 +774,12 @@ public class ManageApplications extends Fragment implements
|
|||||||
holder.appIcon.setImageDrawable(entry.icon);
|
holder.appIcon.setImageDrawable(entry.icon);
|
||||||
}
|
}
|
||||||
holder.updateSizeText(mTab.mInvalidSizeStr, mWhichSize);
|
holder.updateSizeText(mTab.mInvalidSizeStr, mWhichSize);
|
||||||
if (InstalledAppDetails.SUPPORT_DISABLE_APPS) {
|
if ((entry.info.flags&ApplicationInfo.FLAG_INSTALLED) == 0) {
|
||||||
holder.disabled.setVisibility(entry.info.enabled ? View.GONE : View.VISIBLE);
|
holder.disabled.setVisibility(View.VISIBLE);
|
||||||
|
holder.disabled.setText(R.string.not_installed);
|
||||||
|
} else if (!entry.info.enabled) {
|
||||||
|
holder.disabled.setVisibility(View.VISIBLE);
|
||||||
|
holder.disabled.setText(R.string.disabled);
|
||||||
} else {
|
} else {
|
||||||
holder.disabled.setVisibility(View.GONE);
|
holder.disabled.setVisibility(View.GONE);
|
||||||
}
|
}
|
||||||
@@ -997,7 +1001,6 @@ public class ManageApplications extends Fragment implements
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
|
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
|
||||||
Log.i(TAG, "onCreateOptionsMenu in " + this + ": " + menu);
|
|
||||||
mOptionsMenu = menu;
|
mOptionsMenu = menu;
|
||||||
// note: icons removed for now because the cause the new action
|
// note: icons removed for now because the cause the new action
|
||||||
// bar UI to be very confusing.
|
// bar UI to be very confusing.
|
||||||
|
Reference in New Issue
Block a user