Mechanical rename of base::debug -> base::trace_event for /content
[chromium-blink-merge.git] / chrome / browser / platform_util_mac.mm
blob15622f16ca3a51c53d94ca47adeac73e7be62609
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "chrome/browser/platform_util.h"
7 #include <Carbon/Carbon.h>
8 #import <Cocoa/Cocoa.h>
9 #include <CoreServices/CoreServices.h>
11 #include "base/files/file_path.h"
12 #include "base/logging.h"
13 #include "base/mac/mac_logging.h"
14 #import "base/mac/mac_util.h"
15 #import "base/mac/sdk_forward_declarations.h"
16 #include "base/mac/scoped_aedesc.h"
17 #include "base/strings/sys_string_conversions.h"
18 #include "url/gurl.h"
20 namespace platform_util {
22 void ShowItemInFolder(Profile* profile, const base::FilePath& full_path) {
23   DCHECK([NSThread isMainThread]);
24   NSString* path_string = base::SysUTF8ToNSString(full_path.value());
25   if (!path_string || ![[NSWorkspace sharedWorkspace] selectFile:path_string
26                                         inFileViewerRootedAtPath:nil])
27     LOG(WARNING) << "NSWorkspace failed to select file " << full_path.value();
30 void OpenItem(Profile* profile, const base::FilePath& full_path) {
31   DCHECK([NSThread isMainThread]);
32   NSString* path_string = base::SysUTF8ToNSString(full_path.value());
33   if (!path_string)
34     return;
36   // On Mavericks or later, NSWorkspaceLaunchWithErrorPresentation will
37   // properly handle Finder activation for quarantined files
38   // (http://crbug.com/32921) and unassociated file types
39   // (http://crbug.com/50263).
40   if (base::mac::IsOSMavericksOrLater()) {
41     NSURL* url = [NSURL fileURLWithPath:path_string];
42     if (!url)
43       return;
45     const NSWorkspaceLaunchOptions launch_options =
46         NSWorkspaceLaunchAsync | NSWorkspaceLaunchWithErrorPresentation;
47     [[NSWorkspace sharedWorkspace] openURLs:@[ url ]
48                     withAppBundleIdentifier:nil
49                                     options:launch_options
50              additionalEventParamDescriptor:nil
51                           launchIdentifiers:NULL];
52     return;
53   }
55   // On older OSes, both LaunchServices and NSWorkspace will fail silently for
56   // the two cases described above. On those platforms, use an AppleEvent to
57   // instruct the Finder to open the file.
59   // Create the target of this AppleEvent, the Finder.
60   base::mac::ScopedAEDesc<AEAddressDesc> address;
61   const OSType finderCreatorCode = 'MACS';
62   OSErr status = AECreateDesc(typeApplSignature,  // type
63                               &finderCreatorCode,  // data
64                               sizeof(finderCreatorCode),  // dataSize
65                               address.OutPointer());  // result
66   if (status != noErr) {
67     OSSTATUS_LOG(WARNING, status) << "Could not create OpenItem() AE target";
68     return;
69   }
71   // Build the AppleEvent data structure that instructs Finder to open files.
72   base::mac::ScopedAEDesc<AppleEvent> theEvent;
73   status = AECreateAppleEvent(kCoreEventClass,  // theAEEventClass
74                               kAEOpenDocuments,  // theAEEventID
75                               address,  // target
76                               kAutoGenerateReturnID,  // returnID
77                               kAnyTransactionID,  // transactionID
78                               theEvent.OutPointer());  // result
79   if (status != noErr) {
80     OSSTATUS_LOG(WARNING, status) << "Could not create OpenItem() AE event";
81     return;
82   }
84   // Create the list of files (only ever one) to open.
85   base::mac::ScopedAEDesc<AEDescList> fileList;
86   status = AECreateList(NULL,  // factoringPtr
87                         0,  // factoredSize
88                         false,  // isRecord
89                         fileList.OutPointer());  // resultList
90   if (status != noErr) {
91     OSSTATUS_LOG(WARNING, status) << "Could not create OpenItem() AE file list";
92     return;
93   }
95   // Add the single path to the file list.  C-style cast to avoid both a
96   // static_cast and a const_cast to get across the toll-free bridge.
97   CFURLRef pathURLRef = (CFURLRef)[NSURL fileURLWithPath:path_string];
98   FSRef pathRef;
99   if (CFURLGetFSRef(pathURLRef, &pathRef)) {
100     status = AEPutPtr(fileList.OutPointer(),  // theAEDescList
101                       0,  // index
102                       typeFSRef,  // typeCode
103                       &pathRef,  // dataPtr
104                       sizeof(pathRef));  // dataSize
105     if (status != noErr) {
106       OSSTATUS_LOG(WARNING, status)
107           << "Could not add file path to AE list in OpenItem()";
108       return;
109     }
110   } else {
111     LOG(WARNING) << "Could not get FSRef for path URL in OpenItem()";
112     return;
113   }
115   // Attach the file list to the AppleEvent.
116   status = AEPutParamDesc(theEvent.OutPointer(),  // theAppleEvent
117                           keyDirectObject,  // theAEKeyword
118                           fileList);  // theAEDesc
119   if (status != noErr) {
120     OSSTATUS_LOG(WARNING, status)
121         << "Could not put the AE file list the path in OpenItem()";
122     return;
123   }
125   // Send the actual event.  Do not care about the reply.
126   base::mac::ScopedAEDesc<AppleEvent> reply;
127   status = AESend(theEvent,  // theAppleEvent
128                   reply.OutPointer(),  // reply
129                   kAENoReply + kAEAlwaysInteract,  // sendMode
130                   kAENormalPriority,  // sendPriority
131                   kAEDefaultTimeout,  // timeOutInTicks
132                   NULL, // idleProc
133                   NULL);  // filterProc
134   if (status != noErr) {
135     OSSTATUS_LOG(WARNING, status)
136         << "Could not send AE to Finder in OpenItem()";
137   }
140 void OpenExternal(Profile* profile, const GURL& url) {
141   DCHECK([NSThread isMainThread]);
142   NSString* url_string = base::SysUTF8ToNSString(url.spec());
143   NSURL* ns_url = [NSURL URLWithString:url_string];
144   if (!ns_url || ![[NSWorkspace sharedWorkspace] openURL:ns_url])
145     LOG(WARNING) << "NSWorkspace failed to open URL " << url;
148 gfx::NativeWindow GetTopLevel(gfx::NativeView view) {
149   return [view window];
152 gfx::NativeView GetViewForWindow(gfx::NativeWindow window) {
153   DCHECK(window);
154   DCHECK([window contentView]);
155   return [window contentView];
158 gfx::NativeView GetParent(gfx::NativeView view) {
159   return nil;
162 bool IsWindowActive(gfx::NativeWindow window) {
163   return [window isKeyWindow] || [window isMainWindow];
166 void ActivateWindow(gfx::NativeWindow window) {
167   [window makeKeyAndOrderFront:nil];
170 bool IsVisible(gfx::NativeView view) {
171   // A reasonable approximation of how you'd expect this to behave.
172   return (view &&
173           ![view isHiddenOrHasHiddenAncestor] &&
174           [view window] &&
175           [[view window] isVisible]);
178 bool IsSwipeTrackingFromScrollEventsEnabled() {
179   SEL selector = @selector(isSwipeTrackingFromScrollEventsEnabled);
180   return [NSEvent respondsToSelector:selector]
181       && [NSEvent performSelector:selector];
184 }  // namespace platform_util