Skip to content
Snippets Groups Projects
Commit 5b6bf947 authored by Idries Hamadi's avatar Idries Hamadi Committed by Elliott Hughes
Browse files

Remove fastdeploy dependency on libandroidfw

Call aapt2 to determine package name instead of parsing APK within process.

Test: mm
Test: adb install -r -f --force-agent --local-agent ~/example_apks/example.apk
Test: adb install -r -f --no-streaming --force-agent --local-agent ~/example_apks/example.apk
Change-Id: I99b2c64f0617a9bb27a5c54a2e8f39efd5028f36
parent 28c95396
No related branches found
No related tags found
No related merge requests found
...@@ -174,12 +174,6 @@ cc_library_host_static { ...@@ -174,12 +174,6 @@ cc_library_host_static {
"libdiagnose_usb", "libdiagnose_usb",
"libmdnssd", "libmdnssd",
"libusb", "libusb",
"libandroidfw",
"libziparchive",
"libz",
"libutils",
"liblog",
"libcutils",
], ],
} }
...@@ -262,12 +256,6 @@ cc_binary_host { ...@@ -262,12 +256,6 @@ cc_binary_host {
"liblog", "liblog",
"libmdnssd", "libmdnssd",
"libusb", "libusb",
"libandroidfw",
"libziparchive",
"libz",
"libutils",
"liblog",
"libcutils",
], ],
stl: "libc++_static", stl: "libc++_static",
......
...@@ -130,7 +130,7 @@ static int delete_device_patch_file(const char* apkPath) { ...@@ -130,7 +130,7 @@ static int delete_device_patch_file(const char* apkPath) {
} }
static int install_app_streamed(int argc, const char** argv, bool use_fastdeploy, static int install_app_streamed(int argc, const char** argv, bool use_fastdeploy,
bool use_localagent, const char* adb_path) { bool use_localagent) {
printf("Performing Streamed Install\n"); printf("Performing Streamed Install\n");
// The last argument must be the APK file // The last argument must be the APK file
...@@ -152,8 +152,7 @@ static int install_app_streamed(int argc, const char** argv, bool use_fastdeploy ...@@ -152,8 +152,7 @@ static int install_app_streamed(int argc, const char** argv, bool use_fastdeploy
printf("failed to extract metadata %d\n", metadata_len); printf("failed to extract metadata %d\n", metadata_len);
return 1; return 1;
} else { } else {
int create_patch_result = create_patch(file, metadataTmpFile.path, patchTmpFile.path, int create_patch_result = create_patch(file, metadataTmpFile.path, patchTmpFile.path);
use_localagent, adb_path);
if (create_patch_result != 0) { if (create_patch_result != 0) {
printf("Patch creation failure, error code: %d\n", create_patch_result); printf("Patch creation failure, error code: %d\n", create_patch_result);
result = create_patch_result; result = create_patch_result;
...@@ -226,8 +225,8 @@ static int install_app_streamed(int argc, const char** argv, bool use_fastdeploy ...@@ -226,8 +225,8 @@ static int install_app_streamed(int argc, const char** argv, bool use_fastdeploy
} }
} }
static int install_app_legacy(int argc, const char** argv, bool use_fastdeploy, bool use_localagent, static int install_app_legacy(int argc, const char** argv, bool use_fastdeploy,
const char* adb_path) { bool use_localagent) {
static const char* const DATA_DEST = "/data/local/tmp/%s"; static const char* const DATA_DEST = "/data/local/tmp/%s";
static const char* const SD_DEST = "/sdcard/tmp/%s"; static const char* const SD_DEST = "/sdcard/tmp/%s";
const char* where = DATA_DEST; const char* where = DATA_DEST;
...@@ -269,8 +268,8 @@ static int install_app_legacy(int argc, const char** argv, bool use_fastdeploy, ...@@ -269,8 +268,8 @@ static int install_app_legacy(int argc, const char** argv, bool use_fastdeploy,
printf("failed to extract metadata %d\n", metadata_len); printf("failed to extract metadata %d\n", metadata_len);
return 1; return 1;
} else { } else {
int create_patch_result = create_patch(apk_file[0], metadataTmpFile.path, int create_patch_result =
patchTmpFile.path, use_localagent, adb_path); create_patch(apk_file[0], metadataTmpFile.path, patchTmpFile.path);
if (create_patch_result != 0) { if (create_patch_result != 0) {
printf("Patch creation failure, error code: %d\n", create_patch_result); printf("Patch creation failure, error code: %d\n", create_patch_result);
result = create_patch_result; result = create_patch_result;
...@@ -380,14 +379,10 @@ int install_app(int argc, const char** argv) { ...@@ -380,14 +379,10 @@ int install_app(int argc, const char** argv) {
} }
} }
std::string adb_path = android::base::GetExecutablePath();
if (adb_path.length() == 0) {
return 1;
}
if (use_fastdeploy == true) { if (use_fastdeploy == true) {
bool agent_up_to_date = fastdeploy_init(use_localagent);
update_agent(agent_update_strategy, use_localagent, adb_path.c_str());
bool agent_up_to_date = update_agent(agent_update_strategy);
if (agent_up_to_date == false) { if (agent_up_to_date == false) {
printf("Failed to update agent, exiting\n"); printf("Failed to update agent, exiting\n");
return 1; return 1;
...@@ -397,10 +392,10 @@ int install_app(int argc, const char** argv) { ...@@ -397,10 +392,10 @@ int install_app(int argc, const char** argv) {
switch (installMode) { switch (installMode) {
case INSTALL_PUSH: case INSTALL_PUSH:
return install_app_legacy(passthrough_argv.size(), passthrough_argv.data(), return install_app_legacy(passthrough_argv.size(), passthrough_argv.data(),
use_fastdeploy, use_localagent, adb_path.c_str()); use_fastdeploy, use_localagent);
case INSTALL_STREAM: case INSTALL_STREAM:
return install_app_streamed(passthrough_argv.size(), passthrough_argv.data(), return install_app_streamed(passthrough_argv.size(), passthrough_argv.data(),
use_fastdeploy, use_localagent, adb_path.c_str()); use_fastdeploy, use_localagent);
case INSTALL_DEFAULT: case INSTALL_DEFAULT:
default: default:
return 1; return 1;
......
...@@ -14,11 +14,12 @@ ...@@ -14,11 +14,12 @@
* limitations under the License. * limitations under the License.
*/ */
#include <androidfw/ResourceTypes.h>
#include <androidfw/ZipFileRO.h>
#include <libgen.h> #include <libgen.h>
#include <algorithm> #include <algorithm>
#include <array>
#include "android-base/file.h"
#include "android-base/strings.h"
#include "client/file_sync_client.h" #include "client/file_sync_client.h"
#include "commandline.h" #include "commandline.h"
#include "fastdeploy.h" #include "fastdeploy.h"
...@@ -29,6 +30,15 @@ static constexpr long kRequiredAgentVersion = 0x00000001; ...@@ -29,6 +30,15 @@ static constexpr long kRequiredAgentVersion = 0x00000001;
static constexpr const char* kDeviceAgentPath = "/data/local/tmp/"; static constexpr const char* kDeviceAgentPath = "/data/local/tmp/";
struct TFastDeployConfig {
bool use_localagent;
};
static TFastDeployConfig& get_fastdeploy_config() {
TFastDeployConfig& instance = *new TFastDeployConfig;
return instance;
}
long get_agent_version() { long get_agent_version() {
std::vector<char> versionOutputBuffer; std::vector<char> versionOutputBuffer;
std::vector<char> versionErrorBuffer; std::vector<char> versionErrorBuffer;
...@@ -58,17 +68,19 @@ int get_device_api_level() { ...@@ -58,17 +68,19 @@ int get_device_api_level() {
return api_level; return api_level;
} }
void fastdeploy_init(bool use_localagent) {
get_fastdeploy_config().use_localagent = use_localagent;
}
// local_path - must start with a '/' and be relative to $ANDROID_PRODUCT_OUT // local_path - must start with a '/' and be relative to $ANDROID_PRODUCT_OUT
static bool get_agent_component_host_path(bool use_localagent, const char* adb_path, static bool get_agent_component_host_path(const char* local_path, const char* sdk_path,
const char* local_path, const char* sdk_path,
std::string* output_path) { std::string* output_path) {
std::string mutable_adb_path = adb_path; std::string adb_dir = android::base::GetExecutableDirectory();
const char* adb_dir = dirname(&mutable_adb_path[0]); if (adb_dir.empty()) {
if (adb_dir == nullptr) {
return false; return false;
} }
if (use_localagent) { if (get_fastdeploy_config().use_localagent) {
const char* product_out = getenv("ANDROID_PRODUCT_OUT"); const char* product_out = getenv("ANDROID_PRODUCT_OUT");
if (product_out == nullptr) { if (product_out == nullptr) {
return false; return false;
...@@ -76,26 +88,25 @@ static bool get_agent_component_host_path(bool use_localagent, const char* adb_p ...@@ -76,26 +88,25 @@ static bool get_agent_component_host_path(bool use_localagent, const char* adb_p
*output_path = android::base::StringPrintf("%s%s", product_out, local_path); *output_path = android::base::StringPrintf("%s%s", product_out, local_path);
return true; return true;
} else { } else {
*output_path = android::base::StringPrintf("%s%s", adb_dir, sdk_path); *output_path = adb_dir + sdk_path;
return true; return true;
} }
return false; return false;
} }
static bool deploy_agent(bool checkTimeStamps, bool use_localagent, const char* adb_path) { static bool deploy_agent(bool checkTimeStamps) {
std::vector<const char*> srcs; std::vector<const char*> srcs;
std::string agent_jar_path; std::string agent_jar_path;
if (get_agent_component_host_path(use_localagent, adb_path, "/system/framework/deployagent.jar", if (get_agent_component_host_path("/system/framework/deployagent.jar", "/deployagent.jar",
"/deployagent.jar", &agent_jar_path)) { &agent_jar_path)) {
srcs.push_back(agent_jar_path.c_str()); srcs.push_back(agent_jar_path.c_str());
} else { } else {
return false; return false;
} }
std::string agent_sh_path; std::string agent_sh_path;
if (get_agent_component_host_path(use_localagent, adb_path, "/system/bin/deployagent.sh", if (get_agent_component_host_path("/system/bin/deployagent.sh", "/deployagent.sh",
"/deployagent.sh", &agent_sh_path)) { &agent_sh_path)) {
srcs.push_back(agent_sh_path.c_str()); srcs.push_back(agent_sh_path.c_str());
} else { } else {
return false; return false;
...@@ -114,17 +125,16 @@ static bool deploy_agent(bool checkTimeStamps, bool use_localagent, const char* ...@@ -114,17 +125,16 @@ static bool deploy_agent(bool checkTimeStamps, bool use_localagent, const char*
} }
} }
bool update_agent(FastDeploy_AgentUpdateStrategy agentUpdateStrategy, bool use_localagent, bool update_agent(FastDeploy_AgentUpdateStrategy agentUpdateStrategy) {
const char* adb_path) {
long agent_version = get_agent_version(); long agent_version = get_agent_version();
switch (agentUpdateStrategy) { switch (agentUpdateStrategy) {
case FastDeploy_AgentUpdateAlways: case FastDeploy_AgentUpdateAlways:
if (deploy_agent(false, use_localagent, adb_path) == false) { if (deploy_agent(false) == false) {
return false; return false;
} }
break; break;
case FastDeploy_AgentUpdateNewerTimeStamp: case FastDeploy_AgentUpdateNewerTimeStamp:
if (deploy_agent(true, use_localagent, adb_path) == false) { if (deploy_agent(true) == false) {
return false; return false;
} }
break; break;
...@@ -136,7 +146,7 @@ bool update_agent(FastDeploy_AgentUpdateStrategy agentUpdateStrategy, bool use_l ...@@ -136,7 +146,7 @@ bool update_agent(FastDeploy_AgentUpdateStrategy agentUpdateStrategy, bool use_l
printf("Device agent version is (%ld), (%ld) is required, re-deploying\n", printf("Device agent version is (%ld), (%ld) is required, re-deploying\n",
agent_version, kRequiredAgentVersion); agent_version, kRequiredAgentVersion);
} }
if (deploy_agent(false, use_localagent, adb_path) == false) { if (deploy_agent(false) == false) {
return false; return false;
} }
} }
...@@ -147,91 +157,54 @@ bool update_agent(FastDeploy_AgentUpdateStrategy agentUpdateStrategy, bool use_l ...@@ -147,91 +157,54 @@ bool update_agent(FastDeploy_AgentUpdateStrategy agentUpdateStrategy, bool use_l
return (agent_version == kRequiredAgentVersion); return (agent_version == kRequiredAgentVersion);
} }
static std::string get_string_from_utf16(const char16_t* input, int input_len) { static std::string get_aapt2_path() {
ssize_t utf8_length = utf16_to_utf8_length(input, input_len); if (get_fastdeploy_config().use_localagent) {
if (utf8_length <= 0) { // This should never happen on a Windows machine
return {}; const char* host_out = getenv("ANDROID_HOST_OUT");
if (host_out == nullptr) {
fatal("Could not locate aapt2 because $ANDROID_HOST_OUT is not defined");
} }
return android::base::StringPrintf("%s/bin/aapt2", host_out);
std::string utf8;
utf8.resize(utf8_length);
utf16_to_utf8(input, input_len, &*utf8.begin(), utf8_length + 1);
return utf8;
} }
// output is required to point to a valid output string (non-null) std::string adb_dir = android::base::GetExecutableDirectory();
static bool get_packagename_from_apk(const char* apkPath, std::string* output) { if (adb_dir.empty()) {
using namespace android; fatal("Could not locate aapt2");
}
ZipFileRO* zipFile = ZipFileRO::open(apkPath); return adb_dir + "/aapt2";
if (zipFile == nullptr) {
return false;
} }
ZipEntryRO entry = zipFile->findEntryByName("AndroidManifest.xml"); static int system_capture(const char* cmd, std::string& output) {
if (entry == nullptr) { FILE* pipe = popen(cmd, "re");
return false; int fd = -1;
if (pipe != nullptr) {
fd = fileno(pipe);
} }
uint32_t manifest_len = 0; if (fd == -1) {
if (!zipFile->getEntryInfo(entry, NULL, &manifest_len, NULL, NULL, NULL, NULL)) { fatal_errno("Could not create pipe for process '%s'", cmd);
return false;
} }
std::vector<char> manifest_data(manifest_len); if (!android::base::ReadFdToString(fd, &output)) {
if (!zipFile->uncompressEntry(entry, manifest_data.data(), manifest_len)) { fatal_errno("Error reading from process '%s'", cmd);
return false;
} }
ResXMLTree tree; return pclose(pipe);
status_t setto_status = tree.setTo(manifest_data.data(), manifest_len, true);
if (setto_status != NO_ERROR) {
return false;
} }
ResXMLParser::event_code_t code; // output is required to point to a valid output string (non-null)
while ((code = tree.next()) != ResXMLParser::BAD_DOCUMENT && static bool get_packagename_from_apk(const char* apkPath, std::string* output) {
code != ResXMLParser::END_DOCUMENT) { const char* kAapt2DumpNameCommandPattern = R"(%s dump packagename "%s")";
switch (code) { std::string aapt2_path_string = get_aapt2_path();
case ResXMLParser::START_TAG: { std::string getPackagenameCommand = android::base::StringPrintf(
size_t element_name_length; kAapt2DumpNameCommandPattern, aapt2_path_string.c_str(), apkPath);
const char16_t* element_name = tree.getElementName(&element_name_length);
if (element_name == nullptr) { if (system_capture(getPackagenameCommand.c_str(), *output) == 0) {
continue; // strip any line end characters from the output
} *output = android::base::Trim(*output);
std::u16string element_name_string(element_name, element_name_length);
if (element_name_string == u"manifest") {
for (int i = 0; i < (int)tree.getAttributeCount(); i++) {
size_t attribute_name_length;
const char16_t* attribute_name_text =
tree.getAttributeName(i, &attribute_name_length);
if (attribute_name_text == nullptr) {
continue;
}
std::u16string attribute_name_string(attribute_name_text,
attribute_name_length);
if (attribute_name_string == u"package") {
size_t attribute_value_length;
const char16_t* attribute_value_text =
tree.getAttributeStringValue(i, &attribute_value_length);
if (attribute_value_text == nullptr) {
continue;
}
*output = get_string_from_utf16(attribute_value_text,
attribute_value_length);
return true; return true;
} }
}
}
break;
}
default:
break;
}
}
return false; return false;
} }
...@@ -257,43 +230,30 @@ int extract_metadata(const char* apkPath, FILE* outputFp) { ...@@ -257,43 +230,30 @@ int extract_metadata(const char* apkPath, FILE* outputFp) {
return ret; return ret;
} }
// output is required to point to a valid output string (non-null) static std::string get_patch_generator_command() {
static bool patch_generator_command(bool use_localagent, const char* adb_path, if (get_fastdeploy_config().use_localagent) {
std::string* output) {
if (use_localagent) {
// This should never happen on a Windows machine // This should never happen on a Windows machine
const char* kGeneratorCommandPattern = "java -jar %s/framework/deploypatchgenerator.jar";
const char* host_out = getenv("ANDROID_HOST_OUT"); const char* host_out = getenv("ANDROID_HOST_OUT");
if (host_out == nullptr) { if (host_out == nullptr) {
return false; fatal("Could not locate deploypatchgenerator.jar because $ANDROID_HOST_OUT is not "
"defined");
} }
*output = android::base::StringPrintf(kGeneratorCommandPattern, host_out, host_out); return android::base::StringPrintf("java -jar %s/framework/deploypatchgenerator.jar",
return true; host_out);
} else {
const char* kGeneratorCommandPattern = R"(java -jar "%s/deploypatchgenerator.jar")";
std::string mutable_adb_path = adb_path;
const char* adb_dir = dirname(&mutable_adb_path[0]);
if (adb_dir == nullptr) {
return false;
} }
*output = android::base::StringPrintf(kGeneratorCommandPattern, adb_dir, adb_dir); std::string adb_dir = android::base::GetExecutableDirectory();
return true; if (adb_dir.empty()) {
fatal("Could not locate deploypatchgenerator.jar");
} }
return false; return android::base::StringPrintf(R"(java -jar "%s/deploypatchgenerator.jar")",
adb_dir.c_str());
} }
int create_patch(const char* apkPath, const char* metadataPath, const char* patchPath, int create_patch(const char* apkPath, const char* metadataPath, const char* patchPath) {
bool use_localagent, const char* adb_path) {
const char* kGeneratePatchCommandPattern = R"(%s "%s" "%s" > "%s")";
std::string patch_generator_command_string;
if (patch_generator_command(use_localagent, adb_path, &patch_generator_command_string) ==
false) {
return 1;
}
std::string generatePatchCommand = android::base::StringPrintf( std::string generatePatchCommand = android::base::StringPrintf(
kGeneratePatchCommandPattern, patch_generator_command_string.c_str(), apkPath, R"(%s "%s" "%s" > "%s")", get_patch_generator_command().c_str(), apkPath, metadataPath,
metadataPath, patchPath); patchPath);
return system(generatePatchCommand.c_str()); return system(generatePatchCommand.c_str());
} }
...@@ -302,6 +262,7 @@ std::string get_patch_path(const char* apkPath) { ...@@ -302,6 +262,7 @@ std::string get_patch_path(const char* apkPath) {
if (get_packagename_from_apk(apkPath, &packageName) == false) { if (get_packagename_from_apk(apkPath, &packageName) == false) {
return ""; return "";
} }
std::string patchDevicePath = std::string patchDevicePath =
android::base::StringPrintf("%s%s.patch", kDeviceAgentPath, packageName.c_str()); android::base::StringPrintf("%s%s.patch", kDeviceAgentPath, packageName.c_str());
return patchDevicePath; return patchDevicePath;
...@@ -315,6 +276,7 @@ int apply_patch_on_device(const char* apkPath, const char* patchPath, const char ...@@ -315,6 +276,7 @@ int apply_patch_on_device(const char* apkPath, const char* patchPath, const char
if (get_packagename_from_apk(apkPath, &packageName) == false) { if (get_packagename_from_apk(apkPath, &packageName) == false) {
return -1; return -1;
} }
std::string patchDevicePath = get_patch_path(apkPath); std::string patchDevicePath = get_patch_path(apkPath);
std::vector<const char*> srcs = {patchPath}; std::vector<const char*> srcs = {patchPath};
...@@ -327,6 +289,7 @@ int apply_patch_on_device(const char* apkPath, const char* patchPath, const char ...@@ -327,6 +289,7 @@ int apply_patch_on_device(const char* apkPath, const char* patchPath, const char
std::string applyPatchCommand = std::string applyPatchCommand =
android::base::StringPrintf(kAgentApplyCommandPattern.c_str(), packageName.c_str(), android::base::StringPrintf(kAgentApplyCommandPattern.c_str(), packageName.c_str(),
patchDevicePath.c_str(), outputPath); patchDevicePath.c_str(), outputPath);
return send_shell_command(applyPatchCommand); return send_shell_command(applyPatchCommand);
} }
......
...@@ -18,20 +18,20 @@ ...@@ -18,20 +18,20 @@
#include "adb.h" #include "adb.h"
typedef enum EFastDeploy_AgentUpdateStrategy { enum FastDeploy_AgentUpdateStrategy {
FastDeploy_AgentUpdateAlways, FastDeploy_AgentUpdateAlways,
FastDeploy_AgentUpdateNewerTimeStamp, FastDeploy_AgentUpdateNewerTimeStamp,
FastDeploy_AgentUpdateDifferentVersion FastDeploy_AgentUpdateDifferentVersion
} FastDeploy_AgentUpdateStrategy; };
static constexpr int kFastDeployMinApi = 24; static constexpr int kFastDeployMinApi = 24;
void fastdeploy_init(bool use_localagent);
int get_device_api_level(); int get_device_api_level();
bool update_agent(FastDeploy_AgentUpdateStrategy agentUpdateStrategy, bool use_localagent, bool update_agent(FastDeploy_AgentUpdateStrategy agentUpdateStrategy);
const char* adb_path);
int extract_metadata(const char* apkPath, FILE* outputFp); int extract_metadata(const char* apkPath, FILE* outputFp);
int create_patch(const char* apkPath, const char* metadataPath, const char* patchPath, int create_patch(const char* apkPath, const char* metadataPath, const char* patchPath);
bool use_localagent, const char* adb_path);
int apply_patch_on_device(const char* apkPath, const char* patchPath, const char* outputPath); int apply_patch_on_device(const char* apkPath, const char* patchPath, const char* outputPath);
int install_patch(const char* apkPath, const char* patchPath, int argc, const char** argv); int install_patch(const char* apkPath, const char* patchPath, int argc, const char** argv);
std::string get_patch_path(const char* apkPath); std::string get_patch_path(const char* apkPath);
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment