1/* 2This file is part of Telegram Desktop, 3the official desktop application for the Telegram messaging service. 4 5For license and copyright information please follow this link: 6https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL 7*/ 8#include "platform/mac/file_bookmark_mac.h" 9 10#include "base/platform/mac/base_utilities_mac.h" 11#include "logs.h" 12 13#include <Cocoa/Cocoa.h> 14#include <CoreFoundation/CFURL.h> 15 16namespace Platform { 17namespace { 18 19#ifdef OS_MAC_STORE 20QMutex BookmarksMutex; 21#endif // OS_MAC_STORE 22 23} // namespace 24 25#ifdef OS_MAC_STORE 26struct FileBookmark::Data { 27 ~Data() { 28 if (url) [url release]; 29 } 30 NSURL *url = nil; 31 QString name; 32 QByteArray bookmark; 33 int counter = 0; 34}; 35#endif // OS_MAC_STORE 36 37FileBookmark::FileBookmark(const QByteArray &bookmark) { 38#ifdef OS_MAC_STORE 39 if (bookmark.isEmpty()) return; 40 41 BOOL isStale = NO; 42 NSError *error = nil; 43 NSURL *url = [NSURL URLByResolvingBookmarkData:bookmark.toNSData() options:NSURLBookmarkResolutionWithSecurityScope relativeToURL:nil bookmarkDataIsStale:&isStale error:&error]; 44 if (!url) return; 45 46 if ([url startAccessingSecurityScopedResource]) { 47 data = new Data(); 48 data->url = [url retain]; 49 data->name = NS2QString([url path]); 50 data->bookmark = bookmark; 51 [url stopAccessingSecurityScopedResource]; 52 } 53#endif // OS_MAC_STORE 54} 55 56bool FileBookmark::check() const { 57 if (enable()) { 58 disable(); 59 return true; 60 } 61 return false; 62} 63 64bool FileBookmark::enable() const { 65#ifndef OS_MAC_STORE 66 return true; 67#else // OS_MAC_STORE 68 if (!data) return false; 69 70 QMutexLocker lock(&BookmarksMutex); 71 if (data->counter > 0 || [data->url startAccessingSecurityScopedResource] == YES) { 72 ++data->counter; 73 return true; 74 } 75 return false; 76#endif // OS_MAC_STORE 77} 78 79void FileBookmark::disable() const { 80#ifdef OS_MAC_STORE 81 if (!data) return; 82 83 QMutexLocker lock(&BookmarksMutex); 84 if (data->counter > 0) { 85 --data->counter; 86 if (!data->counter) { 87 [data->url stopAccessingSecurityScopedResource]; 88 } 89 } 90#endif // OS_MAC_STORE 91} 92 93const QString &FileBookmark::name(const QString &original) const { 94#ifndef OS_MAC_STORE 95 return original; 96#else // OS_MAC_STORE 97 return (data && !data->name.isEmpty()) ? data->name : original; 98#endif // OS_MAC_STORE 99} 100 101QByteArray FileBookmark::bookmark() const { 102#ifndef OS_MAC_STORE 103 return QByteArray(); 104#else // OS_MAC_STORE 105 return data ? data->bookmark : QByteArray(); 106#endif // OS_MAC_STORE 107} 108 109FileBookmark::~FileBookmark() { 110#ifdef OS_MAC_STORE 111 if (data && data->counter > 0) { 112 LOG(("Did not disable() bookmark, counter: %1").arg(data->counter)); 113 [data->url stopAccessingSecurityScopedResource]; 114 } 115#endif // OS_MAC_STORE 116} 117 118QByteArray PathBookmark(const QString &path) { 119#ifndef OS_MAC_STORE 120 return QByteArray(); 121#else // OS_MAC_STORE 122 NSURL *url = [NSURL fileURLWithPath:[NSString stringWithUTF8String:path.toUtf8().constData()]]; 123 if (!url) return QByteArray(); 124 125 NSError *error = nil; 126 NSData *data = [url bookmarkDataWithOptions:(NSURLBookmarkCreationWithSecurityScope | NSURLBookmarkCreationSecurityScopeAllowOnlyReadAccess) includingResourceValuesForKeys:nil relativeToURL:nil error:&error]; 127 return data ? QByteArray::fromNSData(data) : QByteArray(); 128#endif // OS_MAC_STORE 129} 130 131} // namespace Platform 132