2 * Copyright (C) 2016 Simon Fels <morphis@gravedo.de>
4 * This program is free software: you can redistribute it and/or modify it
5 * under the terms of the GNU General Public License version 3, as published
6 * by the Free Software Foundation.
8 * This program is distributed in the hope that it will be useful, but
9 * WITHOUT ANY WARRANTY; without even the implied warranties of
10 * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
11 * PURPOSE. See the GNU General Public License for more details.
13 * You should have received a copy of the GNU General Public License along
14 * with this program. If not, see <http://www.gnu.org/licenses/>.
18 #include "anbox/application/launcher_storage.h"
19 #include "anbox/utils.h"
20 #include "anbox/logger.h"
26 namespace fs = boost::filesystem;
29 // This will always point us to the right executable when we're running within
30 // a snap environment.
31 constexpr const char *snap_exe_path{"/snap/bin/anbox"};
35 namespace application {
36 LauncherStorage::LauncherStorage(const fs::path &path) :
39 LauncherStorage::~LauncherStorage() {}
41 void LauncherStorage::reset() {
42 if (fs::exists(path_)) {
43 for(auto & p : boost::filesystem::directory_iterator(path_)) {
44 if (fs::is_regular_file(p)){
45 auto str = p.path().filename().string();
46 if (boost::starts_with(str, "anbox-"))
53 std::string LauncherStorage::clean_package_name(const std::string &package_name) {
54 auto cleaned_package_name = package_name;
55 std::replace(cleaned_package_name.begin(), cleaned_package_name.end(), '.', '-');
56 return cleaned_package_name;
59 fs::path LauncherStorage::path_for_item(const std::string &package_name) {
60 return path_ / utils::string_format("anbox-%s.desktop", package_name);
63 fs::path LauncherStorage::path_for_item_icon(const std::string &package_name) {
64 return path_ / utils::string_format("anbox-%s.png", package_name);
67 void LauncherStorage::add_or_update(const Database::Item &item) {
68 if (!fs::exists(path_)) fs::create_directories(path_);
70 auto package_name = item.package;
71 std::replace(package_name.begin(), package_name.end(), '.', '-');
73 auto exe_path = utils::process_get_exe_path(getpid());
74 if (utils::get_env_value("SNAP").length() > 0)
75 exe_path = snap_exe_path;
77 std::string exec = utils::string_format("%s launch ", exe_path);
79 if (!item.launch_intent.action.empty())
80 exec += utils::string_format("--action=%s ", item.launch_intent.action);
82 if (!item.launch_intent.type.empty())
83 exec += utils::string_format("--type=%s ", item.launch_intent.type);
85 if (!item.launch_intent.uri.empty())
86 exec += utils::string_format("--uri=%s ", item.launch_intent.uri);
88 if (!item.launch_intent.package.empty())
89 exec += utils::string_format("--package=%s ", item.launch_intent.package);
91 if (!item.launch_intent.component.empty())
92 exec += utils::string_format("--component=%s ", item.launch_intent.component);
94 const auto item_icon_path = path_for_item_icon(package_name);
95 if (auto desktop_item = std::ofstream(path_for_item(package_name).string())) {
96 desktop_item << "[Desktop Entry]" << std::endl
97 << "Name=" << item.name << std::endl
98 << "Exec=" << exec << std::endl
99 << "Terminal=false" << std::endl
100 << "Type=Application" << std::endl
101 << "Icon=" << item_icon_path.string() << std::endl;
103 BOOST_THROW_EXCEPTION(std::runtime_error("Failed to create desktop item"));
106 if (auto icon = std::ofstream(item_icon_path.string()))
107 icon.write(item.icon.data(), item.icon.size());
109 BOOST_THROW_EXCEPTION(std::runtime_error("Failed to write icon"));
112 void LauncherStorage::remove(const Database::Item &item) {
113 auto package_name = clean_package_name(item.package);
115 const auto item_path = path_for_item(package_name);
116 if (fs::exists(item_path))
117 fs::remove(item_path);
119 const auto item_icon_path = path_for_item_icon(package_name);
120 if (fs::exists(item_icon_path))
121 fs::remove(item_icon_path);
124 } // namespace application