Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 3 additions & 6 deletions Tactility/Include/Tactility/service/Service.h
Original file line number Diff line number Diff line change
@@ -1,15 +1,12 @@
#pragma once

#include <tactility/service/service_instance.h>

#include <memory>

namespace tt::service {

enum class State {
Starting,
Started,
Stopping,
Stopped
};
using State = ::ServiceState;

// Forward declaration
class ServiceContext;
Expand Down
36 changes: 30 additions & 6 deletions Tactility/Include/Tactility/service/ServicePaths.h
Original file line number Diff line number Diff line change
@@ -1,12 +1,18 @@
#pragma once

#include <Tactility/service/ServiceManifest.h>

#include <tactility/check.h>
#include <tactility/error.h>
#include <tactility/service/service_paths.h>

#include <cassert>
#include <string>
#include <memory>

namespace tt::service {

// Forward declarations
class ServiceManifest;
constexpr size_t PATH_BUFFER_SIZE = 255;

class ServicePaths {

Expand All @@ -20,26 +26,44 @@ class ServicePaths {
* The user data directory is intended to survive OS upgrades.
* The path will not end with a "/".
*/
std::string getUserDataDirectory() const;
std::string getUserDataDirectory() const {
char buffer[PATH_BUFFER_SIZE];
check(service_paths_get_user_data_directory(manifest->id.c_str(), buffer, sizeof(buffer)) == ERROR_NONE);
return buffer;
}

/**
* The user data directory is intended to survive OS upgrades.
* Configuration data should be stored here.
* @param[in] childPath the path without a "/" prefix
*/
std::string getUserDataPath(const std::string& childPath) const;
std::string getUserDataPath(const std::string& childPath) const {
assert(!childPath.starts_with('/'));
char buffer[PATH_BUFFER_SIZE];
check(service_paths_get_user_data_path(manifest->id.c_str(), childPath.c_str(), buffer, sizeof(buffer)) == ERROR_NONE);
return buffer;
}

/**
* You should not store configuration data here.
* The path will not end with a "/".
*/
std::string getAssetsDirectory() const;
std::string getAssetsDirectory() const {
char buffer[PATH_BUFFER_SIZE];
check(service_paths_get_assets_directory(manifest->id.c_str(), buffer, sizeof(buffer)) == ERROR_NONE);
return buffer;
}

/**
* You should not store configuration data here.
* @param[in] childPath the path without a "/" prefix
*/
std::string getAssetsPath(const std::string& childPath) const;
std::string getAssetsPath(const std::string& childPath) const {
assert(!childPath.starts_with('/'));
char buffer[PATH_BUFFER_SIZE];
check(service_paths_get_assets_path(manifest->id.c_str(), childPath.c_str(), buffer, sizeof(buffer)) == ERROR_NONE);
return buffer;
}
};

}
37 changes: 22 additions & 15 deletions Tactility/Private/Tactility/service/ServiceInstance.h
Original file line number Diff line number Diff line change
@@ -1,36 +1,43 @@
#pragma once

#include <Tactility/service/ServiceContext.h>
#include <Tactility/service/Service.h>
#include <Tactility/Mutex.h>
#include <Tactility/service/ServiceManifest.h>
#include <Tactility/service/ServicePaths.h>

#include <tactility/service/service_context.h>

#include <memory>

namespace tt::service {

/**
* Thin wrapper around the running TactilityKernel service context (::ServiceContext,
* which is the same object as ::ServiceInstance in the C API). Non-owning: valid only
* for as long as the underlying kernel instance is running.
*/
class ServiceInstance final : public ServiceContext {

Mutex mutex;
std::shared_ptr<const ServiceManifest> manifest;
std::shared_ptr<Service> service;
State state = State::Stopped;
::ServiceContext* cContext;

std::shared_ptr<const ServiceManifest>& getCppManifest(::ServiceContext* cContext) const {
const auto* cManifest = service_context_get_manifest(cContext);
return *static_cast<std::shared_ptr<const ServiceManifest>*>(cManifest->context);
}

public:

explicit ServiceInstance(std::shared_ptr<const ServiceManifest> manifest);
explicit ServiceInstance(::ServiceContext* cContext) : cContext(cContext) {}
~ServiceInstance() override = default;

/** @return a reference to the service's manifest */
const ServiceManifest& getManifest() const override;
const ServiceManifest& getManifest() const override {
return *getCppManifest(cContext);
}

/** Retrieve the paths that are relevant to this service */
std::unique_ptr<ServicePaths> getPaths() const override;

std::shared_ptr<Service> getService() const { return service; }

State getState() const { return state; }

void setState(State newState) { state = newState; }
std::unique_ptr<ServicePaths> getPaths() const override {
return std::make_unique<ServicePaths>(getCppManifest(cContext));
}
};

}
14 changes: 11 additions & 3 deletions Tactility/Source/bluetooth/BluetoothPairedDevice.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
#include <Tactility/bluetooth/BluetoothPairedDevice.h>

#include "Tactility/Paths.h"

#include <Tactility/file/File.h>
#include <Tactility/file/PropertiesFile.h>
#include <tactility/log.h>
Expand All @@ -16,13 +18,16 @@ namespace tt::bluetooth::settings {
constexpr auto* TAG = "BluetoothPairedDevice";

// Use the same directory as the old service for backward compatibility.
constexpr auto* DATA_DIR = "/data/service/bluetooth";
constexpr auto* DEVICE_SETTINGS_FORMAT = "{}/{}.device.properties";
constexpr auto* KEY_NAME = "name";
constexpr auto* KEY_ADDR = "addr";
constexpr auto* KEY_AUTO_CONNECT = "autoConnect";
constexpr auto* KEY_PROFILE_ID = "profileId";

static std::string getSettingsFilePath() {
return getUserDataPath() + "/service/bluetooth";
}

Comment thread
KenVanHoeylandt marked this conversation as resolved.
std::string addrToHex(const std::array<uint8_t, 6>& addr) {
std::stringstream stream;
stream << std::hex;
Expand Down Expand Up @@ -52,7 +57,7 @@ static bool hexToAddr(const std::string& hex, std::array<uint8_t, 6>& addr) {
}

static std::string getFilePath(const std::string& addr_hex) {
return std::format(DEVICE_SETTINGS_FORMAT, DATA_DIR, addr_hex);
return std::format(DEVICE_SETTINGS_FORMAT, getSettingsFilePath(), addr_hex);
}

bool hasFileForDevice(const std::string& addr_hex) {
Expand Down Expand Up @@ -102,7 +107,10 @@ bool remove(const std::string& addr_hex) {

std::vector<PairedDevice> loadAll() {
std::vector<dirent> entries;
file::scandir(DATA_DIR, entries, [](const dirent* entry) -> int {
if (!file::isDirectory(getSettingsFilePath())) {
return {};
}
file::scandir(getSettingsFilePath(), entries, [](const dirent* entry) -> int {
if (entry->d_type != file::TT_DT_REG && entry->d_type != file::TT_DT_UNKNOWN) return -1;
std::string name = entry->d_name;
return name.ends_with(".device.properties") ? 0 : -1;
Expand Down
4 changes: 2 additions & 2 deletions Tactility/Source/lvgl/Lvgl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@ void attachDevices() {
// We search for the manifest first, because during the initial start() during boot
// the service won't be registered yet.
if (service::findManifestById("Gui") != nullptr) {
if (service::getState("Gui") == service::State::Stopped) {
if (service::getState("Gui") == SERVICE_STATE_STOPPED) {
service::startService("Gui");
} else {
LOG_E(TAG, "Gui service is not in Stopped state");
Expand All @@ -112,7 +112,7 @@ void attachDevices() {
// We search for the manifest first, because during the initial start() during boot
// the service won't be registered yet.
if (service::findManifestById("Statusbar") != nullptr) {
if (service::getState("Statusbar") == service::State::Stopped) {
if (service::getState("Statusbar") == SERVICE_STATE_STOPPED) {
service::startService("Statusbar");
} else {
LOG_E(TAG, "Statusbar service is not in Stopped state");
Expand Down
19 changes: 0 additions & 19 deletions Tactility/Source/service/ServiceInstance.cpp

This file was deleted.

29 changes: 0 additions & 29 deletions Tactility/Source/service/ServicePaths.cpp

This file was deleted.

Loading
Loading