1f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch/*
2f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch * libjingle
3f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch * Copyright 2007--2009, Google Inc.
4f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch *
5f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch * Redistribution and use in source and binary forms, with or without
6f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch * modification, are permitted provided that the following conditions are met:
7f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch *
8f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch *  1. Redistributions of source code must retain the above copyright notice,
9f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch *     this list of conditions and the following disclaimer.
10f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch *  2. Redistributions in binary form must reproduce the above copyright notice,
11f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch *     this list of conditions and the following disclaimer in the documentation
12f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch *     and/or other materials provided with the distribution.
13f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch *  3. The name of the author may not be used to endorse or promote products
14f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch *     derived from this software without specific prior written permission.
15f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch *
16f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
17f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
18f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
19f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
20f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
21f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
22f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
23f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
24f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
25f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch */
27f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
28f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch#include <sstream>
29f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
30f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch#include "talk/base/common.h"
31f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch#include "talk/base/logging.h"
32f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch#include "talk/base/macutils.h"
33f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch#include "talk/base/scoped_ptr.h"
34f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch#include "talk/base/stringutils.h"
35f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
36f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdochnamespace talk_base {
37f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
38f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch///////////////////////////////////////////////////////////////////////////////
39f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
40f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdochbool ToUtf8(const CFStringRef str16, std::string* str8) {
41f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  if ((NULL == str16) || (NULL == str8))
42f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch    return false;
43f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  size_t maxlen = CFStringGetMaximumSizeForEncoding(CFStringGetLength(str16),
44f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch                                                    kCFStringEncodingUTF8)
45f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch                  + 1;
46f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  scoped_array<char> buffer(new char[maxlen]);
47f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  if (!buffer.get()
48f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch      || !CFStringGetCString(str16, buffer.get(), maxlen,
49f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch                             kCFStringEncodingUTF8))
50f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch    return false;
51f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  str8->assign(buffer.get());
52f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  return true;
53f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch}
54f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
55f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdochbool ToUtf16(const std::string& str8, CFStringRef* str16) {
56f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  if (NULL == str16)
57f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch    return false;
58f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  *str16 = CFStringCreateWithBytes(kCFAllocatorDefault,
59f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch                                   reinterpret_cast<const UInt8*>(str8.data()),
60f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch                                   str8.length(), kCFStringEncodingUTF8,
61f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch                                   false);
62f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  return (NULL != *str16);
63f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch}
64f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
65f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdochvoid DecodeFourChar(UInt32 fc, std::string* out) {
66f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  std::stringstream ss;
67f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  ss << '\'';
68f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  bool printable = true;
69f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  for (int i = 3; i >= 0; --i) {
70f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch    char ch = (fc >> (8 * i)) & 0xFF;
71f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch    if (isprint(static_cast<unsigned char>(ch))) {
72f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch      ss << ch;
73f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch    } else {
74f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch      printable = false;
75f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch      break;
76f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch    }
77f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  }
78f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  if (printable) {
79f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch    ss << '\'';
80f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  } else {
81f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch    ss.str("");
82f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch    ss << "0x" << std::hex << fc;
83f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  }
84f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  out->append(ss.str());
85f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch}
86f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
87f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdochstd::string DecodeEvent(EventRef event) {
88f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  std::string str;
89f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  DecodeFourChar(::GetEventClass(event), &str);
90f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  str.push_back(':');
91f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  DecodeFourChar(::GetEventKind(event), &str);
92f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  return str;
93f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch}
94f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
95f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdochstatic bool GetGestalt(OSType ostype, int* value) {
96f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  ASSERT(NULL != value);
97f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  SInt32 native_value;
98f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  OSStatus result = Gestalt(ostype, &native_value);
99f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  if (noErr == result) {
100f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch    *value = native_value;
101f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch    return true;
102f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  }
103f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  std::string str;
104f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  DecodeFourChar(ostype, &str);
105f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  LOG_E(LS_ERROR, OS, result) << "Gestalt(" << str << ")";
106f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  return false;
107f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch}
108f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
109f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdochbool GetOSVersion(int* major, int* minor, int* bugfix) {
110f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  ASSERT(major && minor && bugfix);
111f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  if (!GetGestalt(gestaltSystemVersion, major))
112f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch    return false;
113f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  if (*major < 0x1040) {
114f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch    *bugfix = *major & 0xF;
115f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch    *minor = (*major >> 4) & 0xF;
116f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch    *major = (*major >> 8);
117f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch    return true;
118f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  }
119f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  return GetGestalt(gestaltSystemVersionMajor, major)
120f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch      && GetGestalt(gestaltSystemVersionMinor, minor)
121f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch      && GetGestalt(gestaltSystemVersionBugFix, bugfix);
122f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch}
123f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
124f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen MurdochMacOSVersionName GetOSVersionName() {
125f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  int major = 0, minor = 0, bugfix = 0;
126f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  if (!GetOSVersion(&major, &minor, &bugfix))
127f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch    return kMacOSUnknown;
128f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  if (major > 10)
129f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch    return kMacOSNewer;
130f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  if ((major < 10) || (minor < 3))
131f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch    return kMacOSOlder;
132f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  switch (minor) {
133f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch    case 3:
134f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch      return kMacOSPanther;
135f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch    case 4:
136f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch      return kMacOSTiger;
137f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch    case 5:
138f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch      return kMacOSLeopard;
139f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  }
140f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  return kMacOSNewer;
141f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch}
142f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
143f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdochbool GetQuickTimeVersion(std::string* out) {
144f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  int ver;
145f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  if (!GetGestalt(gestaltQuickTimeVersion, &ver))
146f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch    return false;
1474a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch
148f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  std::stringstream ss;
149f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  ss << std::hex << ver;
150f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  *out = ss.str();
151f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  return true;
152f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch}
153f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
1544a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdochbool RunAppleScript(const std::string& script) {
1554a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch  ComponentInstance component = NULL;
1564a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch  AEDesc script_desc;
1574a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch  AEDesc result_data;
1584a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch  OSStatus err;
1594a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch  OSAID script_id, result_id;
1604a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch
1614a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch  AECreateDesc(typeNull, NULL, 0, &script_desc);
1624a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch  AECreateDesc(typeNull, NULL, 0, &result_data);
1634a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch  script_id = kOSANullScript;
1644a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch  result_id = kOSANullScript;
1654a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch
1664a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch  component = OpenDefaultComponent(kOSAComponentType, typeAppleScript);
1674a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch  if (component == NULL) {
1684a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch    LOG(LS_ERROR) << "Failed opening Apple Script component";
1694a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch    return false;
1704a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch  }
1714a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch  err = AECreateDesc(typeUTF8Text, script.data(), script.size(), &script_desc);
1724a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch  if (err != noErr) {
1734a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch    CloseComponent(component);
1744a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch    LOG(LS_ERROR) << "Failed creating Apple Script description";
1754a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch    return false;
1764a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch  }
1774a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch
1784a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch  err = OSACompile(component, &script_desc, kOSAModeCanInteract, &script_id);
1794a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch  if (err != noErr) {
1804a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch    AEDisposeDesc(&script_desc);
1814a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch    if (script_id != kOSANullScript) {
1824a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch      OSADispose(component, script_id);
1834a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch    }
1844a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch    CloseComponent(component);
1854a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch    LOG(LS_ERROR) << "Error compiling Apple Script";
1864a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch    return false;
1874a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch  }
1884a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch
1894a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch  err = OSAExecute(component, script_id, kOSANullScript, kOSAModeCanInteract,
1904a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch		   &result_id);
1914a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch
1924a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch  if (err == errOSAScriptError) {
1934a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch    LOG(LS_ERROR) << "Error when executing Apple Script: " << script;
1944a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch    AECreateDesc(typeNull, NULL, 0, &result_data);
1954a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch    OSAScriptError(component, kOSAErrorMessage, typeChar, &result_data);
1964a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch    int len = AEGetDescDataSize(&result_data);
1974a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch    char* data = (char*) malloc(len);
1984a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch    if (data != NULL) {
1994a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch      err = AEGetDescData(&result_data, data, len);
2004a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch      LOG(LS_ERROR) << "Script error: " << data;
2014a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch    }
2024a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch    AEDisposeDesc(&script_desc);
2034a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch    AEDisposeDesc(&result_data);
2044a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch    return false;
2054a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch  }
2064a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch  AEDisposeDesc(&script_desc);
2074a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch  if (script_id != kOSANullScript) {
2084a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch    OSADispose(component, script_id);
2094a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch  }
2104a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch  if (result_id != kOSANullScript) {
2114a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch    OSADispose(component, result_id);
2124a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch  }
2134a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch  CloseComponent(component);
2144a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch  return true;
2154a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch}
2164a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch
2174a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch
218f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch///////////////////////////////////////////////////////////////////////////////
219f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
220f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch}  // namespace talk_base
221