1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
|
// SPDX-FileCopyrightText: Copyright 2025 citron Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
#include <map>
#include <mutex>
#include "common/logging/log.h"
#include "core/hle/service/nim/nim_utils.h"
namespace Service::NIM::nn::nim {
// Simple implementation to track installation tasks
namespace {
std::mutex g_task_mutex;
std::map<u64, Task> g_tasks;
u64 g_next_task_id = 1;
bool g_service_available = true; // Default to true for emulation
}
bool IsServiceAvailable() {
std::lock_guard lock(g_task_mutex);
return g_service_available;
}
u64 CreateInstallTask(u64 application_id) {
std::lock_guard lock(g_task_mutex);
if (!g_service_available) {
LOG_WARNING(Service_NIM, "Installation task creation attempted but service is not available");
return 0;
}
u64 task_id = g_next_task_id++;
Task task{
.task_id = task_id,
.progress = {
.downloaded_bytes = 0,
.total_bytes = 1'000'000'000, // Fake 1GB download size
.status = TaskStatus::None
}
};
g_tasks[task_id] = task;
LOG_INFO(Service_NIM, "Installation task created for application 0x{:016X} with ID: {}",
application_id, task_id);
return task_id;
}
TaskProgress GetTaskProgress(u64 task_id) {
std::lock_guard lock(g_task_mutex);
auto it = g_tasks.find(task_id);
if (it == g_tasks.end()) {
LOG_ERROR(Service_NIM, "Tried to get progress for invalid task ID: {}", task_id);
return {0, 0, TaskStatus::Failed};
}
// If task is in download state, simulate progress
if (it->second.progress.status == TaskStatus::Downloading) {
// Simulate download progress (add 10% of total size)
auto& progress = it->second.progress;
const u64 increment = progress.total_bytes / 10;
progress.downloaded_bytes += increment;
if (progress.downloaded_bytes >= progress.total_bytes) {
progress.downloaded_bytes = progress.total_bytes;
progress.status = TaskStatus::Installing;
LOG_INFO(Service_NIM, "Task ID {} download complete, now installing", task_id);
}
} else if (it->second.progress.status == TaskStatus::Installing) {
// Simulate installation completion
it->second.progress.status = TaskStatus::Complete;
LOG_INFO(Service_NIM, "Task ID {} installation complete", task_id);
}
return it->second.progress;
}
bool StartInstallTask(u64 task_id) {
std::lock_guard lock(g_task_mutex);
auto it = g_tasks.find(task_id);
if (it == g_tasks.end()) {
LOG_ERROR(Service_NIM, "Tried to start invalid task ID: {}", task_id);
return false;
}
if (it->second.progress.status != TaskStatus::None &&
it->second.progress.status != TaskStatus::Pending) {
LOG_WARNING(Service_NIM, "Tried to start task ID {} which is already in progress", task_id);
return false;
}
it->second.progress.status = TaskStatus::Downloading;
LOG_INFO(Service_NIM, "Started installation task ID: {}", task_id);
return true;
}
bool CancelInstallTask(u64 task_id) {
std::lock_guard lock(g_task_mutex);
auto it = g_tasks.find(task_id);
if (it == g_tasks.end()) {
LOG_ERROR(Service_NIM, "Tried to cancel invalid task ID: {}", task_id);
return false;
}
if (it->second.progress.status == TaskStatus::Complete ||
it->second.progress.status == TaskStatus::Failed ||
it->second.progress.status == TaskStatus::Canceled) {
LOG_WARNING(Service_NIM, "Tried to cancel task ID {} which is already in a final state", task_id);
return false;
}
it->second.progress.status = TaskStatus::Canceled;
LOG_INFO(Service_NIM, "Canceled installation task ID: {}", task_id);
return true;
}
} // namespace Service::NIM::nn::nim
|