mirror of
https://github.com/google/pebble.git
synced 2025-03-19 18:41:21 +00:00
256 lines
6.8 KiB
C
256 lines
6.8 KiB
C
|
/*
|
||
|
* Copyright 2024 Google LLC
|
||
|
*
|
||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||
|
* you may not use this file except in compliance with the License.
|
||
|
* You may obtain a copy of the License at
|
||
|
*
|
||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||
|
*
|
||
|
* Unless required by applicable law or agreed to in writing, software
|
||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||
|
* See the License for the specific language governing permissions and
|
||
|
* limitations under the License.
|
||
|
*/
|
||
|
|
||
|
#include "clar.h"
|
||
|
|
||
|
//#include "comm/remote.h"
|
||
|
#include "process_management/app_run_state.h"
|
||
|
#include "services/common/comm_session/protocol.h"
|
||
|
#include "system/passert.h"
|
||
|
|
||
|
#include "util/attributes.h"
|
||
|
#include "util/list.h"
|
||
|
|
||
|
#include <stdlib.h>
|
||
|
|
||
|
// Stubs
|
||
|
///////////////////////////////////////
|
||
|
#include "stubs_logging.h"
|
||
|
#include "stubs_passert.h"
|
||
|
#include "stubs_pbl_malloc.h"
|
||
|
#include "stubs_rand_ptr.h"
|
||
|
|
||
|
// Fakes
|
||
|
///////////////////////////////////////
|
||
|
#include "fake_app_manager.h"
|
||
|
#include "fake_pebble_tasks.h"
|
||
|
|
||
|
// Structures
|
||
|
///////////////////////////////////////
|
||
|
typedef struct PACKED {
|
||
|
uint8_t command;
|
||
|
Uuid uuid;
|
||
|
} AppStateMessage;
|
||
|
|
||
|
struct CommSession {
|
||
|
};
|
||
|
|
||
|
typedef struct PACKED {
|
||
|
AppState state:8;
|
||
|
Uuid uuid;
|
||
|
} AppRunState;
|
||
|
|
||
|
// Globals
|
||
|
///////////////////////////////////////
|
||
|
CommSession *s_session = NULL;
|
||
|
|
||
|
static uint8_t s_launcher_deprecated_messages = 0;
|
||
|
|
||
|
static uint8_t s_app_run_state_messages = 0;
|
||
|
|
||
|
static uint8_t s_free_count = 0;
|
||
|
|
||
|
static uint8_t s_malloc_count = 0;
|
||
|
|
||
|
static void *s_ptr = NULL;
|
||
|
|
||
|
static uint8_t s_app_state;
|
||
|
|
||
|
static uint64_t s_flags = 0;
|
||
|
|
||
|
static const Uuid s_app_uuid = {
|
||
|
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5
|
||
|
};
|
||
|
|
||
|
// Helpers
|
||
|
///////////////////////////////////////
|
||
|
static void prv_set_remote_active(void) {
|
||
|
static const int deadbeef = 0xdeadbeef;
|
||
|
s_session = (void*)&deadbeef;
|
||
|
s_flags = 0;
|
||
|
}
|
||
|
|
||
|
static void prv_set_expected(AppState app_state) {
|
||
|
s_app_state = app_state;
|
||
|
}
|
||
|
|
||
|
static void prv_set_remote_capability(CommSessionCapability c) {
|
||
|
s_flags |= c;
|
||
|
}
|
||
|
|
||
|
bool comm_session_has_capability(CommSession *session, CommSessionCapability c) {
|
||
|
return (s_flags & c) != 0;
|
||
|
}
|
||
|
|
||
|
void app_install_unmark_prioritized(const Uuid *uuid) {
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
bool app_install_is_app_running(AppInstallId id) {
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
void app_install_mark_prioritized(AppInstallId install_id, bool can_expire) {
|
||
|
}
|
||
|
|
||
|
bool system_task_add_callback(void(*cb)(void *data), void *data) {
|
||
|
cb(data);
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
status_t app_cache_app_launched(AppInstallId id) {
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
void app_manager_put_launch_app_event(const AppLaunchEventConfig *config) {
|
||
|
app_run_state_send_update(&app_manager_get_current_app_md()->uuid, RUNNING);
|
||
|
}
|
||
|
|
||
|
void process_manager_put_kill_process_event(PebbleTask task, bool gracefully) {
|
||
|
app_run_state_send_update(&app_manager_get_current_app_md()->uuid, NOT_RUNNING);
|
||
|
}
|
||
|
|
||
|
CommSession *comm_session_get_system_session(void) {
|
||
|
return s_session;
|
||
|
}
|
||
|
|
||
|
void launcher_app_message_send_app_state_deprecated(const Uuid *uuid, bool running) {
|
||
|
s_launcher_deprecated_messages++;
|
||
|
cl_assert(running == (s_app_state == RUNNING ? true : false));
|
||
|
}
|
||
|
|
||
|
bool comm_session_send_data(CommSession *session, uint16_t endpoint_id,
|
||
|
const uint8_t *data, size_t length, uint32_t timeout_ms) {
|
||
|
AppRunState *state = (AppRunState*)data;
|
||
|
s_app_run_state_messages++;
|
||
|
cl_assert(state->state == s_app_state);
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
void bt_lock(void) {
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
void bt_unlock(void) {
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
|
||
|
// Tests
|
||
|
///////////////////////////////////////
|
||
|
|
||
|
extern void app_run_state_protocol_msg_callback(CommSession*, const uint8_t*, size_t);
|
||
|
|
||
|
void test_app_run_state__initialize(void) {
|
||
|
s_launcher_deprecated_messages = 0;
|
||
|
s_app_run_state_messages = 0;
|
||
|
s_session = NULL;
|
||
|
s_flags = 0;
|
||
|
|
||
|
s_malloc_count = 0;
|
||
|
s_free_count = 0;
|
||
|
|
||
|
stub_app_init();
|
||
|
}
|
||
|
|
||
|
|
||
|
void test_app_run_state__cleanup(void) {
|
||
|
// Always ensure that after any test, all malloc'd data has been freed
|
||
|
cl_assert_equal_i(s_malloc_count, s_free_count);
|
||
|
}
|
||
|
|
||
|
|
||
|
void test_app_run_state__send_update(void) {
|
||
|
// Tests that when app_run_state_send_update is called, that the proper
|
||
|
// callback is triggered depending on the device / version
|
||
|
app_run_state_send_update(&s_app_uuid, RUNNING);
|
||
|
|
||
|
// When no remote is set, this should just not run
|
||
|
cl_assert_equal_i(s_launcher_deprecated_messages, 0);
|
||
|
|
||
|
// Set the remote as being active
|
||
|
prv_set_remote_active();
|
||
|
stub_app_set_uuid(s_app_uuid);
|
||
|
|
||
|
// When app_run_state is not supported, should use launcher_app_message
|
||
|
prv_set_expected(RUNNING);
|
||
|
app_run_state_send_update(&s_app_uuid, RUNNING);
|
||
|
cl_assert_equal_i(s_launcher_deprecated_messages, 1);
|
||
|
|
||
|
// When app_run_state is supported, should use app_run_state
|
||
|
prv_set_expected(NOT_RUNNING);
|
||
|
prv_set_remote_capability(CommSessionRunState);
|
||
|
app_run_state_send_update(&s_app_uuid, NOT_RUNNING);
|
||
|
cl_assert_equal_i(s_launcher_deprecated_messages, 1);
|
||
|
cl_assert_equal_i(s_app_run_state_messages, 1);
|
||
|
|
||
|
// Changing the remote should change the flags and use launcher_app_message
|
||
|
// if app_run_state not supported
|
||
|
prv_set_remote_active();
|
||
|
app_run_state_send_update(&s_app_uuid, NOT_RUNNING);
|
||
|
cl_assert_equal_i(s_launcher_deprecated_messages, 2);
|
||
|
cl_assert_equal_i(s_app_run_state_messages, 1);
|
||
|
}
|
||
|
|
||
|
void test_app_run_state__protocol_msg_callback(void) {
|
||
|
// Tests app_run_state_procotol_msg_callback which should take data
|
||
|
// from a source and perform the appropriate command
|
||
|
prv_set_remote_active();
|
||
|
prv_set_remote_capability(CommSessionRunState);
|
||
|
stub_app_set_uuid(s_app_uuid);
|
||
|
stub_app_set_install_id(1337);
|
||
|
|
||
|
CommSession session;
|
||
|
AppStateMessage msg;
|
||
|
|
||
|
msg.command = APP_RUN_STATE_INVALID_COMMAND;
|
||
|
memcpy(&msg.uuid, &s_app_uuid, sizeof(s_app_uuid));
|
||
|
|
||
|
app_run_state_protocol_msg_callback(&session, (uint8_t*)&msg, sizeof(msg));
|
||
|
|
||
|
// This should be a noop since the key is invalid
|
||
|
cl_assert_equal_i(s_launcher_deprecated_messages, 0);
|
||
|
cl_assert_equal_i(s_app_run_state_messages, 0);
|
||
|
|
||
|
AppRunStateCommand commands[] = {
|
||
|
APP_RUN_STATE_INVALID_COMMAND,
|
||
|
APP_RUN_STATE_RUN_COMMAND,
|
||
|
APP_RUN_STATE_STOP_COMMAND,
|
||
|
APP_RUN_STATE_STATUS_COMMAND
|
||
|
};
|
||
|
|
||
|
AppState expected[] = {
|
||
|
RUNNING,
|
||
|
RUNNING,
|
||
|
NOT_RUNNING,
|
||
|
RUNNING
|
||
|
};
|
||
|
|
||
|
// Since our version is >= 2.2, this should use the new endpoint
|
||
|
// And check that we're getting back the right state
|
||
|
for (int msg_count = 0; msg_count < 4; msg_count++) {
|
||
|
msg.command = commands[msg_count];
|
||
|
prv_set_expected(expected[msg_count]);
|
||
|
app_run_state_protocol_msg_callback(&session, (uint8_t*)&msg, sizeof(msg));
|
||
|
cl_assert_equal_i(s_launcher_deprecated_messages, 0);
|
||
|
cl_assert_equal_i(s_app_run_state_messages, msg_count);
|
||
|
}
|
||
|
|
||
|
app_run_state_protocol_msg_callback(NULL, (uint8_t*)&msg, sizeof(msg));
|
||
|
|
||
|
cl_assert_equal_i(s_launcher_deprecated_messages, 1);
|
||
|
}
|