RNBServices.cpp revision 56b9f80df238c8be09d2b7441e9e71f7828bbd3a
1//===-- RNBServices.cpp -----------------------------------------*- C++ -*-===// 2// 3// The LLVM Compiler Infrastructure 4// 5// This file is distributed under the University of Illinois Open Source 6// License. See LICENSE.TXT for details. 7// 8//===----------------------------------------------------------------------===// 9// 10// Created by Christopher Friesen on 3/21/08. 11// 12//===----------------------------------------------------------------------===// 13 14#import "RNBServices.h" 15 16#import <CoreFoundation/CoreFoundation.h> 17#import <unistd.h> 18#import "DNBLog.h" 19#include "MacOSX/CFUtils.h" 20 21#ifdef WITH_SPRINGBOARD 22#import <SpringBoardServices/SpringBoardServices.h> 23#endif 24 25int 26ListApplications(std::string& plist, bool opt_runningApps, bool opt_debuggable) 27{ 28#ifdef WITH_SPRINGBOARD 29 int result = -1; 30 31 CFAllocatorRef alloc = kCFAllocatorDefault; 32 33 // Create a mutable array that we can populate. Specify zero so it can be of any size. 34 CFReleaser<CFMutableArrayRef> plistMutableArray (::CFArrayCreateMutable (alloc, 0, &kCFTypeArrayCallBacks)); 35 36 CFReleaser<CFStringRef> sbsFrontAppID (::SBSCopyFrontmostApplicationDisplayIdentifier ()); 37 CFReleaser<CFArrayRef> sbsAppIDs (::SBSCopyApplicationDisplayIdentifiers (opt_runningApps, opt_debuggable)); 38 39 // Need to check the return value from SBSCopyApplicationDisplayIdentifiers. 40 CFIndex count = sbsAppIDs.get() ? ::CFArrayGetCount (sbsAppIDs.get()) : 0; 41 CFIndex i = 0; 42 for (i = 0; i < count; i++) 43 { 44 CFStringRef displayIdentifier = (CFStringRef)::CFArrayGetValueAtIndex (sbsAppIDs.get(), i); 45 46 // Create a new mutable dictionary for each application 47 CFReleaser<CFMutableDictionaryRef> appInfoDict (::CFDictionaryCreateMutable (alloc, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks)); 48 49 // Get the process id for the app (if there is one) 50 pid_t pid = INVALID_NUB_PROCESS; 51 if (::SBSProcessIDForDisplayIdentifier ((CFStringRef)displayIdentifier, &pid) == true) 52 { 53 CFReleaser<CFNumberRef> pidCFNumber (::CFNumberCreate (alloc, kCFNumberSInt32Type, &pid)); 54 ::CFDictionarySetValue (appInfoDict.get(), DTSERVICES_APP_PID_KEY, pidCFNumber.get()); 55 } 56 57 // Set the a boolean to indicate if this is the front most 58 if (sbsFrontAppID.get() && displayIdentifier && (::CFStringCompare (sbsFrontAppID.get(), displayIdentifier, 0) == kCFCompareEqualTo)) 59 ::CFDictionarySetValue (appInfoDict.get(), DTSERVICES_APP_FRONTMOST_KEY, kCFBooleanTrue); 60 else 61 ::CFDictionarySetValue (appInfoDict.get(), DTSERVICES_APP_FRONTMOST_KEY, kCFBooleanFalse); 62 63 64 CFReleaser<CFStringRef> executablePath (::SBSCopyExecutablePathForDisplayIdentifier (displayIdentifier)); 65 if (executablePath.get() != NULL) 66 { 67 ::CFDictionarySetValue (appInfoDict.get(), DTSERVICES_APP_PATH_KEY, executablePath.get()); 68 } 69 70 CFReleaser<CFStringRef> iconImagePath (::SBSCopyIconImagePathForDisplayIdentifier (displayIdentifier)) ; 71 if (iconImagePath.get() != NULL) 72 { 73 ::CFDictionarySetValue (appInfoDict.get(), DTSERVICES_APP_ICON_PATH_KEY, iconImagePath.get()); 74 } 75 76 CFReleaser<CFStringRef> localizedDisplayName (::SBSCopyLocalizedApplicationNameForDisplayIdentifier (displayIdentifier)); 77 if (localizedDisplayName.get() != NULL) 78 { 79 ::CFDictionarySetValue (appInfoDict.get(), DTSERVICES_APP_DISPLAY_NAME_KEY, localizedDisplayName.get()); 80 } 81 82 // Append the application info to the plist array 83 ::CFArrayAppendValue (plistMutableArray.get(), appInfoDict.get()); 84 } 85 86 CFReleaser<CFDataRef> plistData (::CFPropertyListCreateXMLData (alloc, plistMutableArray.get())); 87 88 // write plist to service port 89 if (plistData.get() != NULL) 90 { 91 CFIndex size = ::CFDataGetLength (plistData.get()); 92 const UInt8 *bytes = ::CFDataGetBytePtr (plistData.get()); 93 if (bytes != NULL && size > 0) 94 { 95 plist.assign((char *)bytes, size); 96 return 0; // Success 97 } 98 else 99 { 100 DNBLogError("empty application property list."); 101 result = -2; 102 } 103 } 104 else 105 { 106 DNBLogError("serializing task list."); 107 result = -3; 108 } 109 110 return result; 111#else 112 // TODO: list all current processes 113 DNBLogError("SBS doesn't support getting application list."); 114 return -1; 115#endif 116} 117 118 119bool 120IsSBProcess (nub_process_t pid) 121{ 122#ifdef WITH_SPRINGBOARD 123 CFReleaser<CFArrayRef> appIdsForPID (::SBSCopyDisplayIdentifiersForProcessID(pid)); 124 return appIdsForPID.get() != NULL; 125#else 126 return false; 127#endif 128} 129 130