yashsingh1/xdaforums huggingface dataset:
[Android Software/Hacking General [Developers Only]] llrraa2010:
Step 1. ActivityManagerService.startProcessLocked

frameworks/base/services/java/com/android/server/am/ActivityManagerService.java

public final class ActivityManagerService extends ActivityManagerNative
implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {

......

private final void startProcessLocked(ProcessRecord app,
String hostingType, String hostingNameStr) {

......

try {
int uid = app.info.uid;
int[] gids = null;
try {
gids = mContext.getPackageManager().getPackageGids(
app.info.packageName);
} catch (PackageManager.NameNotFoundException e) {
......
}

......

int debugFlags = 0;

......

int pid = Process.start("android.app.ActivityThread",
mSimpleProcessManagement ? app.processName : null, uid, uid,
gids, debugFlags, null);

......

} catch (RuntimeException e) {

......

}
}

......

}
[Android Software/Hacking General [Developers Only]] llrraa2010:
Step 2. Process.start

frameworks/base/core/java/android/os/Process.java

public class Process {
......

public static final int start(final String processClass,
final String niceName,
int uid, int gid, int[] gids,
int debugFlags,
String[] zygoteArgs)
{
if (supportsProcesses()) {
try {
return startViaZygote(processClass, niceName, uid, gid, gids,
debugFlags, zygoteArgs);
} catch (ZygoteStartFailedEx ex) {
......
}
} else {
......

return 0;
}
}

......
}
[Android Software/Hacking General [Developers Only]] llrraa2010:
Step 3. Process.startViaZygote

frameworks/base/core/java/android/os/Process.java

public class Process {
......

private static int startViaZygote(final String processClass,
final String niceName,
final int uid, final int gid,
final int[] gids,
int debugFlags,
String[] extraArgs)
throws ZygoteStartFailedEx {
int pid;

synchronized(Process.class) {
ArrayList<String> argsForZygote = new ArrayList<String>();

// --runtime-init, --setuid=, --setgid=,
// and --setgroups= must go first
argsForZygote.add("--runtime-init");
argsForZygote.add("--setuid=" + uid);
argsForZygote.add("--setgid=" + gid);
if ((debugFlags & Zygote.DEBUG_ENABLE_SAFEMODE) != 0) {
argsForZygote.add("--enable-safemode");
}
if ((debugFlags & Zygote.DEBUG_ENABLE_DEBUGGER) != 0) {
argsForZygote.add("--enable-debugger");
}
if ((debugFlags & Zygote.DEBUG_ENABLE_CHECKJNI) != 0) {
argsForZygote.add("--enable-checkjni");
}
if ((debugFlags & Zygote.DEBUG_ENABLE_ASSERT) != 0) {
argsForZygote.add("--enable-assert");
}

//TODO optionally enable debuger
//argsForZygote.add("--enable-debugger");

// --setgroups is a comma-separated list
if (gids != null && gids.length > 0) {
StringBuilder sb = new StringBuilder();
sb.append("--setgroups=");

int sz = gids.length;
for (int i = 0; i < sz; i++) {
if (i != 0) {
sb.append(',');
}
sb.append(gids[i]);
}

argsForZygote.add(sb.toString());
}

if (niceName != null) {
argsForZygote.add("--nice-name=" + niceName);
}

argsForZygote.add(processClass);

if (extraArgs != null) {
for (String arg : extraArgs) {
argsForZygote.add(arg);
}
}

pid = zygoteSendArgsAndGetPid(argsForZygote);
}
}

......
}
[Android Software/Hacking General [Developers Only]] llrraa2010:
Step 4. Process.zygoteSendAndGetPid

frameworks/base/core/java/android/os/Process.java

public class Process {
......

private static int zygoteSendArgsAndGetPid(ArrayList<String> args)
throws ZygoteStartFailedEx {
int pid;

openZygoteSocketIfNeeded();

try {
/**
* See com.android.internal.os.ZygoteInit.readArgumentList()
* Presently the wire format to the zygote process is:
* a) a count of arguments (argc, in essence)
* b) a number of newline-separated argument strings equal to count
*
* After the zygote process reads these it will write the pid of
* the child or -1 on failure.
*/

sZygoteWriter.write(Integer.toString(args.size()));
sZygoteWriter.newLine();

int sz = args.size();
for (int i = 0; i < sz; i++) {
String arg = args.get(i);
if (arg.indexOf('\n') >= 0) {
throw new ZygoteStartFailedEx(
"embedded newlines not allowed");
}
sZygoteWriter.write(arg);
sZygoteWriter.newLine();
}

sZygoteWriter.flush();

// Should there be a timeout on this?
pid = sZygoteInputStream.readInt();

if (pid < 0) {
throw new ZygoteStartFailedEx("fork() failed");
}
} catch (IOException ex) {
......
}

return pid;
}

......
}
[Android Software/Hacking General [Developers Only]] llrraa2010:
Step 5. ZygoteInit.runSelectLoopMode

frameworks/base/core/java/com/android/internal/os/ZygoteInit.java

public class ZygoteInit {
......

/**
* Runs the zygote process's select loop. Accepts new connections as
* they happen, and reads commands from connections one spawn-request's
* worth at a time.
*
* @throws MethodAndArgsCaller in a child process when a main() should
* be executed.
*/
private static void runSelectLoopMode() throws MethodAndArgsCaller {
ArrayList<FileDescriptor> fds = new ArrayList();
ArrayList<ZygoteConnection> peers = new ArrayList();
FileDescriptor[] fdArray = new FileDescriptor[4];

fds.add(sServerSocket.getFileDescriptor());
peers.add(null);

int loopCount = GC_LOOP_COUNT;
while (true) {
int index;
/*
* Call gc() before we block in select().
* It's work that has to be done anyway, and it's better
* to avoid making every child do it. It will also
* madvise() any free memory as a side-effect.
*
* Don't call it every time, because walking the entire
* heap is a lot of overhead to free a few hundred bytes.
*/
if (loopCount <= 0) {
gc();
loopCount = GC_LOOP_COUNT;
} else {
loopCount--;
}

try {
fdArray = fds.toArray(fdArray);
index = selectReadable(fdArray);
} catch (IOException ex) {
throw new RuntimeException("Error in select()", ex);
}

if (index < 0) {
throw new RuntimeException("Error in select()");
} else if (index == 0) {
ZygoteConnection newPeer = acceptCommandPeer();
peers.add(newPeer);
fds.add(newPeer.getFileDesciptor());
} else {
boolean done;
done = peers.get(index).runOnce();

if (done) {
peers.remove(index);
fds.remove(index);
}
}
}
}

......
}
[Android Software/Hacking General [Developers Only]] llrraa2010:
Step 6. ZygoteConnection.runOnce

frameworks/base/core/java/com/android/internal/os/ZygoteConnection.java

class ZygoteConnection {
......

boolean runOnce() throws ZygoteInit.MethodAndArgsCaller {
String args[];
Arguments parsedArgs = null;
FileDescriptor[] descriptors;

try {
args = readArgumentList();
descriptors = mSocket.getAncillaryFileDescriptors();
} catch (IOException ex) {
......
return true;
}

......

/** the stderr of the most recent request, if avail */
PrintStream newStderr = null;

if (descriptors != null && descriptors.length >= 3) {
newStderr = new PrintStream(
new FileOutputStream(descriptors[2]));
}

int pid;

try {
parsedArgs = new Arguments(args);

applyUidSecurityPolicy(parsedArgs, peer);
applyDebuggerSecurityPolicy(parsedArgs);
applyRlimitSecurityPolicy(parsedArgs, peer);
applyCapabilitiesSecurityPolicy(parsedArgs, peer);

int[][] rlimits = null;

if (parsedArgs.rlimits != null) {
rlimits = parsedArgs.rlimits.toArray(intArray2d);
}

pid = Zygote.forkAndSpecialize(parsedArgs.uid, parsedArgs.gid,
parsedArgs.gids, parsedArgs.debugFlags, rlimits);
} catch (IllegalArgumentException ex) {
......
} catch (ZygoteSecurityException ex) {
......
}

if (pid == 0) {
// in child
handleChildProc(parsedArgs, descriptors, newStderr);
// should never happen
return true;
} else { /* pid != 0 */
// in parent...pid of < 0 means failure
return handleParentProc(pid, descriptors, parsedArgs);
}
}

......
}
[Android Software/Hacking General [Developers Only]] llrraa2010:
Step 7. ZygoteConnection.handleChildProc

frameworks/base/core/java/com/android/internal/os/ZygoteConnection.java

class ZygoteConnection {
......

private void handleChildProc(Arguments parsedArgs,
FileDescriptor[] descriptors, PrintStream newStderr)
throws ZygoteInit.MethodAndArgsCaller {
......

if (parsedArgs.runtimeInit) {
RuntimeInit.zygoteInit(parsedArgs.remainingArgs);
} else {
......
}
}

......
}
[Android Software/Hacking General [Developers Only]] llrraa2010:
Step 8. RuntimeInit.zygoteInit

frameworks/base/core/java/com/android/internal/os/RuntimeInit.java

public class RuntimeInit {
......

public static final void zygoteInit(String[] argv)
throws ZygoteInit.MethodAndArgsCaller {
// TODO: Doing this here works, but it seems kind of arbitrary. Find
// a better place. The goal is to set it up for applications, but not
// tools like am.
System.setOut(new AndroidPrintStream(Log.INFO, "System.out"));
System.setErr(new AndroidPrintStream(Log.WARN, "System.err"));

commonInit();
zygoteInitNative();

int curArg = 0;
for ( /* curArg */ ; curArg < argv.length; curArg++) {
String arg = argv[curArg];

if (arg.equals("--")) {
curArg++;
break;
} else if (!arg.startsWith("--")) {
break;
} else if (arg.startsWith("--nice-name=")) {
String niceName = arg.substring(arg.indexOf('=') + 1);
Process.setArgV0(niceName);
}
}

if (curArg == argv.length) {
Slog.e(TAG, "Missing classname argument to RuntimeInit!");
// let the process exit
return;
}

// Remaining arguments are passed to the start class's static main

String startClass = argv[curArg++];
String[] startArgs = new String[argv.length - curArg];

System.arraycopy(argv, curArg, startArgs, 0, startArgs.length);
invokeStaticMain(startClass, startArgs);
}

......
}
[Android Software/Hacking General [Developers Only]] llrraa2010:
step 9. RuntimeInit.zygoteInitNative

frameworks/base/core/java/com/android/internal/os/RuntimeInit.java

public class RuntimeInit {
......

public static final native void zygoteInitNative();

......
}
[Android Software/Hacking General [Developers Only]] llrraa2010:
Step 10. AppRuntime.onZygoteInit

frameworks/base/cmds/app_process/app_main.cpp

class AppRuntime : public AndroidRuntime
{
......

virtual void onZygoteInit()
{
sp<ProcessState> proc = ProcessState::self();
if (proc->supportsProcesses()) {
LOGV("App process: starting thread pool.\n");
proc->startThreadPool();
}
}

......
};
[Android Software/Hacking General [Developers Only]] llrraa2010:
Step 11. ProcessState.startThreadPool

frameworks/base/libs/binder/ProcessState.cpp

void ProcessState::startThreadPool()
{
AutoMutex _l(mLock);
if (!mThreadPoolStarted) {
mThreadPoolStarted = true;
spawnPooledThread(true);
}
}
[Android Software/Hacking General [Developers Only]] llrraa2010:
Step 12. ProcessState.spawnPooledThread

frameworks/base/libs/binder/ProcessState.cpp

void ProcessState::spawnPooledThread(bool isMain)
{
if (mThreadPoolStarted) {
int32_t s = android_atomic_add(1, &mThreadPoolSeq);
char buf[32];
sprintf(buf, "Binder Thread #%d", s);
LOGV("Spawning new pooled thread, name=%s\n", buf);
sp<Thread> t = new PoolThread(isMain);
t->run(buf);
}
}
[Android Software/Hacking General [Developers Only]] llrraa2010:
Step 13. PoolThread.threadLoop

frameworks/base/libs/binder/ProcessState.cpp

class PoolThread : public Thread
{
public:
PoolThread(bool isMain)
: mIsMain(isMain)
{
}

protected:
virtual bool threadLoop()
{
IPCThreadState::self()->joinThreadPool(mIsMain);
return false;
}

const bool mIsMain;
};
[Android Software/Hacking General [Developers Only]] llrraa2010:
Step 14. IPCThreadState.joinThreadPool

frameworks/base/libs/binder/IPCThreadState.cpp

void IPCThreadState::joinThreadPool(bool isMain)
{
......

mOut.writeInt32(isMain ? BC_ENTER_LOOPER : BC_REGISTER_LOOPER);

......

status_t result;
do {
int32_t cmd;

......

// now get the next command to be processed, waiting if necessary
result = talkWithDriver();
if (result >= NO_ERROR) {
size_t IN = mIn.dataAvail();
if (IN < sizeof(int32_t)) continue;
cmd = mIn.readInt32();
......

result = executeCommand(cmd);
}

......
} while (result != -ECONNREFUSED && result != -EBADF);

......

mOut.writeInt32(BC_EXIT_LOOPER);
talkWithDriver(false);
}
[Android Software/Hacking General [Developers Only]] llrraa2010:
Step 15. talkWithDriver

frameworks/base/libs/binder/IPCThreadState.cpp

status_t IPCThreadState::talkWithDriver(bool doReceive)
{
......

binder_write_read bwr;

// Is the read buffer empty?
const bool needRead = mIn.dataPosition() >= mIn.dataSize();

// We don't want to write anything if we are still reading
// from data left in the input buffer and the caller
// has requested to read the next data.
const size_t outAvail = (!doReceive || needRead) ? mOut.dataSize() : 0;

bwr.write_size = outAvail;
bwr.write_buffer = (long unsigned int)mOut.data();

// This is what we'll read.
if (doReceive && needRead) {
bwr.read_size = mIn.dataCapacity();
bwr.read_buffer = (long unsigned int)mIn.data();
} else {
bwr.read_size = 0;
}

......

// Return immediately if there is nothing to do.
if ((bwr.write_size == 0) && (bwr.read_size == 0)) return NO_ERROR;

bwr.write_consumed = 0;
bwr.read_consumed = 0;
status_t err;
do {
......
#if defined(HAVE_ANDROID_OS)
if (ioctl(mProcess->mDriverFD, BINDER_WRITE_READ, &bwr) >= 0)
err = NO_ERROR;
else
err = -errno;
#else
err = INVALID_OPERATION;
#endif
......
}
} while (err == -EINTR);

....

if (err >= NO_ERROR) {
if (bwr..write_consumed > 0) {
if (bwr.write_consumed < (ssize_t)mOut.dataSize())
mOut.remove(0, bwr.write_consumed);
else
mOut.setDataSize(0);
}
if (bwr.read_consumed > 0) {
mIn.setDataSize(bwr.read_consumed);
mIn.setDataPosition(0);
}
......
return NO_ERROR;
}

return err;
}
[Android Software/Hacking General [Developers Only]] llrraa2010:
Step 16. RuntimeInit.invokeStaticMain

frameworks/base/core/java/com/android/internal/os/RuntimeInit.java

public class ZygoteInit {
......

static void invokeStaticMain(ClassLoader loader,
String className, String[] argv)
throws ZygoteInit.MethodAndArgsCaller {
Class<?> cl;

try {
cl = loader.loadClass(className);
} catch (ClassNotFoundException ex) {
......
}

Method m;
try {
m = cl.getMethod("main", new Class[] { String[].class });
} catch (NoSuchMethodException ex) {
......
} catch (SecurityException ex) {
......
}

int modifiers = m.getModifiers();
......

/*
* This throw gets caught in ZygoteInit.main(), which responds
* by invoking the exception's run() method. This arrangement
* clears up all the stack frames that were required in setting
* up the process.
*/
throw new ZygoteInit.MethodAndArgsCaller(m, argv);
}

......
}
[Android Software/Hacking General [Developers Only]] llrraa2010:
Step 17. ActivityThread.main

frameworks/base/core/java/android/app/ActivityThread.java

public final class ActivityThread {
......

public static final void main(String[] args) {
SamplingProfilerIntegration.start();

Process.setArgV0("<pre-initialized>");

Looper.prepareMainLooper();
if (sMainThreadHandler == null) {
sMainThreadHandler = new Handler();
}

ActivityThread thread = new ActivityThread();
thread.attach(false);

if (false) {
Looper.myLooper().setMessageLogging(new
LogPrinter(Log.DEBUG, "ActivityThread"));
}
Looper.loop();

if (Process.supportsProcesses()) {
throw new RuntimeException("Main thread loop unexpectedly exited");
}

thread.detach();
String name = (thread.mInitialApplication != null)
? thread.mInitialApplication.getPackageName()
: "<unknown>";
Slog.i(TAG, "Main thread of " + name + " is now exiting");
}

......
}
[Android Software/Hacking General [Developers Only]] llrraa2010:
16.1　installation of application
[Android Software/Hacking General [Developers Only]] llrraa2010:
Step 1. SystemServer.main

frameworks/base/services/java/com/android/server/SystemServer.java

public class SystemServer
{
......

native public static void init1(String[] args);

......

public static void main(String[] args) {
......

init1(args);

......
}

......
}
[Android Software/Hacking General [Developers Only]] llrraa2010:
Step 2. SystemServer.init1

frameworks/base/services/jni/com_android_server_SystemServer.cpp

namespace android {

extern "C" int system_init();

static void android_server_SystemServer_init1(JNIEnv* env, jobject clazz)
{
system_init();
}

/*
* JNI registration.
*/
static JNINativeMethod gMethods[] = {
/* name, signature, funcPtr */
{ "init1", "([Ljava/lang/String;)V", (void*) android_server_SystemServer_init1 },
};

int register_android_server_SystemServer(JNIEnv* env)
{
return jniRegisterNativeMethods(env, "com/android/server/SystemServer",
gMethods, NELEM(gMethods));
}

}; // namespace android
[Android Software/Hacking General [Developers Only]] llrraa2010:
Step 3. libsystem_server.system_init

frameworks/base/cmds/system_server/library/system_init.cpp

extern "C" status_t system_init()
{
LOGI("Entered system_init()");

sp<ProcessState> proc(ProcessState::self());

sp<IServiceManager> sm = defaultServiceManager();
LOGI("ServiceManager: %p\n", sm.get());

sp<GrimReaper> grim = new GrimReaper();
sm->asBinder()->linkToDeath(grim, grim.get(), 0);

char propBuf[PROPERTY_VALUE_MAX];
property_get("system_init.startsurfaceflinger", propBuf, "1");
if (strcmp(propBuf, "1") == 0) {
// Start the SurfaceFlinger
SurfaceFlinger::instantiate();
}

// Start the sensor service
SensorService::instantiate();

// On the simulator, audioflinger et al don't get started the
// same way as on the device, and we need to start them here
if (!proc->supportsProcesses()) {

// Start the AudioFlinger
AudioFlinger::instantiate();

// Start the media playback service
MediaPlayerService::instantiate();

// Start the camera service
CameraService::instantiate();

// Start the audio policy service
AudioPolicyService::instantiate();
}

// And now start the Android runtime. We have to do this bit
// of nastiness because the Android runtime initialization requires
// some of the core system services to already be started.
// All other servers should just start the Android runtime at
// the beginning of their processes's main(), before calling
// the init function.
LOGI("System server: starting Android runtime.\n");

AndroidRuntime* runtime = AndroidRuntime::getRuntime();

LOGI("System server: starting Android services.\n");
runtime->callStatic("com/android/server/SystemServer", "init2");

// If running in our own process, just go into the thread
// pool. Otherwise, call the initialization finished
// func to let this process continue its initilization.
if (proc->supportsProcesses()) {
LOGI("System server: entering thread pool.\n");
ProcessState::self()->startThreadPool();
IPCThreadState::self()->joinThreadPool();
LOGI("System server: exiting thread pool.\n");
}

return NO_ERROR;
}
[Android Software/Hacking General [Developers Only]] llrraa2010:
Step 4. AndroidRuntime.callStatic

frameworks/base/core/jni/AndroidRuntime.cpp

/*
* Call a static Java Programming Language function that takes no arguments and returns void.
*/
status_t AndroidRuntime::callStatic(const char* className, const char* methodName)
{
JNIEnv* env;
jclass clazz;
jmethodID methodId;

env = getJNIEnv();
if (env == NULL)
return UNKNOWN_ERROR;

clazz = findClass(env, className);
if (clazz == NULL) {
LOGE("ERROR: could not find class '%s'\n", className);
return UNKNOWN_ERROR;
}
methodId = env->GetStaticMethodID(clazz, methodName, "()V");
if (methodId == NULL) {
LOGE("ERROR: could not find method %s.%s\n", className, methodName);
return UNKNOWN_ERROR;
}

env->CallStaticVoidMethod(clazz, methodId);

return NO_ERROR;
}
[Android Software/Hacking General [Developers Only]] llrraa2010:
Step 5. SystemServer.init2

frameworks/base/services/java/com/android/server/SystemServer.java

public class SystemServer
{
......

public static final void init2() {
Slog.i(TAG, "Entered the Android system server!");
Thread thr = new ServerThread();
thr.setName("android.server.ServerThread");
thr.start();
}
}
[Android Software/Hacking General [Developers Only]] llrraa2010:
Step 6. ServerThread.run

frameworks/base/services/java/com/android/server/SystemServer.java

class ServerThread extends Thread {
......

@Override
public void run() {
......

IPackageManager pm = null;

......

// Critical services...
try {
......

Slog.i(TAG, "Package Manager");
pm = PackageManagerService.main(context,
factoryTest != SystemServer.FACTORY_TEST_OFF);

......
} catch (RuntimeException e) {
Slog.e("System", "Failure starting core service", e);
}

......
}

......
}
[Android Software/Hacking General [Developers Only]] llrraa2010:
Step 7. PackageManagerService.main

frameworks/base/services/java/com/android/server/PackageManagerService.java

class PackageManagerService extends IPackageManager.Stub {
......

public static final IPackageManager main(Context context, boolean factoryTest) {
PackageManagerService m = new PackageManagerService(context, factoryTest);
ServiceManager.addService("package", m);
return m;
}

......
}
[Android Software/Hacking General [Developers Only]] llrraa2010:
Step 8. PackageManagerService.scanDirLI

frameworks/base/services/java/com/android/server/PackageManagerService.java

class PackageManagerService extends IPackageManager.Stub {
......

private void scanDirLI(File dir, int flags, int scanMode, long currentTime) {
String[] files = dir.list();
......

int i;
for (i=0; i<files.length; i++) {
File file = new File(dir, files[i]);
if (!isPackageFilename(files[i])) {
// Ignore entries which are not apk's
continue;
}
PackageParser.Package pkg = scanPackageLI(file,
flags|PackageParser.PARSE_MUST_BE_APK, scanMode, currentTime);
// Don't mess around with apps in system partition.
if (pkg == null && (flags & PackageParser.PARSE_IS_SYSTEM) == 0 &&
mLastScanError == PackageManager.INSTALL_FAILED_INVALID_APK) {
// Delete the apk
Slog.w(TAG, "Cleaning up failed install of " + file);
file.delete();
}
}
}

......
}
[Android Software/Hacking General [Developers Only]] llrraa2010:
Step 9. PackageManagerService.scanPackageLI

frameworks/base/services/java/com/android/server/PackageManagerService.java

class PackageManagerService extends IPackageManager.Stub {
......

private PackageParser.Package scanPackageLI(File scanFile,
int parseFlags, int scanMode, long currentTime) {
......

String scanPath = scanFile.getPath();
parseFlags |= mDefParseFlags;
PackageParser pp = new PackageParser(scanPath);

......

final PackageParser.Package pkg = pp.parsePackage(scanFile,
scanPath, mMetrics, parseFlags);

......

return scanPackageLI(pkg, parseFlags, scanMode | SCAN_UPDATE_SIGNATURE, currentTime);
}

......
}
[Android Software/Hacking General [Developers Only]] llrraa2010:
Step 10. PackageParser.parsePackage

frameworks/base/core/java/android/content/pm/PackageParser.java

public class PackageParser {
......

public Package parsePackage(File sourceFile, String destCodePath,
DisplayMetrics metrics, int flags) {
......

mArchiveSourcePath = sourceFile.getPath();

......

XmlResourceParser parser = null;
AssetManager assmgr = null;
boolean assetError = true;
try {
assmgr = new AssetManager();
int cookie = assmgr.addAssetPath(mArchiveSourcePath);
if(cookie != 0) {
parser = assmgr.openXmlResourceParser(cookie, "AndroidManifest.xml");
assetError = false;
} else {
......
}
} catch (Exception e) {
......
}

......

String[] errorText = new String[1];
Package pkg = null;
Exception errorException = null;
try {
// XXXX todo: need to figure out correct configuration.
Resources res = new Resources(assmgr, metrics, null);
pkg = parsePackage(res, parser, flags, errorText);
} catch (Exception e) {
......
}

......

parser.close();
assmgr.close();

// Set code and resource paths
pkg.mPath = destCodePath;
pkg.mScanPath = mArchiveSourcePath;
//pkg.applicationInfo.sourceDir = destCodePath;
//pkg.applicationInfo.publicSourceDir = destRes;
pkg.mSignatures = null;

return pkg;
}

......
}