Merge "Checkbox for removing contributes files"
This commit is contained in:
committed by
Android (Google) Code Review
commit
1d66a820a1
@@ -141,6 +141,7 @@ applications that come with the platform
|
||||
<permission name="android.permission.MANAGE_USERS"/>
|
||||
<permission name="android.permission.UPDATE_APP_OPS_STATS"/>
|
||||
<permission name="android.permission.SUBSTITUTE_NOTIFICATION_APP_NAME"/>
|
||||
<permission name="android.permission.CLEAR_APP_USER_DATA"/>
|
||||
</privapp-permissions>
|
||||
|
||||
<privapp-permissions package="com.android.permissioncontroller">
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
<uses-permission android:name="android.permission.MANAGE_APP_OPS_MODES" />
|
||||
<uses-permission android:name="android.permission.INTERACT_ACROSS_USERS_FULL" />
|
||||
<uses-permission android:name="android.permission.SUBSTITUTE_NOTIFICATION_APP_NAME" />
|
||||
<uses-permission android:name="android.permission.CLEAR_APP_USER_DATA" />
|
||||
|
||||
<uses-permission android:name="com.google.android.permission.INSTALL_WEARABLE_PACKAGES" />
|
||||
|
||||
|
||||
@@ -0,0 +1,47 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
~ Copyright (C) 2018 The Android Open Source Project
|
||||
~
|
||||
~ Licensed under the Apache License, Version 2.0 (the "License");
|
||||
~ you may not use this file except in compliance with the License.
|
||||
~ You may obtain a copy of the License at
|
||||
~
|
||||
~ http://www.apache.org/licenses/LICENSE-2.0
|
||||
~
|
||||
~ Unless required by applicable law or agreed to in writing, software
|
||||
~ distributed under the License is distributed on an "AS IS" BASIS,
|
||||
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
~ See the License for the specific language governing permissions and
|
||||
~ limitations under the License.
|
||||
-->
|
||||
|
||||
<!-- Check box that is displayed in the activity resolver UI for the user
|
||||
to make their selection the preferred activity. -->
|
||||
|
||||
<LinearLayout
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:theme="?android:attr/alertDialogTheme"
|
||||
android:orientation="vertical"
|
||||
android:paddingTop="8dp"
|
||||
android:paddingStart="?android:attr/dialogPreferredPadding"
|
||||
android:paddingEnd="?android:attr/dialogPreferredPadding"
|
||||
android:clipToPadding="false">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/message"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
style="@android:style/TextAppearance.Material.Subhead" />
|
||||
|
||||
<CheckBox
|
||||
android:id="@+id/checkbox"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="8dp"
|
||||
android:layout_marginStart="-8dp"
|
||||
android:paddingLeft="8sp"
|
||||
style="@android:style/TextAppearance.Material.Subhead" />
|
||||
|
||||
</LinearLayout>
|
||||
@@ -119,6 +119,8 @@
|
||||
<string name="uninstall_update_text">Replace this app with the factory version? All data will be removed.</string>
|
||||
<!-- [CHAR LIMIT=none] -->
|
||||
<string name="uninstall_update_text_multiuser">Replace this app with the factory version? All data will be removed. This affects all users of this device, including those with work profiles.</string>
|
||||
<!-- Label of a checkbox that allows to remove the files contributed by app during uninstall [CHAR LIMIT=none] -->
|
||||
<string name="uninstall_remove_contributed_files">Also remove <xliff:g id="size" example="1.5MB">%1$s</xliff:g> of associated media files.</string>
|
||||
|
||||
<!-- Label for the notification channel containing notifications for current uninstall operations [CHAR LIMIT=40] -->
|
||||
<string name="uninstalling_notification_channel">Running uninstalls</string>
|
||||
|
||||
@@ -50,6 +50,8 @@ public class UninstallUninstalling extends Activity implements
|
||||
"com.android.packageinstaller.ACTION_UNINSTALL_COMMIT";
|
||||
|
||||
static final String EXTRA_APP_LABEL = "com.android.packageinstaller.extra.APP_LABEL";
|
||||
static final String EXTRA_CLEAR_CONTRIBUTED_FILES =
|
||||
"com.android.packageinstaller.extra.CLEAR_CONTRIBUTED_FILES";
|
||||
|
||||
private int mUninstallId;
|
||||
private ApplicationInfo mAppInfo;
|
||||
@@ -72,6 +74,8 @@ public class UninstallUninstalling extends Activity implements
|
||||
if (savedInstanceState == null) {
|
||||
boolean allUsers = getIntent().getBooleanExtra(Intent.EXTRA_UNINSTALL_ALL_USERS,
|
||||
false);
|
||||
boolean clearContributedFiles = getIntent().getBooleanExtra(
|
||||
EXTRA_CLEAR_CONTRIBUTED_FILES, false);
|
||||
UserHandle user = getIntent().getParcelableExtra(Intent.EXTRA_USER);
|
||||
|
||||
// Show dialog, which is the whole UI
|
||||
@@ -95,12 +99,15 @@ public class UninstallUninstalling extends Activity implements
|
||||
PendingIntent pendingIntent = PendingIntent.getBroadcast(this, mUninstallId,
|
||||
broadcastIntent, PendingIntent.FLAG_UPDATE_CURRENT);
|
||||
|
||||
int flags = allUsers ? PackageManager.DELETE_ALL_USERS : 0;
|
||||
flags |= clearContributedFiles ? PackageManager.DELETE_CONTRIBUTED_MEDIA : 0;
|
||||
|
||||
try {
|
||||
ActivityThread.getPackageManager().getPackageInstaller().uninstall(
|
||||
new VersionedPackage(mAppInfo.packageName,
|
||||
PackageManager.VERSION_CODE_HIGHEST),
|
||||
getPackageName(), allUsers ? PackageManager.DELETE_ALL_USERS : 0,
|
||||
pendingIntent.getIntentSender(), user.getIdentifier());
|
||||
getPackageName(), flags, pendingIntent.getIntentSender(),
|
||||
user.getIdentifier());
|
||||
} catch (RemoteException e) {
|
||||
e.rethrowFromSystemServer();
|
||||
}
|
||||
|
||||
@@ -285,7 +285,7 @@ public class UninstallerActivity extends Activity {
|
||||
fragment.show(ft, "dialog");
|
||||
}
|
||||
|
||||
public void startUninstallProgress() {
|
||||
public void startUninstallProgress(boolean clearContributedFiles) {
|
||||
boolean returnResult = getIntent().getBooleanExtra(Intent.EXTRA_RETURN_RESULT, false);
|
||||
CharSequence label = mDialogInfo.appInfo.loadSafeLabel(getPackageManager());
|
||||
|
||||
@@ -310,6 +310,8 @@ public class UninstallerActivity extends Activity {
|
||||
newIntent.putExtra(Intent.EXTRA_UNINSTALL_ALL_USERS, mDialogInfo.allUsers);
|
||||
newIntent.putExtra(PackageUtil.INTENT_ATTR_APPLICATION_INFO, mDialogInfo.appInfo);
|
||||
newIntent.putExtra(UninstallUninstalling.EXTRA_APP_LABEL, label);
|
||||
newIntent.putExtra(UninstallUninstalling.EXTRA_CLEAR_CONTRIBUTED_FILES,
|
||||
clearContributedFiles);
|
||||
newIntent.putExtra(PackageInstaller.EXTRA_CALLBACK, mDialogInfo.callback);
|
||||
|
||||
if (returnResult) {
|
||||
@@ -358,12 +360,14 @@ public class UninstallerActivity extends Activity {
|
||||
try {
|
||||
Log.i(TAG, "Uninstalling extras=" + broadcastIntent.getExtras());
|
||||
|
||||
int flags = mDialogInfo.allUsers ? PackageManager.DELETE_ALL_USERS : 0;
|
||||
flags |= clearContributedFiles ? PackageManager.DELETE_CONTRIBUTED_MEDIA : 0;
|
||||
|
||||
ActivityThread.getPackageManager().getPackageInstaller().uninstall(
|
||||
new VersionedPackage(mDialogInfo.appInfo.packageName,
|
||||
PackageManager.VERSION_CODE_HIGHEST),
|
||||
getPackageName(), mDialogInfo.allUsers
|
||||
? PackageManager.DELETE_ALL_USERS : 0,
|
||||
pendingIntent.getIntentSender(), mDialogInfo.user.getIdentifier());
|
||||
getPackageName(), flags, pendingIntent.getIntentSender(),
|
||||
mDialogInfo.user.getIdentifier());
|
||||
} catch (Exception e) {
|
||||
notificationManager.cancel(uninstallId);
|
||||
|
||||
|
||||
@@ -16,6 +16,9 @@
|
||||
|
||||
package com.android.packageinstaller.handheld;
|
||||
|
||||
import static android.text.format.Formatter.formatFileSize;
|
||||
|
||||
import android.annotation.NonNull;
|
||||
import android.app.AlertDialog;
|
||||
import android.app.Dialog;
|
||||
import android.app.DialogFragment;
|
||||
@@ -24,14 +27,41 @@ import android.content.pm.ApplicationInfo;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.content.pm.UserInfo;
|
||||
import android.os.Bundle;
|
||||
import android.os.UserHandle;
|
||||
import android.os.UserManager;
|
||||
import android.provider.MediaStore;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.CheckBox;
|
||||
import android.widget.TextView;
|
||||
|
||||
import com.android.packageinstaller.R;
|
||||
import com.android.packageinstaller.UninstallerActivity;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
|
||||
public class UninstallAlertDialogFragment extends DialogFragment implements
|
||||
DialogInterface.OnClickListener {
|
||||
|
||||
private CheckBox mClearContributedFiles;
|
||||
|
||||
/**
|
||||
* Get number of bytes of the combined files contributed by the package.
|
||||
*
|
||||
* @param pkg The package that might have contibuted files.
|
||||
* @param user The user the package belongs to.
|
||||
*
|
||||
* @return The number of bytes.
|
||||
*/
|
||||
private long getContributedMediaSize(@NonNull String pkg, @NonNull UserHandle user) {
|
||||
try {
|
||||
return MediaStore.getContributedMediaSize(getContext(), pkg, user);
|
||||
} catch (IOException e) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Dialog onCreateDialog(Bundle savedInstanceState) {
|
||||
final PackageManager pm = getActivity().getPackageManager();
|
||||
@@ -76,14 +106,44 @@ public class UninstallAlertDialogFragment extends DialogFragment implements
|
||||
dialogBuilder.setTitle(appLabel);
|
||||
dialogBuilder.setPositiveButton(android.R.string.ok, this);
|
||||
dialogBuilder.setNegativeButton(android.R.string.cancel, this);
|
||||
dialogBuilder.setMessage(messageBuilder.toString());
|
||||
|
||||
String pkg = dialogInfo.appInfo.packageName;
|
||||
long contributedFileSize = 0;
|
||||
if (dialogInfo.allUsers) {
|
||||
List<UserInfo> users = userManager.getUsers();
|
||||
|
||||
int numUsers = users.size();
|
||||
for (int i = 0; i < numUsers; i++) {
|
||||
UserHandle user = UserHandle.of(users.get(i).id);
|
||||
|
||||
contributedFileSize += getContributedMediaSize(pkg, user);
|
||||
}
|
||||
} else {
|
||||
contributedFileSize = getContributedMediaSize(pkg, dialogInfo.user);
|
||||
}
|
||||
|
||||
if (contributedFileSize == 0) {
|
||||
dialogBuilder.setMessage(messageBuilder.toString());
|
||||
} else {
|
||||
LayoutInflater inflater = getContext().getSystemService(LayoutInflater.class);
|
||||
ViewGroup content = (ViewGroup) inflater.inflate(R.layout.uninstall_content_view, null);
|
||||
|
||||
((TextView) content.requireViewById(R.id.message)).setText(messageBuilder.toString());
|
||||
mClearContributedFiles = content.requireViewById(R.id.checkbox);
|
||||
mClearContributedFiles.setText(getString(R.string.uninstall_remove_contributed_files,
|
||||
formatFileSize(getContext(), contributedFileSize)));
|
||||
|
||||
dialogBuilder.setView(content);
|
||||
}
|
||||
|
||||
return dialogBuilder.create();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onClick(DialogInterface dialog, int which) {
|
||||
if (which == Dialog.BUTTON_POSITIVE) {
|
||||
((UninstallerActivity) getActivity()).startUninstallProgress();
|
||||
((UninstallerActivity) getActivity()).startUninstallProgress(
|
||||
mClearContributedFiles != null && mClearContributedFiles.isChecked());
|
||||
} else {
|
||||
((UninstallerActivity) getActivity()).dispatchAborted();
|
||||
}
|
||||
|
||||
@@ -99,7 +99,7 @@ public class UninstallAlertFragment extends GuidedStepFragment {
|
||||
public void onGuidedActionClicked(GuidedAction action) {
|
||||
if (isAdded()) {
|
||||
if (action.getId() == GuidedAction.ACTION_ID_OK) {
|
||||
((UninstallerActivity) getActivity()).startUninstallProgress();
|
||||
((UninstallerActivity) getActivity()).startUninstallProgress(false);
|
||||
getActivity().finish();
|
||||
} else {
|
||||
((UninstallerActivity) getActivity()).dispatchAborted();
|
||||
|
||||
Reference in New Issue
Block a user