Improve application manangement and create desktop entries for available app

This commit is contained in:
Simon Fels 2016-12-02 16:11:38 +01:00
commit 00aadb5467
45 changed files with 1435 additions and 249 deletions

View file

@ -27,6 +27,8 @@
#include <binder/IServiceManager.h>
#include <string>
namespace {
std::map<std::string,std::string> common_env = {
{"ANDROID_DATA", "/data"},
@ -60,69 +62,60 @@ void AndroidApiSkeleton::connect_services() {
}
}
void AndroidApiSkeleton::install_application(anbox::protobuf::bridge::InstallApplication const *request,
anbox::protobuf::rpc::Void *response,
google::protobuf::Closure *done) {
(void) response;
std::vector<std::string> argv = {
"/system/bin/pm",
"install",
request->path(),
};
auto process = core::posix::exec("/system/bin/sh", argv, common_env, core::posix::StandardStream::empty);
wait_for_process(process, response);
done->Run();
}
void AndroidApiSkeleton::launch_application(anbox::protobuf::bridge::LaunchApplication const *request,
anbox::protobuf::rpc::Void *response,
google::protobuf::Closure *done) {
(void) response;
std::string intent = request->package_name();
if (request->has_activity()) {
intent += "/";
intent += request->activity();
}
auto intent = request->intent();
std::vector<std::string> argv = {
"/system/bin/am",
"start",
// Launch any applications always in freeform stack
// Launch any application always in the freeform stack
"--stack", "2",
intent,
};
if (intent.has_action()) {
argv.push_back("-a");
argv.push_back(intent.action());
}
if (intent.has_uri()) {
argv.push_back("-d");
argv.push_back(intent.uri());
}
if (intent.has_type()) {
argv.push_back("-t");
argv.push_back(intent.type());
}
std::string component;
if (intent.has_package())
component += intent.package();
if (!component.empty() && intent.has_component()) {
component += "/";
component += intent.component();
}
if (!component.empty())
argv.push_back(component);
ALOGI("Launch am with the following arguments: ");
std::string test;
for (const auto &a : argv) {
test += a;
test += " ";
}
ALOGI("%s", test.c_str());
auto process = core::posix::exec("/system/bin/sh", argv, common_env, core::posix::StandardStream::empty);
wait_for_process(process, response);
done->Run();
}
void AndroidApiSkeleton::set_dns_servers(anbox::protobuf::bridge::SetDnsServers const *request,
anbox::protobuf::rpc::Void *response,
google::protobuf::Closure *done) {
(void) response;
std::vector<std::string> argv = {
"resolver",
"setnetdns",
"0",
request->domain(),
};
for (int n = 0; n < request->servers_size(); n++)
argv.push_back(request->servers(n).address());
auto process = core::posix::exec("/system/bin/ndc", argv, common_env, core::posix::StandardStream::empty);
wait_for_process(process, response);
done->Run();
}
void AndroidApiSkeleton::set_focused_task(anbox::protobuf::bridge::SetFocusedTask const *request,
anbox::protobuf::rpc::Void *response,
google::protobuf::Closure *done) {

View file

@ -49,18 +49,10 @@ public:
AndroidApiSkeleton();
~AndroidApiSkeleton();
void install_application(anbox::protobuf::bridge::InstallApplication const *request,
anbox::protobuf::rpc::Void *response,
google::protobuf::Closure *done);
void launch_application(anbox::protobuf::bridge::LaunchApplication const *request,
anbox::protobuf::rpc::Void *response,
google::protobuf::Closure *done);
void set_dns_servers(anbox::protobuf::bridge::SetDnsServers const *request,
anbox::protobuf::rpc::Void *response,
google::protobuf::Closure *done);
void set_focused_task(anbox::protobuf::bridge::SetFocusedTask const *request,
anbox::protobuf::rpc::Void *response,
google::protobuf::Closure *done);

View file

@ -35,12 +35,8 @@ MessageProcessor::~MessageProcessor() {
}
void MessageProcessor::dispatch(rpc::Invocation const& invocation) {
if (invocation.method_name() == "install_application")
invoke(this, platform_api_.get(), &AndroidApiSkeleton::install_application, invocation);
else if (invocation.method_name() == "launch_application")
if (invocation.method_name() == "launch_application")
invoke(this, platform_api_.get(), &AndroidApiSkeleton::launch_application, invocation);
else if (invocation.method_name() == "set_dns_servers")
invoke(this, platform_api_.get(), &AndroidApiSkeleton::set_dns_servers, invocation);
else if (invocation.method_name() == "set_focused_task")
invoke(this, platform_api_.get(), &AndroidApiSkeleton::set_focused_task, invocation);
}

View file

@ -61,4 +61,28 @@ void PlatformApiStub::update_window_state(const WindowStateUpdate &state) {
rpc_channel_->send_event(seq);
}
void PlatformApiStub::update_application_list(const ApplicationListUpdate &update) {
protobuf::bridge::EventSequence seq;
auto event = seq.mutable_application_list_update();
for (const auto &a : update.applications) {
auto app = event->add_applications();
app->set_name(a.name);
app->set_package(a.package);
auto launch_intent = app->mutable_launch_intent();
launch_intent->set_action(a.launch_intent.action);
launch_intent->set_uri(a.launch_intent.uri);
launch_intent->set_type(a.launch_intent.type);
launch_intent->set_package(a.launch_intent.package);
launch_intent->set_component(a.launch_intent.component);
for (const auto &category : a.launch_intent.categories) {
auto c = launch_intent->add_categories();
*c = category;
}
}
rpc_channel_->send_event(seq);
}
} // namespace anbox

View file

@ -60,6 +60,25 @@ public:
void update_window_state(const WindowStateUpdate &state);
struct ApplicationListUpdate {
struct Application {
std::string name;
std::string package;
struct Intent {
std::string action;
std::string uri;
std::string type;
std::string package;
std::string component;
std::vector<std::string> categories;
};
Intent launch_intent;
};
std::vector<Application> applications;
};
void update_application_list(const ApplicationListUpdate &update);
private:
template<typename Response>
struct Request {

View file

@ -16,6 +16,7 @@
*/
#include "android/service/platform_service.h"
#include "android/service/intent.h"
#include "anbox/rpc/channel.h"
#include "anbox_rpc.pb.h"
@ -84,4 +85,44 @@ status_t PlatformService::update_window_state(const Parcel &data) {
return OK;
}
status_t PlatformService::update_application_list(const Parcel &data) {
anbox::PlatformApiStub::ApplicationListUpdate update;
const auto num_packages = data.readInt32();
for (auto n = 0; n < num_packages; n++) {
String8 name(data.readString16());
String8 package_name(data.readString16());
auto p = anbox::PlatformApiStub::ApplicationListUpdate::Application{
name.string(),
package_name.string(),
};
if (data.readInt32() == 1) {
String8 action(data.readString16());
String8 uri(data.readString16());
String8 type(data.readString16());
String8 component_package(data.readString16());
String8 component_class(data.readString16());
std::vector<std::string> categories;
unsigned int num_categories = data.readInt32();
for (int m = 0; m < num_categories; m++)
categories.push_back(String8(data.readString16()).string());
p.launch_intent.action = action;
p.launch_intent.uri = uri;
p.launch_intent.type = type;
p.launch_intent.package = component_package;
p.launch_intent.component = component_class;
p.launch_intent.categories = categories;
update.applications.push_back(p);
};
}
platform_api_stub_->update_application_list(update);
return OK;
}
} // namespace android

View file

@ -34,6 +34,7 @@ public:
status_t boot_finished() override;
status_t update_window_state(const Parcel &data) override;
status_t update_application_list(const Parcel &data) override;
private:
anbox::PlatformApiStub::WindowStateUpdate::Window unpack_window_state(const Parcel &data);

View file

@ -34,6 +34,12 @@ status_t BpPlatformService::update_window_state(const Parcel&) {
return remote()->transact(IPlatformService::UPDATE_WINDOW_STATE, data, &reply);
}
status_t BpPlatformService::update_application_list(const Parcel&) {
Parcel data, reply;
data.writeInterfaceToken(IPlatformService::getInterfaceDescriptor());
return remote()->transact(IPlatformService::UPDATE_APPLICATION_LIST, data, &reply);
}
IMPLEMENT_META_INTERFACE(PlatformService, "org.anbox.IPlatformService");
status_t BnPlatformService::onTransact(uint32_t code, const Parcel &data,
@ -45,6 +51,9 @@ status_t BnPlatformService::onTransact(uint32_t code, const Parcel &data,
case UPDATE_WINDOW_STATE:
CHECK_INTERFACE(IPlatformService, data, reply);
return update_window_state(data);
case UPDATE_APPLICATION_LIST:
CHECK_INTERFACE(IPlatformService, data, reply);
return update_application_list(data);
default:
break;
}

View file

@ -36,10 +36,12 @@ public:
// Keep this synchronized with frameworks/base/services/java/com/android/server/wm/AnboxPlatformServiceProxy.java
BOOT_FINISHED = IBinder::FIRST_CALL_TRANSACTION,
UPDATE_WINDOW_STATE = IBinder::FIRST_CALL_TRANSACTION + 1,
UPDATE_APPLICATION_LIST = IBinder::FIRST_CALL_TRANSACTION + 2,
};
virtual status_t boot_finished() = 0;
virtual status_t update_window_state(const Parcel &data) = 0;
virtual status_t update_application_list(const Parcel &data) = 0;
};
class BpPlatformService : public BpInterface<IPlatformService> {
@ -48,6 +50,7 @@ public:
status_t boot_finished() override;
status_t update_window_state(const Parcel &data) override;
status_t update_application_list(const Parcel &data) override;
};
class BnPlatformService : public BnInterface<IPlatformService> {