Fix some bugs.
Bug #2376231: Apps lose window focus (and back key causes ANR) if the lock screen is dismissed while the phone is in landscape mode This is another case where we weren't recomputing the focused window after changing the visibility policy. bug #2479958: Investigate source of "Resources don't contain package for resource number 0x7f0a0000" Um, okay, so it turns out there were bugs all over the place where we would load an XML resource from a another application, but not use the Resources for that application to retrieve its resources...! I think the only reason any of this stuff was working at all was because it typically only cared about retrieving the resource identifiers of the items (it would look up the values later). Bug #2401082: Passion ERE26 monkey crash - InputMethodManagerService Add some null checks.
This commit is contained in:
@@ -19,6 +19,7 @@ package android.accounts;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.content.pm.RegisteredServicesCache;
|
||||
import android.content.pm.XmlSerializerAndParser;
|
||||
import android.content.res.Resources;
|
||||
import android.content.res.TypedArray;
|
||||
import android.content.Context;
|
||||
import android.util.AttributeSet;
|
||||
@@ -47,8 +48,9 @@ import java.io.IOException;
|
||||
AccountManager.AUTHENTICATOR_ATTRIBUTES_NAME, sSerializer);
|
||||
}
|
||||
|
||||
public AuthenticatorDescription parseServiceAttributes(String packageName, AttributeSet attrs) {
|
||||
TypedArray sa = mContext.getResources().obtainAttributes(attrs,
|
||||
public AuthenticatorDescription parseServiceAttributes(Resources res,
|
||||
String packageName, AttributeSet attrs) {
|
||||
TypedArray sa = res.obtainAttributes(attrs,
|
||||
com.android.internal.R.styleable.AccountAuthenticator);
|
||||
try {
|
||||
final String accountType =
|
||||
|
||||
@@ -25,7 +25,9 @@ import android.content.pm.ApplicationInfo;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.content.pm.ResolveInfo;
|
||||
import android.content.pm.ServiceInfo;
|
||||
import android.content.pm.PackageManager.NameNotFoundException;
|
||||
import android.content.res.Resources.NotFoundException;
|
||||
import android.content.res.Resources;
|
||||
import android.content.res.TypedArray;
|
||||
import android.content.res.XmlResourceParser;
|
||||
import android.graphics.drawable.Drawable;
|
||||
@@ -96,6 +98,8 @@ public final class WallpaperInfo implements Parcelable {
|
||||
+ WallpaperService.SERVICE_META_DATA + " meta-data");
|
||||
}
|
||||
|
||||
Resources res = pm.getResourcesForApplication(si.applicationInfo);
|
||||
|
||||
AttributeSet attrs = Xml.asAttributeSet(parser);
|
||||
|
||||
int type;
|
||||
@@ -109,7 +113,7 @@ public final class WallpaperInfo implements Parcelable {
|
||||
"Meta-data does not start with wallpaper tag");
|
||||
}
|
||||
|
||||
TypedArray sa = context.getResources().obtainAttributes(attrs,
|
||||
TypedArray sa = res.obtainAttributes(attrs,
|
||||
com.android.internal.R.styleable.Wallpaper);
|
||||
settingsActivityComponent = sa.getString(
|
||||
com.android.internal.R.styleable.Wallpaper_settingsActivity);
|
||||
@@ -125,6 +129,9 @@ public final class WallpaperInfo implements Parcelable {
|
||||
-1);
|
||||
|
||||
sa.recycle();
|
||||
} catch (NameNotFoundException e) {
|
||||
throw new XmlPullParserException(
|
||||
"Unable to create context for: " + si.packageName);
|
||||
} finally {
|
||||
if (parser != null) parser.close();
|
||||
}
|
||||
|
||||
@@ -26,6 +26,8 @@ import android.content.pm.ActivityInfo;
|
||||
import android.content.pm.ApplicationInfo;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.content.pm.ResolveInfo;
|
||||
import android.content.pm.PackageManager.NameNotFoundException;
|
||||
import android.content.res.Resources;
|
||||
import android.content.res.TypedArray;
|
||||
import android.content.res.XmlResourceParser;
|
||||
import android.content.res.Resources.NotFoundException;
|
||||
@@ -181,6 +183,8 @@ public final class DeviceAdminInfo implements Parcelable {
|
||||
+ DeviceAdminReceiver.DEVICE_ADMIN_META_DATA + " meta-data");
|
||||
}
|
||||
|
||||
Resources res = pm.getResourcesForApplication(ai.applicationInfo);
|
||||
|
||||
AttributeSet attrs = Xml.asAttributeSet(parser);
|
||||
|
||||
int type;
|
||||
@@ -194,7 +198,7 @@ public final class DeviceAdminInfo implements Parcelable {
|
||||
"Meta-data does not start with device-admin tag");
|
||||
}
|
||||
|
||||
TypedArray sa = context.getResources().obtainAttributes(attrs,
|
||||
TypedArray sa = res.obtainAttributes(attrs,
|
||||
com.android.internal.R.styleable.DeviceAdmin);
|
||||
|
||||
mVisible = sa.getBoolean(
|
||||
@@ -227,6 +231,9 @@ public final class DeviceAdminInfo implements Parcelable {
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (NameNotFoundException e) {
|
||||
throw new XmlPullParserException(
|
||||
"Unable to create context for: " + ai.packageName);
|
||||
} finally {
|
||||
if (parser != null) parser.close();
|
||||
}
|
||||
|
||||
@@ -18,6 +18,7 @@ package android.content;
|
||||
|
||||
import android.content.pm.RegisteredServicesCache;
|
||||
import android.content.pm.XmlSerializerAndParser;
|
||||
import android.content.res.Resources;
|
||||
import android.content.res.TypedArray;
|
||||
import android.util.AttributeSet;
|
||||
import org.xmlpull.v1.XmlPullParser;
|
||||
@@ -42,8 +43,9 @@ import java.io.IOException;
|
||||
super(context, SERVICE_INTERFACE, SERVICE_META_DATA, ATTRIBUTES_NAME, sSerializer);
|
||||
}
|
||||
|
||||
public SyncAdapterType parseServiceAttributes(String packageName, AttributeSet attrs) {
|
||||
TypedArray sa = mContext.getResources().obtainAttributes(attrs,
|
||||
public SyncAdapterType parseServiceAttributes(Resources res,
|
||||
String packageName, AttributeSet attrs) {
|
||||
TypedArray sa = res.obtainAttributes(attrs,
|
||||
com.android.internal.R.styleable.SyncAdapter);
|
||||
try {
|
||||
final String authority =
|
||||
|
||||
@@ -21,6 +21,8 @@ import android.content.BroadcastReceiver;
|
||||
import android.content.Intent;
|
||||
import android.content.IntentFilter;
|
||||
import android.content.ComponentName;
|
||||
import android.content.pm.PackageManager.NameNotFoundException;
|
||||
import android.content.res.Resources;
|
||||
import android.content.res.XmlResourceParser;
|
||||
import android.os.Environment;
|
||||
import android.os.Handler;
|
||||
@@ -402,7 +404,8 @@ public abstract class RegisteredServicesCache<V> {
|
||||
"Meta-data does not start with " + mAttributesName + " tag");
|
||||
}
|
||||
|
||||
V v = parseServiceAttributes(si.packageName, attrs);
|
||||
V v = parseServiceAttributes(pm.getResourcesForApplication(si.applicationInfo),
|
||||
si.packageName, attrs);
|
||||
if (v == null) {
|
||||
return null;
|
||||
}
|
||||
@@ -410,6 +413,9 @@ public abstract class RegisteredServicesCache<V> {
|
||||
final ApplicationInfo applicationInfo = serviceInfo.applicationInfo;
|
||||
final int uid = applicationInfo.uid;
|
||||
return new ServiceInfo<V>(v, componentName, uid);
|
||||
} catch (NameNotFoundException e) {
|
||||
throw new XmlPullParserException(
|
||||
"Unable to load resources for pacakge " + si.packageName);
|
||||
} finally {
|
||||
if (parser != null) parser.close();
|
||||
}
|
||||
@@ -499,5 +505,6 @@ public abstract class RegisteredServicesCache<V> {
|
||||
}
|
||||
}
|
||||
|
||||
public abstract V parseServiceAttributes(String packageName, AttributeSet attrs);
|
||||
public abstract V parseServiceAttributes(Resources res,
|
||||
String packageName, AttributeSet attrs);
|
||||
}
|
||||
|
||||
@@ -25,6 +25,8 @@ import android.content.pm.ApplicationInfo;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.content.pm.ResolveInfo;
|
||||
import android.content.pm.ServiceInfo;
|
||||
import android.content.pm.PackageManager.NameNotFoundException;
|
||||
import android.content.res.Resources;
|
||||
import android.content.res.TypedArray;
|
||||
import android.content.res.XmlResourceParser;
|
||||
import android.graphics.drawable.Drawable;
|
||||
@@ -92,6 +94,8 @@ public final class InputMethodInfo implements Parcelable {
|
||||
+ InputMethod.SERVICE_META_DATA + " meta-data");
|
||||
}
|
||||
|
||||
Resources res = pm.getResourcesForApplication(si.applicationInfo);
|
||||
|
||||
AttributeSet attrs = Xml.asAttributeSet(parser);
|
||||
|
||||
int type;
|
||||
@@ -105,13 +109,16 @@ public final class InputMethodInfo implements Parcelable {
|
||||
"Meta-data does not start with input-method tag");
|
||||
}
|
||||
|
||||
TypedArray sa = context.getResources().obtainAttributes(attrs,
|
||||
TypedArray sa = res.obtainAttributes(attrs,
|
||||
com.android.internal.R.styleable.InputMethod);
|
||||
settingsActivityComponent = sa.getString(
|
||||
com.android.internal.R.styleable.InputMethod_settingsActivity);
|
||||
isDefaultResId = sa.getResourceId(
|
||||
com.android.internal.R.styleable.InputMethod_isDefault, 0);
|
||||
sa.recycle();
|
||||
} catch (NameNotFoundException e) {
|
||||
throw new XmlPullParserException(
|
||||
"Unable to create context for: " + si.packageName);
|
||||
} finally {
|
||||
if (parser != null) parser.close();
|
||||
}
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
#define LOG_TAG "asset"
|
||||
|
||||
#define DEBUG_STYLES(x) //x
|
||||
#define THROW_ON_BAD_ID 0
|
||||
|
||||
#include <android_runtime/android_util_AssetManager.h>
|
||||
|
||||
@@ -719,9 +720,21 @@ static jint android_content_AssetManager_loadResourceValue(JNIEnv* env, jobject
|
||||
ResTable_config config;
|
||||
uint32_t typeSpecFlags;
|
||||
ssize_t block = res.getResource(ident, &value, false, &typeSpecFlags, &config);
|
||||
#if THROW_ON_BAD_ID
|
||||
if (block == BAD_INDEX) {
|
||||
jniThrowException(env, "java/lang/IllegalStateException", "Bad resource!");
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
uint32_t ref = ident;
|
||||
if (resolve) {
|
||||
block = res.resolveReference(&value, block, &ref);
|
||||
#if THROW_ON_BAD_ID
|
||||
if (block == BAD_INDEX) {
|
||||
jniThrowException(env, "java/lang/IllegalStateException", "Bad resource!");
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
return block >= 0 ? copyValue(env, outValue, &res, value, ref, block, typeSpecFlags, &config) : block;
|
||||
}
|
||||
@@ -763,6 +776,12 @@ static jint android_content_AssetManager_loadResourceBagValue(JNIEnv* env, jobje
|
||||
uint32_t ref = ident;
|
||||
if (resolve) {
|
||||
block = res.resolveReference(&value, block, &ref, &typeSpecFlags);
|
||||
#if THROW_ON_BAD_ID
|
||||
if (block == BAD_INDEX) {
|
||||
jniThrowException(env, "java/lang/IllegalStateException", "Bad resource!");
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
return block >= 0 ? copyValue(env, outValue, &res, value, ref, block, typeSpecFlags) : block;
|
||||
}
|
||||
@@ -852,6 +871,12 @@ static jint android_content_AssetManager_loadThemeAttributeValue(
|
||||
uint32_t ref = 0;
|
||||
if (resolve) {
|
||||
block = res.resolveReference(&value, block, &ref, &typeSpecFlags);
|
||||
#if THROW_ON_BAD_ID
|
||||
if (block == BAD_INDEX) {
|
||||
jniThrowException(env, "java/lang/IllegalStateException", "Bad resource!");
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
return block >= 0 ? copyValue(env, outValue, &res, value, ref, block, typeSpecFlags) : block;
|
||||
}
|
||||
@@ -1071,6 +1096,12 @@ static jboolean android_content_AssetManager_applyStyle(JNIEnv* env, jobject cla
|
||||
value.dataType, value.data));
|
||||
newBlock = res.resolveReference(&value, block, &resid,
|
||||
&typeSetFlags, &config);
|
||||
#if THROW_ON_BAD_ID
|
||||
if (newBlock == BAD_INDEX) {
|
||||
jniThrowException(env, "java/lang/IllegalStateException", "Bad resource!");
|
||||
return JNI_FALSE;
|
||||
}
|
||||
#endif
|
||||
if (newBlock >= 0) block = newBlock;
|
||||
DEBUG_STYLES(LOGI("-> Resolved theme: type=0x%x, data=0x%08x",
|
||||
value.dataType, value.data));
|
||||
@@ -1207,6 +1238,12 @@ static jboolean android_content_AssetManager_retrieveAttributes(JNIEnv* env, job
|
||||
//printf("Resolving attribute reference\n");
|
||||
ssize_t newBlock = res.resolveReference(&value, block, &resid,
|
||||
&typeSetFlags, &config);
|
||||
#if THROW_ON_BAD_ID
|
||||
if (newBlock == BAD_INDEX) {
|
||||
jniThrowException(env, "java/lang/IllegalStateException", "Bad resource!");
|
||||
return JNI_FALSE;
|
||||
}
|
||||
#endif
|
||||
if (newBlock >= 0) block = newBlock;
|
||||
}
|
||||
|
||||
@@ -1314,6 +1351,12 @@ static jint android_content_AssetManager_retrieveArray(JNIEnv* env, jobject claz
|
||||
//printf("Resolving attribute reference\n");
|
||||
ssize_t newBlock = res.resolveReference(&value, block, &resid,
|
||||
&typeSetFlags, &config);
|
||||
#if THROW_ON_BAD_ID
|
||||
if (newBlock == BAD_INDEX) {
|
||||
jniThrowException(env, "java/lang/IllegalStateException", "Bad resource!");
|
||||
return JNI_FALSE;
|
||||
}
|
||||
#endif
|
||||
if (newBlock >= 0) block = newBlock;
|
||||
}
|
||||
|
||||
@@ -1421,6 +1464,13 @@ static jintArray android_content_AssetManager_getArrayStringInfo(JNIEnv* env, jo
|
||||
stringIndex = value.data;
|
||||
}
|
||||
|
||||
#if THROW_ON_BAD_ID
|
||||
if (stringBlock == BAD_INDEX) {
|
||||
jniThrowException(env, "java/lang/IllegalStateException", "Bad resource!");
|
||||
return array;
|
||||
}
|
||||
#endif
|
||||
|
||||
//todo: It might be faster to allocate a C array to contain
|
||||
// the blocknums and indices, put them in there and then
|
||||
// do just one SetIntArrayRegion()
|
||||
@@ -1469,6 +1519,12 @@ static jobjectArray android_content_AssetManager_getArrayStringResource(JNIEnv*
|
||||
|
||||
// Take care of resolving the found resource to its final value.
|
||||
ssize_t block = res.resolveReference(&value, bag->stringBlock, NULL);
|
||||
#if THROW_ON_BAD_ID
|
||||
if (block == BAD_INDEX) {
|
||||
jniThrowException(env, "java/lang/IllegalStateException", "Bad resource!");
|
||||
return array;
|
||||
}
|
||||
#endif
|
||||
if (value.dataType == Res_value::TYPE_STRING) {
|
||||
const ResStringPool* pool = res.getTableStringBlock(block);
|
||||
const char* str8 = pool->string8At(value.data, &strLen);
|
||||
@@ -1520,6 +1576,12 @@ static jintArray android_content_AssetManager_getArrayIntResource(JNIEnv* env, j
|
||||
|
||||
// Take care of resolving the found resource to its final value.
|
||||
ssize_t block = res.resolveReference(&value, bag->stringBlock, NULL);
|
||||
#if THROW_ON_BAD_ID
|
||||
if (block == BAD_INDEX) {
|
||||
jniThrowException(env, "java/lang/IllegalStateException", "Bad resource!");
|
||||
return array;
|
||||
}
|
||||
#endif
|
||||
if (value.dataType >= Res_value::TYPE_FIRST_INT
|
||||
&& value.dataType <= Res_value::TYPE_LAST_INT) {
|
||||
int intVal = value.data;
|
||||
|
||||
@@ -1850,7 +1850,7 @@ bool ResTable::getResourceName(uint32_t resID, resource_name* outName) const
|
||||
if (Res_GETPACKAGE(resID)+1 == 0) {
|
||||
LOGW("No package identifier when getting name for resource number 0x%08x", resID);
|
||||
} else {
|
||||
LOGV("Resources don't contain package for resource number 0x%08x", resID);
|
||||
LOGW("No known package when getting name for resource number 0x%08x", resID);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
@@ -1898,9 +1898,9 @@ ssize_t ResTable::getResource(uint32_t resID, Res_value* outValue, bool mayBeBag
|
||||
|
||||
if (p < 0) {
|
||||
if (Res_GETPACKAGE(resID)+1 == 0) {
|
||||
LOGW("No package identifier when getting name for resource number 0x%08x", resID);
|
||||
LOGW("No package identifier when getting value for resource number 0x%08x", resID);
|
||||
} else {
|
||||
LOGV("Resources don't contain package for resource number 0x%08x", resID);
|
||||
LOGW("No known package when getting value for resource number 0x%08x", resID);
|
||||
}
|
||||
return BAD_INDEX;
|
||||
}
|
||||
@@ -1921,7 +1921,7 @@ ssize_t ResTable::getResource(uint32_t resID, Res_value* outValue, bool mayBeBag
|
||||
const PackageGroup* const grp = mPackageGroups[p];
|
||||
if (grp == NULL) {
|
||||
LOGW("Bad identifier when getting value for resource number 0x%08x", resID);
|
||||
return false;
|
||||
return BAD_INDEX;
|
||||
}
|
||||
size_t ip = grp->packages.size();
|
||||
while (ip > 0) {
|
||||
@@ -2003,7 +2003,7 @@ ssize_t ResTable::getResource(uint32_t resID, Res_value* outValue, bool mayBeBag
|
||||
return bestPackage->header->index;
|
||||
}
|
||||
|
||||
return BAD_INDEX;
|
||||
return BAD_VALUE;
|
||||
}
|
||||
|
||||
ssize_t ResTable::resolveReference(Res_value* value, ssize_t blockIndex,
|
||||
@@ -2018,6 +2018,9 @@ ssize_t ResTable::resolveReference(Res_value* value, ssize_t blockIndex,
|
||||
uint32_t newFlags = 0;
|
||||
const ssize_t newIndex = getResource(value->data, value, true, &newFlags,
|
||||
outConfig);
|
||||
if (newIndex == BAD_INDEX) {
|
||||
return BAD_INDEX;
|
||||
}
|
||||
TABLE_THEME(LOGI("Resolving reference %p: newIndex=%d, type=0x%x, data=%p\n",
|
||||
(void*)lastRef, (int)newIndex, (int)value->dataType, (void*)value->data));
|
||||
//printf("Getting reference 0x%08x: newIndex=%d\n", value->data, newIndex);
|
||||
|
||||
@@ -29,6 +29,7 @@ import android.content.pm.ActivityInfo;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.content.pm.PackageInfo;
|
||||
import android.content.pm.ResolveInfo;
|
||||
import android.content.res.Resources;
|
||||
import android.content.res.TypedArray;
|
||||
import android.content.res.XmlResourceParser;
|
||||
import android.net.Uri;
|
||||
@@ -709,7 +710,10 @@ class AppWidgetService extends IAppWidgetService.Stub
|
||||
info.provider = component;
|
||||
p.uid = activityInfo.applicationInfo.uid;
|
||||
|
||||
TypedArray sa = mContext.getResources().obtainAttributes(attrs,
|
||||
Resources res = mPackageManager.getResourcesForApplication(
|
||||
activityInfo.applicationInfo);
|
||||
|
||||
TypedArray sa = res.obtainAttributes(attrs,
|
||||
com.android.internal.R.styleable.AppWidgetProviderInfo);
|
||||
|
||||
// These dimensions has to be resolved in the application's context.
|
||||
|
||||
@@ -1526,13 +1526,15 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
|
||||
mDialogBuilder.setSingleChoiceItems(mItems, checkedItem,
|
||||
new AlertDialog.OnClickListener() {
|
||||
public void onClick(DialogInterface dialog, int which) {
|
||||
if (mIms == null) {
|
||||
return;
|
||||
}
|
||||
synchronized (mMethodMap) {
|
||||
if (mIms == null || mIms.length <= which) {
|
||||
return;
|
||||
}
|
||||
InputMethodInfo im = mIms[which];
|
||||
hideInputMethodMenu();
|
||||
setInputMethodLocked(im.getId());
|
||||
if (im != null) {
|
||||
setInputMethodLocked(im.getId());
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
@@ -9516,6 +9516,9 @@ public class WindowManagerService extends IWindowManager.Stub
|
||||
|
||||
if (mPolicy.doesForceHide(w, attrs)) {
|
||||
if (!wasAnimating && animating) {
|
||||
if (DEBUG_VISIBILITY) Slog.v(TAG,
|
||||
"Animation done that could impact force hide: "
|
||||
+ w);
|
||||
wallpaperForceHidingChanged = true;
|
||||
mFocusMayChange = true;
|
||||
} else if (w.isReadyForDisplay() && w.mAnimation == null) {
|
||||
@@ -9525,19 +9528,31 @@ public class WindowManagerService extends IWindowManager.Stub
|
||||
boolean changed;
|
||||
if (forceHiding) {
|
||||
changed = w.hideLw(false, false);
|
||||
if (DEBUG_VISIBILITY && changed) Slog.v(TAG,
|
||||
"Now policy hidden: " + w);
|
||||
} else {
|
||||
changed = w.showLw(false, false);
|
||||
if (changed && wallpaperForceHidingChanged
|
||||
&& w.isReadyForDisplay()) {
|
||||
// Assume we will need to animate. If
|
||||
// we don't (because the wallpaper will
|
||||
// stay with the lock screen), then we will
|
||||
// clean up later.
|
||||
Animation a = mPolicy.createForceHideEnterAnimation();
|
||||
if (a != null) {
|
||||
w.setAnimation(a);
|
||||
if (DEBUG_VISIBILITY && changed) Slog.v(TAG,
|
||||
"Now policy shown: " + w);
|
||||
if (changed) {
|
||||
if (wallpaperForceHidingChanged
|
||||
&& w.isReadyForDisplay()) {
|
||||
// Assume we will need to animate. If
|
||||
// we don't (because the wallpaper will
|
||||
// stay with the lock screen), then we will
|
||||
// clean up later.
|
||||
Animation a = mPolicy.createForceHideEnterAnimation();
|
||||
if (a != null) {
|
||||
w.setAnimation(a);
|
||||
}
|
||||
}
|
||||
if (mCurrentFocus == null ||
|
||||
mCurrentFocus.mLayer < w.mLayer) {
|
||||
// We are showing on to of the current
|
||||
// focus, so re-evaluate focus to make
|
||||
// sure it is correct.
|
||||
mFocusMayChange = true;
|
||||
}
|
||||
mFocusMayChange = true;
|
||||
}
|
||||
}
|
||||
if (changed && (attrs.flags
|
||||
|
||||
@@ -1863,6 +1863,8 @@ public final class ActivityManagerService extends ActivityManagerNative implemen
|
||||
+ " pid=" + (app != null ? app.pid : -1));
|
||||
if (app != null && app.pid > 0) {
|
||||
if (!knownToBeDead || app.thread == null) {
|
||||
// We already have the app running, or are waiting for it to
|
||||
// come up (we have a pid but not yet its thread), so keep it.
|
||||
return app;
|
||||
} else {
|
||||
// An application record is attached to a previous process,
|
||||
|
||||
Reference in New Issue
Block a user