forked from Avangelista/CowabungaLiteWindows
-
Notifications
You must be signed in to change notification settings - Fork 0
/
HomeScreenApps.cpp
172 lines (147 loc) · 6.63 KB
/
HomeScreenApps.cpp
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
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
#include "HomeScreenApps.h"
#include <iostream>
#include <libimobiledevice/libimobiledevice.h>
#include <libimobiledevice/sbservices.h>
#include <plist/plist.h>
#include "DeviceManager.h"
#include "qmessagebox.h"
void HomeScreenApps::scoutArray(plist_t array, std::unordered_map<std::string, std::unordered_map<std::string, std::variant<std::string, std::vector<char>, int>>>& apps, bool writePos, sbservices_client_t sbservice_t)
{
int num_items = plist_array_get_size(array);
for (int j = 0; j < num_items; j++)
{
plist_t dict = plist_array_get_item(array, j);
plist_t displayName = plist_dict_get_item(dict, "displayName");
if (displayName)
{
plist_t bundleIdentifier = plist_dict_get_item(dict, "bundleIdentifier");
plist_t displayIdentifier = plist_dict_get_item(dict, "displayIdentifier");
// Regular app
if (bundleIdentifier)
{
char *name = nullptr;
plist_get_string_val(displayName, &name);
char *bundle = nullptr;
plist_get_string_val(bundleIdentifier, &bundle);
apps[bundle]["name"] = std::string(name);
apps[bundle]["icon_position"] = writePos ? j : -1;
char* pngdata = nullptr;
uint64_t pngsize = 0;
sbservices_error_t sb_icon_err_code = sbservices_get_icon_pngdata(sbservice_t, bundle, &pngdata, &pngsize);
if (sb_icon_err_code == SBSERVICES_E_SUCCESS)
{
apps[bundle]["icon"] = std::vector<char>(pngdata, pngdata + pngsize);
}
}
// Themed app
else if (displayIdentifier)
{
char *identifier = nullptr;
plist_get_string_val(displayIdentifier, &identifier);
int prefix_len = strlen("Cowabunga_");
if (strncmp(identifier, "Cowabunga_", prefix_len) == 0) {
char bundle[256];
char name[256];
sscanf(identifier, "Cowabunga_%[^,],%[^\n]", bundle, name);
// apps[bundle]["name"] = std::string(name);
auto n = std::string(name);
if (n.substr(0, 3) == "b64")
{
std::string rest = n.substr(3); // Remove "b64" prefix
QByteArray base64Data(rest.c_str(), static_cast<int>(rest.length()));
QByteArray decodedData = QByteArray::fromBase64(base64Data);
apps[bundle]["name"] = decodedData.toStdString();
}
else
{
apps[bundle]["name"] = n;
}
char *themed_name = nullptr;
plist_get_string_val(displayName, &themed_name);
apps[bundle]["themed_name"] = std::string(themed_name);
apps[bundle]["themed_icon_position"] = writePos ? j : -1;
char* pngdata = nullptr;
uint64_t pngsize = 0;
sbservices_error_t sb_icon_err_code = sbservices_get_icon_pngdata(sbservice_t, identifier, &pngdata, &pngsize);
if (sb_icon_err_code == SBSERVICES_E_SUCCESS)
{
apps[bundle]["themed_icon"] = std::vector<char>(pngdata, pngdata + pngsize);
}
}
}
else
{
plist_t listType = plist_dict_get_item(dict, "listType");
if (listType)
{
char *type = nullptr;
plist_get_string_val(listType, &type);
// Folder
if (strcmp("folder", type) == 0)
{
plist_t iconLists = plist_dict_get_item(dict, "iconLists");
if (iconLists)
{
int size = plist_array_get_size(iconLists);
for (int i = 0; i < size; i++)
{
plist_t iconListsArray = plist_array_get_item(iconLists, i);
scoutArray(iconListsArray, apps, false, sbservice_t);
}
}
}
}
}
}
}
}
void HomeScreenApps::scoutAllApps(plist_t icon_state, std::unordered_map<std::string, std::unordered_map<std::string, std::variant<std::string, std::vector<char>, int>>>& apps, sbservices_client_t sbservice_t)
{
int size = plist_array_get_size(icon_state);
for (int i = 0; i < size; i++)
{
plist_t array = plist_array_get_item(icon_state, i);
HomeScreenApps::scoutArray(array, apps, true, sbservice_t);
}
}
std::unordered_map<std::string, std::unordered_map<std::string, std::variant<std::string, std::vector<char>, int>>> HomeScreenApps::getHomeScreenApps()
{
auto udid = DeviceManager::getInstance().getCurrentUUID();
if (!udid) {
return {};
}
idevice_error_t idevice_ret = IDEVICE_E_UNKNOWN_ERROR;
idevice_t device;
plist_t icon_state;
sbservices_client_t sbservice_t;
// Get device
idevice_ret = idevice_new(&device, udid->c_str());
if (idevice_ret != IDEVICE_E_SUCCESS)
{
std::cerr << "No device found with UDID " << *udid << std::endl;
return {};
}
// Get client
sbservices_error_t sb_client_err_code = sbservices_client_start_service(device, &sbservice_t, "iPhone");
if (sb_client_err_code != SBSERVICES_E_SUCCESS)
{
// possible itunes error!
QMessageBox::critical(nullptr, "Error", "Unable to read the list of apps from your device. Please make sure iTunes is installed on this PC and your device is unlocked.");
std::cerr << "Unable to create SpringBoard client: " << sb_client_err_code << std::endl;
return {};
}
// Get icon state
sbservices_error_t sb_icon_err_code = sbservices_get_icon_state(sbservice_t, &icon_state, "2");
if (sb_icon_err_code != SBSERVICES_E_SUCCESS)
{
std::cerr << "Unable to get icon state: " << sb_icon_err_code << std::endl;
}
auto apps = std::unordered_map<std::string, std::unordered_map<std::string, std::variant<std::string, std::vector<char>, int>>>();
HomeScreenApps::scoutAllApps(icon_state, apps, sbservice_t);
for (auto it = apps.begin(); it != apps.end(); ++it) {
auto bundle = it->first;
auto dict = it->second;
auto name = std::get<std::string>(dict["name"]);
}
return apps;
}