LABEL_ATTR = 0x01010001,
ICON_ATTR = 0x01010002,
NAME_ATTR = 0x01010003,
+ DEBUGGABLE_ATTR = 0x0101000f,
VERSION_CODE_ATTR = 0x0101021b,
VERSION_NAME_ATTR = 0x0101021c,
SCREEN_ORIENTATION_ATTR = 0x0101001e,
bool hasWriteExternalStoragePermission = false;
bool hasReadPhoneStatePermission = false;
+ // If an app requests write storage, they will also get read storage.
+ bool hasReadExternalStoragePermission = false;
+
+ // Implement transition to read and write call log.
+ bool hasReadContactsPermission = false;
+ bool hasWriteContactsPermission = false;
+ bool hasReadCallLogPermission = false;
+ bool hasWriteCallLogPermission = false;
+
// This next group of variables is used to implement a group of
// backward-compatibility heuristics necessitated by the addition of
// some new uses-feature constants in 2.1 and 2.2. In most cases, the
if (testOnly != 0) {
printf("testOnly='%d'\n", testOnly);
}
+
+ int32_t debuggable = getResolvedIntegerAttribute(&res, tree, DEBUGGABLE_ATTR, &error, 0);
+ if (error != "") {
+ fprintf(stderr, "ERROR getting 'android:debuggable' attribute: %s\n", error.string());
+ goto bail;
+ }
+ if (debuggable != 0) {
+ printf("application-debuggable\n");
+ }
} else if (tag == "uses-sdk") {
int32_t code = getIntegerAttribute(tree, MIN_SDK_VERSION_ATTR, &error);
if (error != "") {
hasTelephonyPermission = true;
} else if (name == "android.permission.WRITE_EXTERNAL_STORAGE") {
hasWriteExternalStoragePermission = true;
+ } else if (name == "android.permission.READ_EXTERNAL_STORAGE") {
+ hasReadExternalStoragePermission = true;
} else if (name == "android.permission.READ_PHONE_STATE") {
hasReadPhoneStatePermission = true;
+ } else if (name == "android.permission.READ_CONTACTS") {
+ hasReadContactsPermission = true;
+ } else if (name == "android.permission.WRITE_CONTACTS") {
+ hasWriteContactsPermission = true;
+ } else if (name == "android.permission.READ_CALL_LOG") {
+ hasReadCallLogPermission = true;
+ } else if (name == "android.permission.WRITE_CALL_LOG") {
+ hasWriteCallLogPermission = true;
}
printf("uses-permission:'%s'\n", name.string());
} else {
if (targetSdk < 4) {
if (!hasWriteExternalStoragePermission) {
printf("uses-permission:'android.permission.WRITE_EXTERNAL_STORAGE'\n");
+ hasWriteExternalStoragePermission = true;
}
if (!hasReadPhoneStatePermission) {
printf("uses-permission:'android.permission.READ_PHONE_STATE'\n");
}
}
+ // If the application has requested WRITE_EXTERNAL_STORAGE, we will
+ // force them to always take READ_EXTERNAL_STORAGE as well.
+ if (!hasReadExternalStoragePermission && hasWriteExternalStoragePermission) {
+ printf("uses-permission:'android.permission.READ_EXTERNAL_STORAGE'\n");
+ }
+
+ // Pre-JellyBean call log permission compatibility.
+ if (targetSdk < 16) {
+ if (!hasReadCallLogPermission && hasReadContactsPermission) {
+ printf("uses-permission:'android.permission.READ_CALL_LOG'\n");
+ }
+ if (!hasWriteCallLogPermission && hasWriteContactsPermission) {
+ printf("uses-permission:'android.permission.WRITE_CALL_LOG'\n");
+ }
+ }
+
/* The following blocks handle printing "inferred" uses-features, based
* on whether related features or permissions are used by the app.
* Note that the various spec*Feature variables denote whether the