Skip to content

Commit 3c1dc13

Browse files
committed
New Shell commands: is-package-suspended and set-suspended-package
Bug: 171350084 Bug: 181154143 Test: adb shell dumpsys activity service --user 0 com.afwsamples.testdpc set-suspended-packages true com.android.gallery3d Test: adb shell dumpsys activity service --user 0 com.afwsamples.testdpc is-package-suspended com.android.gallery3d Test: manual verification using UI Change-Id: I9a645909091d994c81c31ce77a2e5f7f03340096 (cherry picked from commit 80a8e08810c3ef8df4a5325b639345416fe0ef31)
1 parent f811656 commit 3c1dc13

File tree

4 files changed

+115
-19
lines changed

4 files changed

+115
-19
lines changed

app/src/main/java/com/afwsamples/testdpc/DevicePolicyManagerGateway.java

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717

1818
import android.app.admin.DevicePolicyManager;
1919
import android.content.ComponentName;
20+
import android.content.pm.PackageManager.NameNotFoundException;
2021
import android.graphics.Bitmap;
2122
import android.os.PersistableBundle;
2223
import android.os.UserHandle;
@@ -232,6 +233,17 @@ void setPasswordQuality(int quality, @NonNull Consumer<Void> onSuccess,
232233
void transferOwnership(@NonNull ComponentName target, @Nullable PersistableBundle bundle,
233234
@NonNull Consumer<Void> onSuccess, @NonNull Consumer<Exception> onError);
234235

236+
/**
237+
* See {@link android.app.admin.DevicePolicyManager#setPackagesSuspended(ComponentName, String[], boolean)}.
238+
*/
239+
void setPackagesSuspended(String[] packageNames, boolean suspended, @NonNull Consumer<String[]> onSuccess,
240+
@NonNull Consumer<Exception> onError);
241+
242+
/**
243+
* See {@link android.app.admin.DevicePolicyManager#isPackageSuspended(ComponentName, String)}.
244+
*/
245+
boolean isPackageSuspended(String packageName) throws NameNotFoundException;
246+
235247
/**
236248
* Used on error callbacks to indicate a {@link android.app.admin.DevicePolicyManager} method
237249
* call failed.

app/src/main/java/com/afwsamples/testdpc/DevicePolicyManagerGatewayImpl.java

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
import android.app.admin.DevicePolicyManager;
2020
import android.content.ComponentName;
2121
import android.content.Context;
22+
import android.content.pm.PackageManager.NameNotFoundException;
2223
import android.graphics.Bitmap;
2324
import android.os.Bundle;
2425
import android.os.PersistableBundle;
@@ -446,6 +447,25 @@ public void transferOwnership(ComponentName target, PersistableBundle bundle,
446447
}
447448
}
448449

450+
@Override
451+
public void setPackagesSuspended(String[] packageNames, boolean suspended,
452+
Consumer<String[]> onSuccess, Consumer<Exception> onError) {
453+
Log.d(TAG, "setPackagesSuspended(" + Arrays.toString(packageNames) + ": " + suspended+ ")");
454+
455+
try {
456+
String[] result = mDevicePolicyManager.setPackagesSuspended(mAdminComponentName,
457+
packageNames, suspended);
458+
onSuccess.accept(result);
459+
} catch (Exception e) {
460+
onError.accept(e);
461+
}
462+
}
463+
464+
@Override
465+
public boolean isPackageSuspended(String packageName) throws NameNotFoundException {
466+
return mDevicePolicyManager.isPackageSuspended(mAdminComponentName, packageName);
467+
}
468+
449469
@Override
450470
public String toString() {
451471
return "DevicePolicyManagerGatewayImpl[" + mAdminComponentName + "]";

app/src/main/java/com/afwsamples/testdpc/ShellCommand.java

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717

1818
import android.content.ComponentName;
1919
import android.content.Context;
20+
import android.content.pm.PackageManager.NameNotFoundException;
2021
import android.graphics.Bitmap;
2122
import android.graphics.BitmapFactory;
2223
import android.os.Environment;
@@ -74,6 +75,8 @@ final class ShellCommand {
7475
private static final String CMD_SET_PASSWORD_QUALITY = "set-password-quality";
7576
private static final String CMD_GET_PASSWORD_QUALITY = "get-password-quality";
7677
private static final String CMD_TRANSFER_OWNERSHIP = "transfer-ownership";
78+
private static final String CMD_SET_SUSPENDED_PACKAGES = "set-suspended-packages";
79+
private static final String CMD_IS_PACKAGE_SUSPENDED = "is-package-suspended";
7780

7881
private static final String ARG_FLAGS = "--flags";
7982

@@ -183,6 +186,12 @@ public void run() {
183186
case CMD_TRANSFER_OWNERSHIP:
184187
execute(() -> transferOwnership());
185188
break;
189+
case CMD_SET_SUSPENDED_PACKAGES:
190+
execute(() -> setPackagesSuspended());
191+
break;
192+
case CMD_IS_PACKAGE_SUSPENDED:
193+
execute(() -> isPackageSuspended());
194+
break;
186195
default:
187196
mWriter.printf("Invalid command: %s\n\n", cmd);
188197
showUsage();
@@ -247,6 +256,10 @@ private void showUsage() {
247256
mWriter.printf("\t%s - get password quality\n", CMD_GET_PASSWORD_QUALITY);
248257
mWriter.printf("\t%s [ADMIN]- transfer ownership to the given admin\n",
249258
CMD_TRANSFER_OWNERSHIP);
259+
mWriter.printf("\t%s <SUSPENDED> <PKG1> [PKG2] [PGKN] - suspend / unsuspend the given "
260+
+ "packages\n", CMD_SET_SUSPENDED_PACKAGES);
261+
mWriter.printf("\t%s <PKG1> [PKG2] [PKGN] - checks if the given packages are suspended\n",
262+
CMD_IS_PACKAGE_SUSPENDED);
250263
}
251264

252265
private void createUser() {
@@ -513,6 +526,36 @@ private void transferOwnership() {
513526
(e) -> onError(e, "Error transferring ownership to %s", flatTarget));
514527
}
515528

529+
private static String suspendedToString(boolean suspended) {
530+
return suspended ? "SUSPENDED" : "NOT SUSPENDED";
531+
}
532+
533+
private void setPackagesSuspended() {
534+
boolean suspended = Boolean.parseBoolean(mArgs[1]);
535+
String[] packageNames = getArrayFromArgs(2);
536+
537+
String printableNames = Arrays.toString(packageNames);
538+
String printableStatus = suspendedToString(suspended);
539+
540+
Log.i(TAG, "setSuspendedPackages(" + printableNames + "): " + printableStatus);
541+
542+
mDevicePolicyManagerGateway.setPackagesSuspended(packageNames, suspended,
543+
(v) -> onSuccess("Set %s (but not %s) to %s", printableNames, Arrays.toString(v),
544+
printableStatus),
545+
(e) -> onError(e, "Error settings %s to %s", printableNames, printableStatus));
546+
}
547+
548+
private void isPackageSuspended() {
549+
getListFromAllArgs().forEach((packageName) -> {
550+
try {
551+
boolean suspended = mDevicePolicyManagerGateway.isPackageSuspended(packageName);
552+
mWriter.printf("%s: %s\n", packageName, suspendedToString(suspended));
553+
} catch (NameNotFoundException e) {
554+
mWriter.printf("Invalid package name: %s\n", packageName);
555+
}
556+
});
557+
}
558+
516559
private void execute(@NonNull Runnable r) {
517560
try {
518561
r.run();
@@ -585,4 +628,11 @@ private List<String> getListFromAllArgs() {
585628
private Set<String> getSetFromAllArgs() {
586629
return new LinkedHashSet<String>(getListFromAllArgs());
587630
}
631+
632+
private String[] getArrayFromArgs(int startingIndex) {
633+
int size = mArgs.length - startingIndex;
634+
String[] array = new String[size];
635+
System.arraycopy(mArgs, startingIndex, array, 0, size);
636+
return array;
637+
}
588638
}

app/src/main/java/com/afwsamples/testdpc/policy/PolicyManagementFragment.java

Lines changed: 33 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1634,8 +1634,8 @@ private void requestBugReport() {
16341634
mDevicePolicyManagerGateway.requestBugreport(
16351635
(v) -> onSuccessLog("requestBugreport"),
16361636
(e) -> onErrorOrFailureShowToast("requestBugreport",
1637-
R.string.bugreport_failure_throttled, R.string.bugreport_failure_exception,
1638-
e));
1637+
e, R.string.bugreport_failure_throttled,
1638+
R.string.bugreport_failure_exception));
16391639
}
16401640

16411641
@TargetApi(VERSION_CODES.M)
@@ -2170,7 +2170,7 @@ public void onClick(DialogInterface dialogInterface, int i) {
21702170
private void removeUser(UserHandle userHandle) {
21712171
mDevicePolicyManagerGateway.removeUser(userHandle,
21722172
(u) -> onSuccessShowToast("removeUser()", R.string.user_removed),
2173-
(e) -> onErrorShowToast("removeUser()", R.string.failed_to_remove_user, e));
2173+
(e) -> onErrorShowToast("removeUser()", e, R.string.failed_to_remove_user));
21742174
}
21752175

21762176
/**
@@ -2196,7 +2196,7 @@ private void showSwitchUserPrompt() {
21962196
showChooseUserPrompt(R.string.switch_user, userHandle -> {
21972197
mDevicePolicyManagerGateway.switchUser(userHandle,
21982198
(v) -> onSuccessShowToast("switchUser", R.string.user_switched),
2199-
(e) -> onErrorShowToast("switchUser", R.string.failed_to_switch_user, e));
2199+
(e) -> onErrorShowToast("switchUser", e, R.string.failed_to_switch_user));
22002200
});
22012201
}
22022202

@@ -2211,7 +2211,7 @@ private void showStartUserInBackgroundPrompt() {
22112211
(v) -> onSuccessShowToast("startUserInBackground",
22122212
R.string.user_started_in_background),
22132213
(e) -> onErrorShowToast("startUserInBackground",
2214-
R.string.failed_to_start_user_in_background, e));
2214+
e, R.string.failed_to_start_user_in_background));
22152215
});
22162216
}
22172217

@@ -2224,7 +2224,7 @@ private void showStopUserPrompt() {
22242224
showChooseUserPrompt(R.string.stop_user, userHandle -> {
22252225
mDevicePolicyManagerGateway.startUserInBackground(userHandle,
22262226
(v) -> onSuccessShowToast("stopUser", R.string.user_stopped),
2227-
(e) -> onErrorShowToast("stopUser", R.string.failed_to_stop_user, e));
2227+
(e) -> onErrorShowToast("stopUser", e, R.string.failed_to_stop_user));
22282228
});
22292229
}
22302230

@@ -3322,12 +3322,19 @@ private void showSuspendAppsPrompt(final boolean forUnsuspending) {
33223322
@Override
33233323
public void onClick(DialogInterface dialog, int position) {
33243324
String packageName = showApps.get(position);
3325-
if (mDevicePolicyManager.setPackagesSuspended(mAdminComponentName,
3326-
new String[] {packageName}, !forUnsuspending).length == 0) {
3327-
showToast(successResId, packageName);
3328-
} else {
3329-
showToast(getString(failureResId, packageName), Toast.LENGTH_LONG);
3330-
}
3325+
mDevicePolicyManagerGateway.setPackagesSuspended(
3326+
new String[] {packageName}, !forUnsuspending,
3327+
(failed) -> {
3328+
if (failed.length == 0) {
3329+
onSuccessShowToast("setPackagesSuspended",
3330+
successResId, packageName);
3331+
} else {
3332+
onErrorShowToast("setPackagesSuspended", failureResId,
3333+
packageName);
3334+
}
3335+
},
3336+
(e) -> onErrorShowToast("setPackagesSuspended", e, failureResId,
3337+
packageName));
33313338
}
33323339
})
33333340
.show();
@@ -3416,7 +3423,7 @@ private void clearApplicationUserData(String packageName) {
34163423
@TargetApi(VERSION_CODES.N)
34173424
private boolean isPackageSuspended(String packageName) {
34183425
try {
3419-
return mDevicePolicyManager.isPackageSuspended(mAdminComponentName, packageName);
3426+
return mDevicePolicyManagerGateway.isPackageSuspended(packageName);
34203427
} catch (PackageManager.NameNotFoundException e) {
34213428
Log.e(TAG, "Unable check if package is suspended", e);
34223429
return false;
@@ -3450,8 +3457,10 @@ private void showToast(String msg) {
34503457
private void showToast(String msg, int duration) {
34513458
Activity activity = getActivity();
34523459
if (activity == null || activity.isFinishing()) {
3460+
Log.w(TAG, "Not toasting '" + msg + "' as activity is finishing or finished");
34533461
return;
34543462
}
3463+
Log.d(TAG, "Showing toast: " + msg);
34553464
Toast.makeText(activity, msg, duration).show();
34563465
}
34573466

@@ -4049,18 +4058,23 @@ private void setAutoTimeZoneEnabled(boolean enabled) {
40494058
mDevicePolicyManager.setAutoTimeZoneEnabled(mAdminComponentName, enabled);
40504059
}
40514060

4052-
private void onSuccessShowToast(String method, int msgId) {
4061+
private void onSuccessShowToast(String method, int msgId, Object...args) {
40534062
Log.d(TAG, method + "() succeeded");
4054-
showToast(msgId);
4063+
showToast(msgId, args);
4064+
}
4065+
4066+
private void onErrorShowToast(String method, int msgId, Object... args) {
4067+
Log.e(TAG, method + "() failed");
4068+
showToast(msgId, args);
40554069
}
40564070

4057-
private void onErrorShowToast(String method, int msgId, Exception e) {
4071+
private void onErrorShowToast(String method, Exception e, int msgId, Object... args) {
40584072
Log.e(TAG, method + "() failed: ", e);
4059-
showToast(msgId);
4073+
showToast(msgId, args);
40604074
}
40614075

4062-
private void onErrorOrFailureShowToast(String method, int failureMsgId, int errorMsgId,
4063-
Exception e) {
4076+
private void onErrorOrFailureShowToast(String method, Exception e, int failureMsgId,
4077+
int errorMsgId) {
40644078
if (e instanceof FailedOperationException) {
40654079
Log.e(TAG, method + " returned false");
40664080
showToast(failureMsgId);

0 commit comments

Comments
 (0)