blob: 0f77a8ac5e6fd13fd0d62c11e3d82c865e362b99 [file] [log] [blame]
/*
* Copyright 2014, 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.
*/
package com.android.managedprovisioning.task;
import android.content.Context;
import android.content.Intent;
import android.content.pm.IPackageDeleteObserver;
import android.content.pm.IPackageManager;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.os.RemoteException;
import android.os.ServiceManager;
import com.android.managedprovisioning.ProvisionLogger;
import com.android.managedprovisioning.R;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.concurrent.atomic.AtomicInteger;
/**
* Removes all apps with a launcher that are not required.
* There are two decendants of this class:
* {@link DeleteNonRequiredAppsTask} for profile owner provisioning,
* and {@link DeleteNonRequiredAppsTask} for device owner provisioning.
* The decendents specify which apps are required.
*/
public class DeleteNonRequiredAppsTask {
private final Callback mCallback;
private final Context mContext;
private final IPackageManager mIpm;
private final String mMdmPackageName;
private final PackageManager mPm;
private final int mReqAppsList;
private final int mVendorReqAppsList;
private final int mUserId;
public DeleteNonRequiredAppsTask(Context context, String mdmPackageName, int userId,
int requiredAppsList, int vendorRequiredAppsList, Callback callback) {
mCallback = callback;
mContext = context;
mMdmPackageName = mdmPackageName;
mUserId = userId;
mIpm = IPackageManager.Stub.asInterface(ServiceManager.getService("package"));
mPm = context.getPackageManager();
mReqAppsList = requiredAppsList;
mVendorReqAppsList = vendorRequiredAppsList;
}
public void run() {
ProvisionLogger.logd("Deleting non required apps.");
Intent launcherIntent = new Intent(Intent.ACTION_MAIN);
launcherIntent.addCategory(Intent.CATEGORY_LAUNCHER);
List<ResolveInfo> launcherActivities = mPm.queryIntentActivitiesAsUser(
launcherIntent, PackageManager.NO_CROSS_PROFILE, mUserId);
Set<String> requiredApps = getRequiredApps();
Set<String> packagesToDelete = new HashSet<String>();
for (ResolveInfo activity : launcherActivities) {
String packageName = activity.activityInfo.packageName;
if (!requiredApps.contains(packageName)) {
packagesToDelete.add(packageName);
}
}
PackageDeleteObserver packageDeleteObserver =
new PackageDeleteObserver(packagesToDelete.size());
for (String packageName : packagesToDelete) {
try {
mIpm.deletePackageAsUser(packageName, packageDeleteObserver, mUserId,
PackageManager.DELETE_SYSTEM_APP);
} catch (RemoteException neverThrown) {
// Never thrown, as we are making local calls.
ProvisionLogger.loge("This should not happen.", neverThrown);
}
}
}
protected Set<String> getRequiredApps() {
HashSet<String> requiredApps = new HashSet<String> (Arrays.asList(
mContext.getResources().getStringArray(mReqAppsList)));
requiredApps.addAll(Arrays.asList(
mContext.getResources().getStringArray(mVendorReqAppsList)));
requiredApps.add(mMdmPackageName);
return requiredApps;
}
/**
* Runs the next task when all packages have been deleted or shuts down the activity if package
* deletion fails.
*/
class PackageDeleteObserver extends IPackageDeleteObserver.Stub {
private final AtomicInteger mPackageCount = new AtomicInteger(0);
public PackageDeleteObserver(int packageCount) {
this.mPackageCount.set(packageCount);
}
@Override
public void packageDeleted(String packageName, int returnCode) {
if (returnCode != PackageManager.DELETE_SUCCEEDED) {
ProvisionLogger.logw(
"Could not finish managed profile provisioning: package deletion failed");
mCallback.onError();
}
int currentPackageCount = mPackageCount.decrementAndGet();
if (currentPackageCount == 0) {
ProvisionLogger.logi("All non-required system apps have been uninstalled.");
mCallback.onSuccess();
}
}
}
public abstract static class Callback {
public abstract void onSuccess();
public abstract void onError();
}
}