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
|
//===-- RNBServices.cpp -----------------------------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// Created by Christopher Friesen on 3/21/08.
//
//===----------------------------------------------------------------------===//
#import "RNBServices.h"
#import <CoreFoundation/CoreFoundation.h>
#import <unistd.h>
#import "DNBLog.h"
#include "MacOSX/CFUtils.h"
#if defined (__arm__)
#import <SpringBoardServices/SpringBoardServices.h>
#endif
int
ListApplications(std::string& plist, bool opt_runningApps, bool opt_debuggable)
{
#if defined (__arm__)
int result = -1;
CFAllocatorRef alloc = kCFAllocatorDefault;
// Create a mutable array that we can populate. Specify zero so it can be of any size.
CFReleaser<CFMutableArrayRef> plistMutableArray (::CFArrayCreateMutable (alloc, 0, &kCFTypeArrayCallBacks));
CFReleaser<CFStringRef> sbsFrontAppID (::SBSCopyFrontmostApplicationDisplayIdentifier ());
CFReleaser<CFArrayRef> sbsAppIDs (::SBSCopyApplicationDisplayIdentifiers (opt_runningApps, opt_debuggable));
CFIndex count = ::CFArrayGetCount (sbsAppIDs.get());
CFIndex i = 0;
for (i = 0; i < count; i++)
{
CFStringRef displayIdentifier = (CFStringRef)::CFArrayGetValueAtIndex (sbsAppIDs.get(), i);
// Create a new mutable dictionary for each application
CFReleaser<CFMutableDictionaryRef> appInfoDict (::CFDictionaryCreateMutable (alloc, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks));
// Get the process id for the app (if there is one)
pid_t pid = INVALID_NUB_PROCESS;
if (::SBSProcessIDForDisplayIdentifier ((CFStringRef)displayIdentifier, &pid) == true)
{
CFReleaser<CFNumberRef> pidCFNumber (::CFNumberCreate (alloc, kCFNumberSInt32Type, &pid));
::CFDictionarySetValue (appInfoDict.get(), DTSERVICES_APP_PID_KEY, pidCFNumber.get());
}
// Set the a boolean to indicate if this is the front most
if (sbsFrontAppID.get() && displayIdentifier && (::CFStringCompare (sbsFrontAppID.get(), displayIdentifier, 0) == kCFCompareEqualTo))
::CFDictionarySetValue (appInfoDict.get(), DTSERVICES_APP_FRONTMOST_KEY, kCFBooleanTrue);
else
::CFDictionarySetValue (appInfoDict.get(), DTSERVICES_APP_FRONTMOST_KEY, kCFBooleanFalse);
CFReleaser<CFStringRef> executablePath (::SBSCopyExecutablePathForDisplayIdentifier (displayIdentifier));
if (executablePath.get() != NULL)
{
::CFDictionarySetValue (appInfoDict.get(), DTSERVICES_APP_PATH_KEY, executablePath.get());
}
CFReleaser<CFStringRef> iconImagePath (::SBSCopyIconImagePathForDisplayIdentifier (displayIdentifier)) ;
if (iconImagePath.get() != NULL)
{
::CFDictionarySetValue (appInfoDict.get(), DTSERVICES_APP_ICON_PATH_KEY, iconImagePath.get());
}
CFReleaser<CFStringRef> localizedDisplayName (::SBSCopyLocalizedApplicationNameForDisplayIdentifier (displayIdentifier));
if (localizedDisplayName.get() != NULL)
{
::CFDictionarySetValue (appInfoDict.get(), DTSERVICES_APP_DISPLAY_NAME_KEY, localizedDisplayName.get());
}
// Append the application info to the plist array
::CFArrayAppendValue (plistMutableArray.get(), appInfoDict.get());
}
CFReleaser<CFDataRef> plistData (::CFPropertyListCreateXMLData (alloc, plistMutableArray.get()));
// write plist to service port
if (plistData.get() != NULL)
{
CFIndex size = ::CFDataGetLength (plistData.get());
const UInt8 *bytes = ::CFDataGetBytePtr (plistData.get());
if (bytes != NULL && size > 0)
{
plist.assign((char *)bytes, size);
return 0; // Success
}
else
{
DNBLogError("empty application property list.");
result = -2;
}
}
else
{
DNBLogError("serializing task list.");
result = -3;
}
return result;
#else
// TODO: list all current processes
DNBLogError("SBS doesn't support getting application list.");
return -1;
#endif
}
bool
IsSBProcess (nub_process_t pid)
{
#if defined (__arm__)
bool opt_runningApps = true;
bool opt_debuggable = false;
CFReleaser<CFArrayRef> sbsAppIDs (::SBSCopyApplicationDisplayIdentifiers (opt_runningApps, opt_debuggable));
if (sbsAppIDs.get() != NULL)
{
CFIndex count = ::CFArrayGetCount (sbsAppIDs.get());
CFIndex i = 0;
for (i = 0; i < count; i++)
{
CFStringRef displayIdentifier = (CFStringRef)::CFArrayGetValueAtIndex (sbsAppIDs.get(), i);
// Get the process id for the app (if there is one)
pid_t sbs_pid = INVALID_NUB_PROCESS;
if (::SBSProcessIDForDisplayIdentifier ((CFStringRef)displayIdentifier, &sbs_pid) == TRUE)
{
if (sbs_pid == pid)
return true;
}
}
}
#endif
return false;
}
|