getNavigationName(navigation.string(), ¶ms);
getScreenSizeName(screenSize.string(), ¶ms);
getVersionName(version.string(), ¶ms);
+
+ // Fix up version number based on specified parameters.
+ int minSdk = 0;
+ if ((params.uiMode&ResTable_config::MASK_UI_MODE_TYPE)
+ != ResTable_config::UI_MODE_TYPE_ANY
+ || (params.uiMode&ResTable_config::MASK_UI_MODE_NIGHT)
+ != ResTable_config::UI_MODE_NIGHT_ANY) {
+ minSdk = SDK_FROYO;
+ } else if ((params.screenLayout&ResTable_config::MASK_SCREENSIZE)
+ != ResTable_config::SCREENSIZE_ANY
+ || (params.screenLayout&ResTable_config::MASK_SCREENLONG)
+ != ResTable_config::SCREENLONG_ANY
+ || params.density != ResTable_config::DENSITY_DEFAULT) {
+ minSdk = SDK_DONUT;
+ }
+
+ if (minSdk > params.sdkVersion) {
+ params.sdkVersion = minSdk;
+ }
+
return params;
}
AXIS_VERSION
};
+enum {
+ SDK_CUPCAKE = 3,
+ SDK_DONUT = 4,
+ SDK_ECLAIR = 5,
+ SDK_ECLAIR_0_1 = 6,
+ SDK_MR1 = 7,
+ SDK_FROYO = 8,
+};
+
/**
* This structure contains a specific variation of a single file out
* of all the variations it can have that we can have.
mUpdate(false), mExtending(false),
mRequireLocalization(false), mPseudolocalize(false),
mUTF8(false), mEncodingSpecified(false), mValues(false),
- mCompressionMethod(0), mOutputAPKFile(NULL), mManifestPackageNameOverride(NULL),
+ mCompressionMethod(0), mOutputAPKFile(NULL),
+ mManifestPackageNameOverride(NULL), mInstrumentationPackageNameOverride(NULL),
mAutoAddOverlay(false), mAssetSourceDir(NULL), mProguardFile(NULL),
mAndroidManifestFile(NULL), mPublicOutputFile(NULL),
mRClassDir(NULL), mResourceIntermediatesDir(NULL),
void setOutputAPKFile(const char* val) { mOutputAPKFile = val; }
const char* getManifestPackageNameOverride() const { return mManifestPackageNameOverride; }
void setManifestPackageNameOverride(const char * val) { mManifestPackageNameOverride = val; }
+ const char* getInstrumentationPackageNameOverride() const { return mInstrumentationPackageNameOverride; }
+ void setInstrumentationPackageNameOverride(const char * val) { mInstrumentationPackageNameOverride = val; }
bool getAutoAddOverlay() { return mAutoAddOverlay; }
void setAutoAddOverlay(bool val) { mAutoAddOverlay = val; }
bool mJunkPath;
const char* mOutputAPKFile;
const char* mManifestPackageNameOverride;
+ const char* mInstrumentationPackageNameOverride;
bool mAutoAddOverlay;
const char* mAssetSourceDir;
const char* mProguardFile;
bool actWallpaperService = false;
bool specCameraFeature = false;
bool hasCameraPermission = false;
+ bool specGpsFeature = false;
+ bool hasGpsPermission = false;
int targetSdk = 0;
int smallScreen = 1;
int normalScreen = 1;
REQUIRED_ATTR, NULL, 1);
if (name == "android.hardware.camera") {
specCameraFeature = true;
+ } else if (name == "android.hardware.location.gps") {
+ specGpsFeature = true;
}
printf("uses-feature%s:'%s'\n",
req ? "" : "-not-required", name.string());
if (name != "" && error == "") {
if (name == "android.permission.CAMERA") {
hasCameraPermission = true;
+ } else if (name == "android.permission.ACCESS_FINE_LOCATION") {
+ hasGpsPermission = true;
}
printf("uses-permission:'%s'\n", name.string());
} else {
printf("uses-feature:'android.hardware.camera.autofocus'\n");
}
+ if (!specGpsFeature && hasGpsPermission) {
+ // For applications that have not explicitly stated their
+ // GPS feature requirements, but have requested the "fine" (GPS)
+ // permission, we are going to give them compatibility treatment
+ // of requiring the equivalent to original android devices.
+ printf("uses-feature:'android.hardware.location.gps'\n");
+ }
+
if (hasMainActivity) {
printf("main\n");
}
" %s p[ackage] [-d][-f][-m][-u][-v][-x][-z][-M AndroidManifest.xml] \\\n"
" [-0 extension [-0 extension ...]] [-g tolerance] [-j jarfile] \\\n"
" [--min-sdk-version VAL] [--target-sdk-version VAL] \\\n"
- " [--max-sdk-version VAL] [--app-version VAL] \\\n"
- " [--app-version-name TEXT] [--custom-package VAL] [--utf16] \\\n"
- " [--auto-add-overlay] \\\n"
+ " [--app-version VAL] [--app-version-name TEXT] [--custom-package VAL] \\\n"
+ " [--rename-manifest-package PACKAGE] \\\n"
+ " [--rename-instrumentation-target-package PACKAGE] \\\n"
+ " [--utf16] [--auto-add-overlay] \\\n"
" [-I base-package [-I base-package ...]] \\\n"
" [-A asset-source-dir] [-G class-list-file] [-P public-definitions-file] \\\n"
" [-S resource-sources [-S resource-sources ...]] "
" higher, the default encoding for resources will be in UTF-8.\n"
" --target-sdk-version\n"
" inserts android:targetSdkVersion in to manifest.\n"
- " --max-sdk-version\n"
- " inserts android:maxSdkVersion in to manifest.\n"
" --values\n"
" when used with \"dump resources\" also includes resource values.\n"
" --version-code\n"
" generates R.java into a different package.\n"
" --auto-add-overlay\n"
" Automatically add resources that are only in overlays.\n"
+ " --rename-manifest-package\n"
+ " Rewrite the manifest so that its package name is the package name\n"
+ " given here. Relative class names (for example .Foo) will be\n"
+ " changed to absolute names with the old package so that the code\n"
+ " does not need to change.\n"
+ " --rename-instrumentation-target-package\n"
+ " Rewrite the manifest so that all of its instrumentation\n"
+ " components target the given package. Useful when used in\n"
+ " conjunction with --rename-manifest-package to fix tests against\n"
+ " a package that has been renamed.\n"
" --utf16\n"
" changes default encoding for resources to UTF-16. Only useful when API\n"
" level is set to 7 or higher where the default encoding is UTF-8.\n");
goto bail;
}
bundle.setManifestPackageNameOverride(argv[0]);
+ } else if (strcmp(cp, "-rename-instrumentation-target-package") == 0) {
+ argc--;
+ argv++;
+ if (!argc) {
+ fprintf(stderr, "ERROR: No argument supplied for '--rename-instrumentation-target-package' option\n");
+ wantUsage = true;
+ goto bail;
+ }
+ bundle.setInstrumentationPackageNameOverride(argv[0]);
} else if (strcmp(cp, "-auto-add-overlay") == 0) {
bundle.setAutoAddOverlay(true);
} else {
node->addAttribute(ns, attr, String16(value));
}
-static void fullyQualifyClassName(String8& package, sp<XMLNode> node) {
+static void fullyQualifyClassName(const String8& package, sp<XMLNode> node,
+ const String16& attrName) {
XMLNode::attribute_entry* attr = node->editAttribute(
- String16("http://schemas.android.com/apk/res/android"), String16("name"));
+ String16("http://schemas.android.com/apk/res/android"), attrName);
if (attr != NULL) {
String8 name(attr->string);
// Make class names fully qualified
sp<XMLNode> application = root->getChildElement(String16(), String16("application"));
if (application != NULL) {
- fullyQualifyClassName(origPackage, application);
+ fullyQualifyClassName(origPackage, application, String16("name"));
Vector<sp<XMLNode> >& children = const_cast<Vector<sp<XMLNode> >&>(application->getChildren());
for (size_t i = 0; i < children.size(); i++) {
sp<XMLNode> child = children.editItemAt(i);
String8 tag(child->getElementName());
if (tag == "activity" || tag == "service" || tag == "receiver" || tag == "provider") {
- fullyQualifyClassName(origPackage, child);
+ fullyQualifyClassName(origPackage, child, String16("name"));
+ } else if (tag == "activity-alias") {
+ fullyQualifyClassName(origPackage, child, String16("name"));
+ fullyQualifyClassName(origPackage, child, String16("targetActivity"));
}
}
}
}
+ // Deal with manifest package name overrides
+ const char* instrumentationPackageNameOverride = bundle->getInstrumentationPackageNameOverride();
+ if (instrumentationPackageNameOverride != NULL) {
+ // Fix up instrumentation targets.
+ Vector<sp<XMLNode> >& children = const_cast<Vector<sp<XMLNode> >&>(root->getChildren());
+ for (size_t i = 0; i < children.size(); i++) {
+ sp<XMLNode> child = children.editItemAt(i);
+ String8 tag(child->getElementName());
+ if (tag == "instrumentation") {
+ XMLNode::attribute_entry* attr = child->editAttribute(
+ String16("http://schemas.android.com/apk/res/android"), String16("targetPackage"));
+ if (attr != NULL) {
+ attr->string.setTo(String16(instrumentationPackageNameOverride));
+ }
+ }
+ }
+ }
+
return NO_ERROR;
}