1 /*
2  * Copyright (C) 2016 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy 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,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package com.android.storagemanager.deletionhelper;
18 
19 import android.content.pm.IPackageDeleteObserver;
20 import android.content.pm.PackageManager;
21 import android.os.UserHandle;
22 
23 import java.util.Set;
24 import java.util.concurrent.atomic.AtomicInteger;
25 
26 /**
27  * Deletes a specified set of apps as a specified user and calls back once done.
28  */
29 public class PackageDeletionTask {
30     private Set<String> mPackages;
31     private Callback mCallback;
32     private PackageManager mPm;
33     private UserHandle mUser;
34 
PackageDeletionTask(PackageManager pm, Set<String> packageNames, Callback callback)35     public PackageDeletionTask(PackageManager pm, Set<String> packageNames, Callback callback) {
36         mPackages = packageNames;
37         mCallback = callback;
38         mPm = pm;
39         mUser = android.os.Process.myUserHandle();
40     }
41 
42     /**
43      * Runs the deletion task and clears out the given packages. Upon completion, the callback
44      * is run, if it is set.
45      */
run()46     public void run() {
47         PackageDeletionObserver observer = new PackageDeletionObserver(mPackages.size());
48         for (String packageName : mPackages) {
49             mPm.deletePackageAsUser(packageName, observer, 0, mUser.getIdentifier());
50         }
51     }
52 
53     private class PackageDeletionObserver extends IPackageDeleteObserver.Stub {
54         private final AtomicInteger mPackagesRemaining = new AtomicInteger(0);
55 
PackageDeletionObserver(int packages)56         public PackageDeletionObserver(int packages) {
57             mPackagesRemaining.set(packages);
58         }
59 
60         @Override
packageDeleted(String packageName, int returnCode)61         public void packageDeleted(String packageName, int returnCode) {
62             if (returnCode != PackageManager.DELETE_SUCCEEDED) {
63                 mCallback.onError();
64                 return;
65             }
66 
67             int remaining = mPackagesRemaining.decrementAndGet();
68             if (remaining == 0) {
69                 mCallback.onSuccess();
70             }
71         }
72     }
73 
74     public static abstract class Callback {
onSuccess()75         public abstract void onSuccess();
onError()76         public abstract void onError();
77     }
78 }
79