src/systeminfo/qsysteminfo_mac.mm
changeset 0 876b1a06bc25
equal deleted inserted replaced
-1:000000000000 0:876b1a06bc25
       
     1 /****************************************************************************
       
     2 **
       
     3 ** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
       
     4 ** All rights reserved.
       
     5 ** Contact: Nokia Corporation (qt-info@nokia.com)
       
     6 **
       
     7 ** This file is part of the Qt Mobility Components.
       
     8 **
       
     9 ** $QT_BEGIN_LICENSE:LGPL$
       
    10 ** No Commercial Usage
       
    11 ** This file contains pre-release code and may not be distributed.
       
    12 ** You may use this file in accordance with the terms and conditions
       
    13 ** contained in the Technology Preview License Agreement accompanying
       
    14 ** this package.
       
    15 **
       
    16 ** GNU Lesser General Public License Usage
       
    17 ** Alternatively, this file may be used under the terms of the GNU Lesser
       
    18 ** General Public License version 2.1 as published by the Free Software
       
    19 ** Foundation and appearing in the file LICENSE.LGPL included in the
       
    20 ** packaging of this file.  Please review the following information to
       
    21 ** ensure the GNU Lesser General Public License version 2.1 requirements
       
    22 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
       
    23 **
       
    24 ** In addition, as a special exception, Nokia gives you certain additional
       
    25 ** rights.  These rights are described in the Nokia Qt LGPL Exception
       
    26 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
       
    27 **
       
    28 ** If you have questions regarding the use of this file, please contact
       
    29 ** Nokia at qt-info@nokia.com.
       
    30 **
       
    31 **
       
    32 **
       
    33 **
       
    34 **
       
    35 **
       
    36 **
       
    37 **
       
    38 ** $QT_END_LICENSE$
       
    39 **
       
    40 ****************************************************************************/
       
    41 #include "qsysteminfo.h"
       
    42 #include "qsysteminfo_mac_p.h"
       
    43 
       
    44 #include <QStringList>
       
    45 #include <QSize>
       
    46 #include <QFile>
       
    47 #include <QTextStream>
       
    48 #include <QLocale>
       
    49 #include <QLibraryInfo>
       
    50 #include <QApplication>
       
    51 #include <QDesktopWidget>
       
    52 #include <QDebug>
       
    53 #include <QSettings>
       
    54 #include <QSysInfo>
       
    55 #include <QNetworkInterface>
       
    56 #include <QList>
       
    57 #include <QSettings>
       
    58 #include <QDir>
       
    59 #include <QNetworkInterface>
       
    60 #include <QString>
       
    61 #include <QHostInfo>
       
    62 
       
    63 #include <locale.h>
       
    64 
       
    65 #include <IOBluetooth/IOBluetooth.h>
       
    66 
       
    67 #include <SystemConfiguration/SystemConfiguration.h>
       
    68 #include <CoreFoundation/CFArray.h>
       
    69 #include <CoreFoundation/CFArray.h>
       
    70 #include <CoreFoundation/CFNumber.h>
       
    71 #include <CoreFoundation/CFNotificationCenter.h>
       
    72 #include <IOKit/graphics/IOGraphicsLib.h>
       
    73 #include <CoreFoundation/CoreFoundation.h>
       
    74 #include <CoreFoundation/CFLocale.h>
       
    75 #include <ScreenSaver/ScreenSaverDefaults.h>
       
    76 #include <dns_sd.h>
       
    77 
       
    78 #include <QTKit/QTKit.h>
       
    79 
       
    80 #include <IOKit/usb/IOUSBLib.h>
       
    81 #include <IOKit/pwr_mgt/IOPM.h>
       
    82 #include <IOKit/ps/IOPSKeys.h>
       
    83 #include <IOKit/ps/IOPowerSources.h>
       
    84 #include <IOKit/IOTypes.h>
       
    85 
       
    86 #include <IOKit/storage/IOMedia.h>
       
    87 #include <IOKit/storage/IOCDMedia.h>
       
    88 #include <IOKit/storage/IODVDMedia.h>
       
    89 #include <IOKit/storage/IOBlockStorageDevice.h>
       
    90 
       
    91 #include <IOKit/IOKitLib.h>
       
    92 #include <IOKit/hid/IOHIDLib.h>
       
    93 
       
    94 #include <CoreServices/CoreServices.h>
       
    95 
       
    96 #include <qabstracteventdispatcher.h>
       
    97 
       
    98 #include <QtCore/qthread.h>
       
    99 #include <QtCore/qmutex.h>
       
   100 #include <QEventLoop>
       
   101 
       
   102 #ifdef MAC_SDK_10_6
       
   103 #include <CoreLocation/CLLocation.h>
       
   104 #include <CoreLocation/CLLocationManager.h>
       
   105 #include <CoreWLAN/CWInterface.h>
       
   106 #include <CoreWLAN/CWGlobals.h>
       
   107 #else
       
   108 // 10.5 sdk is broken for this:
       
   109 #include </Developer/SDKs/MacOSX10.5.sdk/System/Library/Frameworks/CoreServices.framework/Frameworks/OSServices.framework/Headers/Power.h>
       
   110 #endif
       
   111 
       
   112 #include <sys/types.h>
       
   113 #include <sys/sysctl.h>
       
   114 #include <sys/cdefs.h>
       
   115 #include <sys/param.h>
       
   116 #include <sys/ucred.h>
       
   117 #include <sys/mount.h>
       
   118 #include <math.h>
       
   119 #include <net/if.h>
       
   120 
       
   121 #include <net/if_types.h>
       
   122 #include <net/if_media.h>
       
   123 #include <sys/ioctl.h>
       
   124 #include <sys/socket.h>
       
   125 
       
   126 
       
   127 static QString stringFromCFString(CFStringRef value) {
       
   128     QString retVal;
       
   129     if(CFStringGetLength(value) > 1) {
       
   130         CFIndex maxLength = 2 * CFStringGetLength(value) + 1/*zero term*/; // max UTF8
       
   131         char *cstring = new char[maxLength];
       
   132         if (CFStringGetCString(CFStringRef(value), cstring, maxLength, kCFStringEncodingUTF8)) {
       
   133             retVal = QString::fromUtf8(cstring);
       
   134         }
       
   135         delete cstring;
       
   136     }
       
   137     return retVal;
       
   138 }
       
   139 
       
   140 inline CFStringRef qstringToCFStringRef(const QString &string)
       
   141 {
       
   142     return CFStringCreateWithCharacters(0, reinterpret_cast<const UniChar *>(string.unicode()),
       
   143                                         string.length());
       
   144 }
       
   145 
       
   146 inline QString nsstringToQString(const NSString *nsstr)
       
   147 { return QString([nsstr UTF8String]);}
       
   148 
       
   149 inline NSString *qstringToNSString(const QString &qstr)
       
   150 { return [reinterpret_cast<const NSString *>(qstringToCFStringRef(qstr)) autorelease]; }
       
   151 
       
   152 inline QStringList nsarrayToQStringList(void *nsarray)
       
   153 {
       
   154     NSAutoreleasePool *autoreleasepool = [[NSAutoreleasePool alloc] init];
       
   155     QStringList result;
       
   156     NSArray *array = static_cast<NSArray *>(nsarray);
       
   157     for (NSUInteger i=0; i<[array count]; ++i)
       
   158         result << nsstringToQString([array objectAtIndex:i]);
       
   159     [autoreleasepool release];
       
   160     return result;
       
   161 }
       
   162 
       
   163 bool hasIOServiceMatching(const QString &classstr)
       
   164 {
       
   165     io_iterator_t ioIterator = NULL;
       
   166     IOServiceGetMatchingServices(kIOMasterPortDefault, IOServiceNameMatching(classstr.toAscii()), &ioIterator);
       
   167     if(ioIterator) {
       
   168         return true;
       
   169     }
       
   170     return false;
       
   171 }
       
   172 
       
   173 
       
   174 
       
   175 #ifdef MAC_SDK_10_6
       
   176 
       
   177 @interface QtMNSListener : NSObject
       
   178 {
       
   179     NSNotificationCenter *center;
       
   180     CWInterface * currentInterface;
       
   181 }
       
   182 - (void)notificationHandler:(NSNotification *)notification;
       
   183 - (void)remove;
       
   184 @end
       
   185 
       
   186 @implementation QtMNSListener
       
   187 - (id) init
       
   188 {
       
   189    [super init];
       
   190     center = [NSNotificationCenter defaultCenter];
       
   191     currentInterface = [CWInterface interfaceWithName:nil];
       
   192 
       
   193     [center addObserver:self selector:@selector(notificationHandler:) name:kCWModeDidChangeNotification object:nil];
       
   194     [center addObserver:self selector:@selector(notificationHandler:) name:kCWSSIDDidChangeNotification object:nil];
       
   195     [center addObserver:self selector:@selector(notificationHandler:) name:kCWBSSIDDidChangeNotification object:nil];
       
   196     [center addObserver:self selector:@selector(notificationHandler:) name:kCWCountryCodeDidChangeNotification object:nil];
       
   197     [center addObserver:self selector:@selector(notificationHandler:) name:kCWLinkDidChangeNotification object:nil];
       
   198     [center addObserver:self selector:@selector(notificationHandler:) name:kCWPowerDidChangeNotification object:nil];
       
   199 
       
   200 
       
   201     return self;
       
   202 }
       
   203 
       
   204 -(void)dealloc
       
   205 {
       
   206    [center release];
       
   207    [super dealloc];
       
   208 }
       
   209 
       
   210 -(void)remove
       
   211 {
       
   212     [center removeObserver:self];
       
   213 }
       
   214 
       
   215 - (void)notificationHandler:(NSNotification *)notification
       
   216 {
       
   217     QTM_NAMESPACE::QSystemNetworkInfoPrivate::instance()->wifiNetworkChanged( nsstringToQString([notification name]), nsstringToQString([[notification object]name]));
       
   218 }
       
   219 @end
       
   220 
       
   221 
       
   222 @interface QtMLangListener : NSObject
       
   223 {
       
   224     NSNotificationCenter *center;
       
   225     QString currentLanguage;
       
   226 }
       
   227 - (void)languageHandler;//:(NSNotification *)notification;
       
   228 - (void)remove;
       
   229 - (void)getCurrentLanguage;
       
   230 @end
       
   231 
       
   232 
       
   233 
       
   234 @implementation QtMLangListener
       
   235 - (id) init
       
   236 {
       
   237     [super init];
       
   238     center = [NSNotificationCenter defaultCenter];
       
   239     [center addObserver:self selector:@selector(languageHandler:) name:NSCurrentLocaleDidChangeNotification object:nil];
       
   240     [self getCurrentLanguage];
       
   241     return self;
       
   242 }
       
   243 
       
   244 -(void)dealloc
       
   245 {
       
   246     [center release];
       
   247     [super dealloc];
       
   248 }
       
   249 
       
   250 -(void)remove
       
   251 {
       
   252     [center removeObserver:self];
       
   253 }
       
   254 
       
   255 - (void)getCurrentLanguage
       
   256 {
       
   257     NSUserDefaults* defs = [NSUserDefaults standardUserDefaults];
       
   258     NSArray* languages = [defs objectForKey:@"AppleLanguages"];
       
   259     NSString* language = [languages objectAtIndex:0];
       
   260 
       
   261     QString langString = nsstringToQString(language);
       
   262     if(langString != currentLanguage) {
       
   263         if(!currentLanguage.isEmpty())
       
   264             QTM_NAMESPACE::QSystemInfoPrivate::instance()->languageChanged(currentLanguage);
       
   265         currentLanguage = langString;
       
   266     }
       
   267 }
       
   268 
       
   269 - (void)languageHandler;//:(NSNotification *)notification
       
   270 {
       
   271     [self getCurrentLanguage];
       
   272 }
       
   273 @end
       
   274 
       
   275 
       
   276 @interface RemoteDeviceRSSIHostControllerDelegate : NSObject
       
   277 {
       
   278 }
       
   279 // See IOBluetoothHostControllerDelegate
       
   280 - (void)readRSSIForDeviceComplete:(id)controller device:(IOBluetoothDevice*)device info:(BluetoothHCIRSSIInfo*)info error:(IOReturn)error;
       
   281 @end
       
   282 
       
   283 @implementation RemoteDeviceRSSIHostControllerDelegate
       
   284 - (id) init
       
   285 {
       
   286    [super init];
       
   287    return self;
       
   288 }
       
   289 
       
   290 - (void)readRSSIForDeviceComplete:(id)controller device:(IOBluetoothDevice*)device info:(BluetoothHCIRSSIInfo*)info error:(IOReturn)error
       
   291 {
       
   292     Q_UNUSED(controller);
       
   293     Q_UNUSED(device);
       
   294 
       
   295     if ((error != kIOReturnSuccess) || (info == NULL)) {
       
   296         qWarning() << "ERROR: readRSSIForDeviceComplete return error";
       
   297 
       
   298     } else if (info->handle == kBluetoothConnectionHandleNone) {
       
   299         qWarning() << "ERROR: readRSSIForDeviceComplete no connection";
       
   300     } else {
       
   301         NSLog(@"Rssi value: %@", info->RSSIValue);
       
   302     }
       
   303 }
       
   304 @end
       
   305 #endif
       
   306 NSObject* delegate;
       
   307 
       
   308 QTM_BEGIN_NAMESPACE
       
   309 
       
   310 Q_GLOBAL_STATIC(QSystemDeviceInfoPrivate, qsystemDeviceInfoPrivate)
       
   311 
       
   312 QSystemInfoPrivate *QSystemInfoPrivate::self = 0;
       
   313 
       
   314 QSystemInfoPrivate::QSystemInfoPrivate(QObject *parent)
       
   315  : QObject(parent),langloopThread(0),langThreadOk(0)
       
   316 {
       
   317     if(!self)
       
   318         self = this;
       
   319 }
       
   320 
       
   321 QSystemInfoPrivate::~QSystemInfoPrivate()
       
   322 {
       
   323     if(langThreadOk && langloopThread->isRunning()) {
       
   324         langloopThread->stop();
       
   325     }
       
   326 }
       
   327 
       
   328 QString QSystemInfoPrivate::currentLanguage() const
       
   329 {
       
   330  QString lang = QLocale::system().name().left(2);
       
   331     if(lang.isEmpty() || lang == QLatin1String("C")) {
       
   332         lang = QLatin1String("en");
       
   333     }
       
   334     return lang;
       
   335 }
       
   336 
       
   337 QStringList QSystemInfoPrivate::availableLanguages() const
       
   338 {
       
   339     NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
       
   340 
       
   341     NSUserDefaults* defs = [NSUserDefaults standardUserDefaults];
       
   342     NSArray* languages = [defs objectForKey:@"AppleLanguages"];
       
   343     QStringList langList = nsarrayToQStringList(languages);
       
   344 
       
   345     QStringList returnList;
       
   346     for(int i = 0; i < langList.count(); i++) {
       
   347      QString language = langList.at(i).left(2);
       
   348      if(!returnList.contains(language))
       
   349          returnList << language;
       
   350     }
       
   351     [pool drain];
       
   352     return returnList;
       
   353 }
       
   354 
       
   355 void QSystemInfoPrivate::languageChanged(const QString &lang)
       
   356 {
       
   357     Q_EMIT currentLanguageChanged(lang);
       
   358 }
       
   359 
       
   360 void QSystemInfoPrivate::connectNotify(const char *signal)
       
   361 {
       
   362     if (QLatin1String(signal) == SIGNAL(currentLanguageChanged(QString))) {
       
   363         langloopThread = new QLangLoopThread(this);
       
   364         langloopThread->start();
       
   365         langThreadOk = true;
       
   366     }
       
   367 }
       
   368 
       
   369 void QSystemInfoPrivate::disconnectNotify(const char *signal)
       
   370 {
       
   371     if (QLatin1String(signal) == SIGNAL(currentLanguageChanged(QString))) {
       
   372         if(langloopThread->isRunning()) {
       
   373             langloopThread->stop();
       
   374         }
       
   375     }
       
   376 }
       
   377 
       
   378 QString QSystemInfoPrivate::version(QSystemInfo::Version type,  const QString &parameter)
       
   379 {
       
   380     Q_UNUSED(parameter);
       
   381     QString errorStr = "Not Available";
       
   382     bool useDate = false;
       
   383     if(parameter == QLatin1String("versionDate")) {
       
   384         useDate = true;
       
   385     }
       
   386     switch(type) {
       
   387     case QSystemInfo::Os:
       
   388         {
       
   389             return nsstringToQString([[NSDictionary dictionaryWithContentsOfFile:@"/System/Library/CoreServices/SystemVersion.plist"] objectForKey:@"ProductVersion"]);
       
   390         }
       
   391         break;
       
   392     case QSystemInfo::QtCore:
       
   393        return  qVersion();
       
   394        break;
       
   395    case QSystemInfo::Firmware:
       
   396        {
       
   397            return QSystemDeviceInfoPrivate::model();
       
   398        }
       
   399        break;
       
   400     };
       
   401   return errorStr;
       
   402 }
       
   403 
       
   404 
       
   405 QString QSystemInfoPrivate::currentCountryCode() const
       
   406 {
       
   407     return QLocale::system().name().mid(3,2);
       
   408 }
       
   409 
       
   410 
       
   411 bool QSystemInfoPrivate::hasFeatureSupported(QSystemInfo::Feature feature)
       
   412 {
       
   413     bool featureSupported = false;
       
   414     switch (feature) {
       
   415     case QSystemInfo::BluetoothFeature:
       
   416         {
       
   417 #ifdef  MAC_SDK_10_6
       
   418             IOBluetoothHostController* controller = [IOBluetoothHostController defaultController];
       
   419             if (controller != NULL) {
       
   420                 featureSupported = true;
       
   421             }
       
   422 #endif
       
   423         }
       
   424         break;
       
   425     case QSystemInfo::CameraFeature:
       
   426         {
       
   427 
       
   428            NSArray * videoDevices;
       
   429            videoDevices = [[QTCaptureDevice inputDevicesWithMediaType:QTMediaTypeVideo] arrayByAddingObjectsFromArray:[QTCaptureDevice inputDevicesWithMediaType:QTMediaTypeMuxed]];
       
   430            if([videoDevices count] > 0) {
       
   431                featureSupported = true;
       
   432            }
       
   433         }
       
   434         break;
       
   435     case QSystemInfo::FmradioFeature:
       
   436         break;
       
   437     case QSystemInfo::IrFeature:
       
   438         {
       
   439             if(hasIOServiceMatching("AppleIRController")) {
       
   440                 featureSupported = true;
       
   441             }
       
   442         }
       
   443         break;
       
   444     case QSystemInfo::LedFeature:
       
   445         {
       
   446 //kHIDPage_LEDs
       
   447         }
       
   448         break;
       
   449     case QSystemInfo::MemcardFeature:
       
   450         {
       
   451 // IOSCSIPeripheralDeviceType0E
       
   452             if(hasIOServiceMatching("IOUSBMassStorageClass")) {
       
   453                 featureSupported = true;
       
   454             }
       
   455         }
       
   456         break;
       
   457     case QSystemInfo::UsbFeature:
       
   458         {
       
   459             if(hasIOServiceMatching("AppleUSBOHCI")) {
       
   460                 featureSupported = true;
       
   461             }
       
   462             if(hasIOServiceMatching("AppleUSBEHCI")) {
       
   463                 featureSupported = true;
       
   464             }
       
   465         }
       
   466         break;
       
   467     case QSystemInfo::VibFeature:
       
   468         {
       
   469         }
       
   470         break;
       
   471     case QSystemInfo::WlanFeature:
       
   472         {
       
   473             if(!QSystemNetworkInfoPrivate::instance()->interfaceForMode(QSystemNetworkInfo::WlanMode).name().isEmpty()) {
       
   474                 featureSupported = true;
       
   475             }
       
   476         }
       
   477         break;
       
   478     case QSystemInfo::SimFeature:
       
   479         {
       
   480         }
       
   481         break;
       
   482     case QSystemInfo::LocationFeature:
       
   483         {
       
   484 #ifdef MAC_SDK_10_6
       
   485             CLLocationManager *locationManager = [[CLLocationManager alloc] init];
       
   486             if ([locationManager locationServicesEnabled]) {
       
   487                 featureSupported = true;
       
   488             }
       
   489             [locationManager release];
       
   490 #endif
       
   491         }
       
   492         break;
       
   493     case QSystemInfo::VideoOutFeature:
       
   494         {
       
   495             ComponentDescription description = {'vout', 0, 0, 0L, 1L << 0};
       
   496             if( ::CountComponents(&description) > 0) {
       
   497                 featureSupported = true;
       
   498             }
       
   499         }
       
   500         break;
       
   501     case QSystemInfo::HapticsFeature:
       
   502         break;
       
   503     default:
       
   504         featureSupported = false;
       
   505         break;
       
   506     };
       
   507     return featureSupported;
       
   508 }
       
   509 
       
   510 QSystemNetworkInfoPrivate *QSystemNetworkInfoPrivate::self = 0;
       
   511 
       
   512 
       
   513 void networkChangeCallback(SCDynamicStoreRef /*dynamicStore*/, CFArrayRef changedKeys, void */*networkConfigurationManagerPrivate*/)
       
   514 {
       
   515 // NSLog(@"changed keys %@", changedKeys);
       
   516     QStringList keyList = nsarrayToQStringList((void*)changedKeys);
       
   517     if(keyList.contains("State:/Network/Global/DNS")) {
       
   518     }
       
   519     if(keyList.contains("State:/Network/Global/IPv4")) {
       
   520         QTM_NAMESPACE::QSystemNetworkInfoPrivate::instance()->ethernetChanged();
       
   521         QTM_NAMESPACE::QSystemNetworkInfoPrivate::instance()->getDefaultInterface();
       
   522     }
       
   523 
       
   524     return;
       
   525 }
       
   526 
       
   527 #ifdef MAC_SDK_10_6
       
   528 QtMLangListener *langListener;
       
   529 #endif
       
   530 
       
   531 
       
   532 QLangLoopThread::QLangLoopThread(QObject *parent)
       
   533     :QThread(parent)
       
   534 {
       
   535 }
       
   536 
       
   537 QLangLoopThread::~QLangLoopThread()
       
   538 {
       
   539 }
       
   540 
       
   541 void QLangLoopThread::stop()
       
   542 {
       
   543     QMutexLocker locker(&mutex);
       
   544     locker.unlock();
       
   545     keepRunning = false;
       
   546     locker.relock();
       
   547 #ifdef MAC_SDK_10_6
       
   548     [langListener release];
       
   549 #endif
       
   550     if(currentThread() != this) {
       
   551         QMetaObject::invokeMethod(this, "quit",
       
   552                                   Qt::QueuedConnection);
       
   553     } else {
       
   554         quit();
       
   555     }
       
   556     wait();
       
   557 }
       
   558 
       
   559 void QLangLoopThread::run()
       
   560 {
       
   561 #ifdef MAC_SDK_10_6
       
   562     QMutexLocker locker(&mutex);
       
   563     locker.unlock();
       
   564     keepRunning = true;
       
   565     locker.relock();
       
   566     NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
       
   567 
       
   568     langListener = [[QtMLangListener alloc] init];
       
   569     SInt32 result;
       
   570     while (keepRunning &&
       
   571            (result = CFRunLoopRunInMode(kCFRunLoopDefaultMode ,5, YES))) {
       
   572     }
       
   573     CFRunLoopStop(CFRunLoopGetCurrent());
       
   574     [pool release];
       
   575 #endif
       
   576 }
       
   577 
       
   578 #ifdef MAC_SDK_10_6
       
   579 QtMNSListener *listener;
       
   580 #endif
       
   581 
       
   582 QRunLoopThread::QRunLoopThread(QObject *parent)
       
   583     :QThread(parent)
       
   584 {
       
   585 }
       
   586 
       
   587 QRunLoopThread::~QRunLoopThread()
       
   588 {
       
   589 }
       
   590 
       
   591 void QRunLoopThread::stop()
       
   592 {
       
   593     QMutexLocker locker(&mutex);
       
   594     locker.unlock();
       
   595     keepRunning = false;
       
   596     locker.relock();
       
   597 #ifdef MAC_SDK_10_6
       
   598     [listener release];
       
   599     [delegate release];
       
   600 #endif
       
   601     if(currentThread() != this) {
       
   602         QMetaObject::invokeMethod(this, "quit",
       
   603                                   Qt::QueuedConnection);
       
   604     } else {
       
   605         quit();
       
   606     }
       
   607     wait();
       
   608 }
       
   609 
       
   610 
       
   611 void QRunLoopThread::run()
       
   612 {
       
   613 #ifdef MAC_SDK_10_6
       
   614 
       
   615     NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
       
   616     startNetworkChangeLoop();
       
   617     delegate = [[RemoteDeviceRSSIHostControllerDelegate alloc] init];
       
   618 
       
   619     mutex.lock();
       
   620     keepRunning = true;
       
   621     mutex.unlock();
       
   622 
       
   623     listener = [[QtMNSListener alloc] init];
       
   624 
       
   625     SInt32 result;
       
   626     while (keepRunning &&
       
   627            (result = CFRunLoopRunInMode(kCFRunLoopDefaultMode ,5, YES))) {
       
   628     }
       
   629     CFRunLoopStop(CFRunLoopGetCurrent());
       
   630     [pool release];
       
   631 #endif
       
   632 }
       
   633 
       
   634 void QRunLoopThread::startNetworkChangeLoop()
       
   635 {
       
   636     storeSession = NULL;
       
   637 
       
   638     SCDynamicStoreContext dynStoreContext = { 0, this /*(void *)storeSession*/, NULL, NULL, NULL };
       
   639     storeSession = SCDynamicStoreCreate(NULL,
       
   640                                  CFSTR("networkChangeCallback"),
       
   641                                  networkChangeCallback,
       
   642                                  &dynStoreContext);
       
   643     if (!storeSession ) {
       
   644         qWarning() << "could not open dynamic store: error:" << SCErrorString(SCError());
       
   645         return;
       
   646     }
       
   647 
       
   648     CFMutableArrayRef notificationKeys;
       
   649     notificationKeys = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks);
       
   650     CFMutableArrayRef patternsArray;
       
   651     patternsArray = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks);
       
   652 
       
   653     CFStringRef storeKey;
       
   654 
       
   655     storeKey = SCDynamicStoreKeyCreateNetworkGlobalEntity(NULL,
       
   656                                                      kSCDynamicStoreDomainState,
       
   657                                                      kSCEntNetLink);
       
   658     CFArrayAppendValue(notificationKeys, storeKey);
       
   659     CFRelease(storeKey);
       
   660 
       
   661     storeKey = SCDynamicStoreKeyCreateNetworkServiceEntity(NULL,
       
   662                                                       kSCDynamicStoreDomainState,
       
   663                                                       kSCCompAnyRegex,
       
   664                                                       kSCEntNetLink);
       
   665     CFArrayAppendValue(patternsArray, storeKey);
       
   666     CFRelease(storeKey);
       
   667 
       
   668     storeKey = SCDynamicStoreKeyCreateNetworkGlobalEntity(NULL,
       
   669                                                      kSCDynamicStoreDomainState,
       
   670                                                      kSCEntNetDNS);
       
   671     CFArrayAppendValue(notificationKeys, storeKey);
       
   672     CFRelease(storeKey);
       
   673 
       
   674     storeKey = SCDynamicStoreKeyCreateNetworkServiceEntity(NULL,
       
   675                                                       kSCDynamicStoreDomainState,
       
   676                                                       kSCCompAnyRegex,
       
   677                                                       kSCEntNetDNS);
       
   678     CFArrayAppendValue(patternsArray, storeKey);
       
   679     CFRelease(storeKey);
       
   680 
       
   681     storeKey = SCDynamicStoreKeyCreateNetworkGlobalEntity(NULL,
       
   682                                                      kSCDynamicStoreDomainState,
       
   683                                                      kSCEntNetIPv4);
       
   684     CFArrayAppendValue(notificationKeys, storeKey);
       
   685     CFRelease(storeKey);
       
   686 
       
   687     storeKey = SCDynamicStoreKeyCreateNetworkServiceEntity(NULL,
       
   688                                                       kSCDynamicStoreDomainState,
       
   689                                                       kSCCompAnyRegex,
       
   690                                                       kSCEntNetIPv4);
       
   691     CFArrayAppendValue(patternsArray, storeKey);
       
   692     CFRelease(storeKey);
       
   693 
       
   694     if (!SCDynamicStoreSetNotificationKeys(storeSession , notificationKeys, patternsArray)) {
       
   695         qWarning() << "register notification error:"<< SCErrorString(SCError());
       
   696         CFRelease(storeSession );
       
   697         CFRelease(notificationKeys);
       
   698         CFRelease(patternsArray);
       
   699         return;
       
   700     }
       
   701     CFRelease(notificationKeys);
       
   702     CFRelease(patternsArray);
       
   703 
       
   704     runloopSource = SCDynamicStoreCreateRunLoopSource(NULL, storeSession , 0);
       
   705     if (!runloopSource) {
       
   706         qWarning() << "runloop source error:"<< SCErrorString(SCError());
       
   707         CFRelease(storeSession);
       
   708         return;
       
   709     }
       
   710 
       
   711     CFRunLoopAddSource(CFRunLoopGetCurrent(), runloopSource, kCFRunLoopDefaultMode);
       
   712     CFRelease(runloopSource);
       
   713     CFRelease(storeSession);
       
   714     return;
       
   715 }
       
   716 
       
   717 
       
   718 static bool isBtPowerOn()
       
   719 {
       
   720     //depreciated yes, but what's the replacement?
       
   721     BluetoothHCIPowerState powerState;
       
   722     IOBluetoothLocalDeviceGetPowerState(&powerState);
       
   723     if(powerState == kBluetoothHCIPowerStateON)
       
   724         return true;
       
   725     return false;
       
   726 }
       
   727 
       
   728 void btPowerStateChange(void *ref, io_service_t /*service*/, natural_t messageType, void */*info*/)
       
   729 {
       
   730     QBluetoothListenerThread * thread = reinterpret_cast< QBluetoothListenerThread *>(ref);
       
   731     switch (messageType) {
       
   732     case kIOMessageDeviceWillPowerOff:
       
   733         {
       
   734             if(!isBtPowerOn())
       
   735                 thread->emitBtPower(false);
       
   736         }
       
   737         break;
       
   738     case kIOMessageDeviceHasPoweredOn:
       
   739         {
       
   740             if(isBtPowerOn())
       
   741                 thread->emitBtPower(true);
       
   742         }
       
   743         break;
       
   744     }
       
   745 }
       
   746 
       
   747 QBluetoothListenerThread::QBluetoothListenerThread(QObject *parent)
       
   748     :QThread(parent)
       
   749 {
       
   750     setTerminationEnabled(true);
       
   751 }
       
   752 
       
   753 QBluetoothListenerThread::~QBluetoothListenerThread()
       
   754 {
       
   755     if(isRunning()) {
       
   756         terminate();
       
   757         wait();
       
   758     }
       
   759 }
       
   760 
       
   761 void QBluetoothListenerThread::stop()
       
   762 {
       
   763     mutex.lock();
       
   764     keepRunning = false;
       
   765     mutex.unlock();
       
   766 
       
   767     if(CFRunLoopContainsSource(rl,rls,kCFRunLoopDefaultMode)) {
       
   768         CFRunLoopRemoveSource(rl,
       
   769                               rls,
       
   770                               kCFRunLoopDefaultMode);
       
   771         CFRunLoopStop(rl);
       
   772     }
       
   773     if(currentThread() != this) {
       
   774         QMetaObject::invokeMethod(this, "quit",
       
   775                                   Qt::QueuedConnection);
       
   776     } else {
       
   777         quit();
       
   778     }
       
   779     mutex.lock();
       
   780     IONotificationPortDestroy(port);
       
   781     mutex.unlock();
       
   782 }
       
   783 
       
   784 void QBluetoothListenerThread::run()
       
   785 {
       
   786 #ifdef MAC_SDK_10_6
       
   787     mutex.lock();
       
   788     keepRunning = true;
       
   789     mutex.unlock();
       
   790     NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
       
   791     io_object_t notifyObject;
       
   792     io_service_t bluetoothservice;
       
   793 
       
   794     io_iterator_t ioIterator;
       
   795     mach_port_t masterPort;
       
   796     CFMutableDictionaryRef serviceMatchDict;
       
   797 
       
   798     if (0 != IOMasterPort(MACH_PORT_NULL, &masterPort)) {
       
   799         qDebug() << "IOMasterPort failed";
       
   800     }
       
   801 
       
   802     serviceMatchDict = IOServiceMatching("IOBluetoothHCIController");
       
   803     if (NULL == serviceMatchDict) {
       
   804         qDebug() << "IOServiceMatching failed";
       
   805     }
       
   806 
       
   807     if (0 != IOServiceGetMatchingServices(masterPort, serviceMatchDict, &ioIterator)) {
       
   808         qDebug() << "IOServiceGetMatchingServices failed";
       
   809     }
       
   810 
       
   811     IOReturn ret;
       
   812 
       
   813     bluetoothservice = IOIteratorNext(ioIterator);
       
   814     if (0 == bluetoothservice) {
       
   815         IOObjectRelease(ioIterator);
       
   816         qDebug() << "IOIteratorNext failed";
       
   817     }
       
   818     IOObjectRelease(ioIterator);
       
   819 
       
   820     port = IONotificationPortCreate(masterPort);
       
   821     if (0 == port) {
       
   822         qDebug() << "IONotificationPortCreate failed";
       
   823     }
       
   824 
       
   825     ret = IOServiceAddInterestNotification(port, bluetoothservice,
       
   826                                            kIOGeneralInterest, btPowerStateChange,
       
   827                                            this, &notifyObject);
       
   828     if(ret != kIOReturnSuccess) {
       
   829         qDebug() << "IOServiceAddInterestNotification failed";
       
   830         return;
       
   831     }
       
   832 
       
   833     rl = CFRunLoopGetCurrent();
       
   834     rls = IONotificationPortGetRunLoopSource(port);
       
   835 
       
   836     CFRunLoopAddSource(rl,
       
   837                        rls,
       
   838                        kCFRunLoopDefaultMode);
       
   839     SInt32 result;
       
   840     while (keepRunning &&
       
   841            (result = CFRunLoopRunInMode(kCFRunLoopDefaultMode ,1, NO))) {
       
   842     }
       
   843 
       
   844     CFRunLoopStop(rl);
       
   845 
       
   846     IOObjectRelease(bluetoothservice);
       
   847     CFRunLoopRemoveSource(rl,
       
   848                           rls,
       
   849                           kCFRunLoopDefaultMode);
       
   850     [pool release];
       
   851 #endif
       
   852 }
       
   853 
       
   854 void QBluetoothListenerThread::emitBtPower(bool b)
       
   855 {
       
   856     Q_EMIT bluetoothPower(b);
       
   857 }
       
   858 
       
   859 
       
   860 QSystemNetworkInfoPrivate::QSystemNetworkInfoPrivate(QObject *parent)
       
   861         : QObject(parent), signalStrengthCache(0)
       
   862 {
       
   863      defaultInterface = "";
       
   864     qRegisterMetaType<QSystemNetworkInfo::NetworkMode>("QSystemNetworkInfo::NetworkMode");
       
   865     qRegisterMetaType<QSystemNetworkInfo::NetworkStatus>("QSystemNetworkInfo::NetworkStatus");
       
   866 
       
   867 #ifdef MAC_SDK_10_6
       
   868 if([[CWInterface supportedInterfaces] count] > 0 ) {
       
   869         hasWifi = true;
       
   870     } else {
       
   871         hasWifi = false;
       
   872     }
       
   873 #endif
       
   874     rssiTimer = new QTimer(this);
       
   875 
       
   876     if(!self)
       
   877         self = this;
       
   878     QTimer::singleShot(200, this, SLOT(primaryInterface()));
       
   879 }
       
   880 
       
   881 QSystemNetworkInfoPrivate::~QSystemNetworkInfoPrivate()
       
   882 {
       
   883 #ifdef MAC_SDK_10_6
       
   884     if(hasWifi && runloopThread->isRunning()) {
       
   885         runloopThread->stop();
       
   886     }
       
   887 #endif
       
   888 }
       
   889 
       
   890 void QSystemNetworkInfoPrivate::primaryInterface()
       
   891 {
       
   892     defaultInterface = getDefaultInterface();
       
   893 }
       
   894 
       
   895 void QSystemNetworkInfoPrivate::connectNotify(const char *signal)
       
   896 {
       
   897     if (QLatin1String(signal) == SIGNAL(networkSignalStrengthChanged(QSystemNetworkInfo::NetworkMode,int))) {
       
   898         connect(rssiTimer, SIGNAL(timeout()), this, SLOT(rssiTimeout()));
       
   899         rssiTimer->start(5000);
       
   900     }
       
   901     if (QLatin1String(signal) == SIGNAL(networkNameChanged(QSystemNetworkInfo::NetworkMode,QString))
       
   902         || QLatin1String(signal) == SIGNAL(networkStatusChanged(QSystemNetworkInfo::NetworkMode, QSystemNetworkInfo::NetworkStatus))) {
       
   903 #ifdef MAC_SDK_10_6
       
   904         if(hasWifi) {
       
   905             runloopThread = new QRunLoopThread(this);
       
   906             runloopThread->start();
       
   907         }
       
   908 #endif
       
   909     }
       
   910 }
       
   911 
       
   912 void QSystemNetworkInfoPrivate::disconnectNotify(const char *signal)
       
   913 {
       
   914     if (QLatin1String(signal) == SIGNAL(networkSignalStrengthChanged(QSystemNetworkInfo::NetworkMode,int))) {
       
   915         rssiTimer->stop();
       
   916         disconnect(rssiTimer, SIGNAL(timeout()), this, SLOT(rssiTimeout()));
       
   917     }
       
   918     if (QLatin1String(signal) == SIGNAL(networkNameChanged(QSystemNetworkInfo::NetworkMode,QString))
       
   919         || QLatin1String(signal) == SIGNAL(networkStatusChanged(QSystemNetworkInfo::NetworkMode, QSystemNetworkInfo::NetworkStatus))) {
       
   920 #ifdef MAC_SDK_10_6
       
   921         if(hasWifi && runloopThread->isRunning()) {
       
   922             runloopThread->quit();
       
   923             runloopThread->wait();
       
   924             [delegate release];
       
   925         }
       
   926 #endif
       
   927     }
       
   928 }
       
   929 
       
   930 QSystemNetworkInfo::NetworkMode QSystemNetworkInfoPrivate::modeForInterface(QString interfaceName)
       
   931 {
       
   932     QSystemNetworkInfo::NetworkMode mode = QSystemNetworkInfo::UnknownMode;
       
   933     CFArrayRef interfaceArray = SCNetworkInterfaceCopyAll(); //10.4
       
   934     CFStringRef iName;
       
   935     CFStringRef type;
       
   936 
       
   937     for ( long i = 0; i < CFArrayGetCount(interfaceArray); i++) {
       
   938         SCNetworkInterfaceRef thisInterface =  (SCNetworkInterfaceRef ) CFArrayGetValueAtIndex(interfaceArray, i);
       
   939         type = SCNetworkInterfaceGetInterfaceType(thisInterface);
       
   940         iName = SCNetworkInterfaceGetBSDName(thisInterface);
       
   941         if( interfaceName == stringFromCFString(iName)) {
       
   942             if (type != NULL) {
       
   943                 if (CFEqual(type, kSCNetworkInterfaceTypeBluetooth)) {
       
   944                     mode = QSystemNetworkInfo::BluetoothMode;
       
   945                     break;
       
   946                 } else if (CFEqual(type, kSCNetworkInterfaceTypeEthernet)) {
       
   947                     mode = QSystemNetworkInfo::EthernetMode;
       
   948                     break;
       
   949                 } else if (CFEqual(type, kSCNetworkInterfaceTypeIEEE80211)) {
       
   950                     mode = QSystemNetworkInfo::WlanMode;
       
   951                     break;
       
   952                 }
       
   953             }
       
   954         }
       
   955     }
       
   956     CFRelease(interfaceArray);
       
   957     return mode;
       
   958 }
       
   959 
       
   960 QString QSystemNetworkInfoPrivate::getDefaultInterface()
       
   961 {
       
   962     SCDynamicStoreRef storeSession2;
       
   963     CFStringRef key;
       
   964     CFDictionaryRef	globalDict;
       
   965     CFStringRef primaryInterface = NULL;
       
   966     QString interfaceName;
       
   967 
       
   968     storeSession2 = SCDynamicStoreCreate(NULL, CFSTR("getPrimary"), NULL, NULL);
       
   969     if (!storeSession2) {
       
   970     }
       
   971     key = SCDynamicStoreKeyCreateNetworkGlobalEntity(NULL, kSCDynamicStoreDomainState,kSCEntNetIPv4);
       
   972     globalDict = (const __CFDictionary*)SCDynamicStoreCopyValue(storeSession2, key);
       
   973     CFRelease(key);
       
   974     if (globalDict) {
       
   975 
       
   976         primaryInterface = (CFStringRef )CFDictionaryGetValue(globalDict,
       
   977                                                                    kSCDynamicStorePropNetPrimaryInterface);
       
   978         if (primaryInterface) {
       
   979             CFRetain(primaryInterface);
       
   980         }
       
   981         CFRelease(globalDict);
       
   982     }
       
   983 
       
   984     CFRelease(storeSession2);
       
   985     if (primaryInterface) {
       
   986         interfaceName = stringFromCFString(primaryInterface);
       
   987         if(interfaceName != defaultInterface) {
       
   988             Q_EMIT networkModeChanged(modeForInterface(interfaceName));
       
   989              defaultInterface = interfaceName;
       
   990         }
       
   991     }
       
   992 
       
   993     return interfaceName;
       
   994 }
       
   995 
       
   996 void QSystemNetworkInfoPrivate::rssiTimeout()
       
   997 {
       
   998     networkSignalStrength(QSystemNetworkInfo::WlanMode);
       
   999 }
       
  1000 
       
  1001 bool QSystemNetworkInfoPrivate::isInterfaceActive(const char* netInterface)
       
  1002 {
       
  1003     struct ifmediareq ifm;
       
  1004 
       
  1005     memset(&ifm, 0, sizeof(struct ifmediareq));
       
  1006     strncpy(ifm.ifm_name, netInterface, IFNAMSIZ);
       
  1007     int s = socket(AF_INET, SOCK_DGRAM, 0);
       
  1008     ioctl(s, SIOCGIFMEDIA, &ifm);
       
  1009     if (ifm.ifm_status & IFM_ACTIVE) {
       
  1010         return true;
       
  1011     }
       
  1012     return false;
       
  1013 }
       
  1014 
       
  1015 void QSystemNetworkInfoPrivate::ethernetChanged()
       
  1016 {
       
  1017     QSystemNetworkInfo::NetworkStatus status = QSystemNetworkInfo::NoNetworkAvailable;
       
  1018     int carrier = 0;
       
  1019 
       
  1020     if(isInterfaceActive(interfaceForMode(QSystemNetworkInfo::EthernetMode).name().toLocal8Bit())) {
       
  1021         status = QSystemNetworkInfo::Connected;
       
  1022         carrier = 100;
       
  1023     }
       
  1024     Q_EMIT networkStatusChanged(QSystemNetworkInfo::EthernetMode,status);
       
  1025     Q_EMIT networkSignalStrengthChanged(QSystemNetworkInfo::EthernetMode,carrier);
       
  1026     Q_EMIT networkNameChanged(QSystemNetworkInfo::EthernetMode, networkName(QSystemNetworkInfo::EthernetMode));
       
  1027     Q_EMIT networkModeChanged(modeForInterface(getDefaultInterface()));
       
  1028 }
       
  1029 
       
  1030 QSystemNetworkInfo::NetworkStatus QSystemNetworkInfoPrivate::networkStatus(QSystemNetworkInfo::NetworkMode mode)
       
  1031 {
       
  1032     QSystemNetworkInfo::NetworkStatus status = QSystemNetworkInfo::NoNetworkAvailable;
       
  1033     switch(mode) {
       
  1034         case QSystemNetworkInfo::GsmMode:
       
  1035         break;
       
  1036         case QSystemNetworkInfo::CdmaMode:
       
  1037         break;
       
  1038         case QSystemNetworkInfo::WcdmaMode:
       
  1039         break;
       
  1040     case QSystemNetworkInfo::WlanMode:
       
  1041         {
       
  1042 #ifdef MAC_SDK_10_6
       
  1043             if(hasWifi) {
       
  1044                 NSAutoreleasePool *autoreleasepool = [[NSAutoreleasePool alloc] init];
       
  1045                 CWInterface *wifiInterface = [CWInterface interfaceWithName:  qstringToNSString(interfaceForMode(mode).name())];
       
  1046 
       
  1047                 if([wifiInterface power]) {
       
  1048                     if(!rssiTimer->isActive())
       
  1049                         rssiTimer->start(5000);
       
  1050                 }  else {
       
  1051                     if(rssiTimer->isActive())
       
  1052                         rssiTimer->stop();
       
  1053                 }
       
  1054 
       
  1055                 switch([[wifiInterface interfaceState]intValue]) {
       
  1056                 case  kCWInterfaceStateInactive:
       
  1057                     status = QSystemNetworkInfo::NoNetworkAvailable;
       
  1058                     break;
       
  1059                 case kCWInterfaceStateScanning:
       
  1060                 case kCWInterfaceStateAuthenticating:
       
  1061                 case kCWInterfaceStateAssociating:
       
  1062                     status = QSystemNetworkInfo::Searching;
       
  1063                     break;
       
  1064                 case kCWInterfaceStateRunning:
       
  1065                     status = QSystemNetworkInfo::Connected;
       
  1066                     break;
       
  1067                 };
       
  1068                 [autoreleasepool release];
       
  1069             }
       
  1070 
       
  1071 #else
       
  1072             if(isInterfaceActive(interfaceForMode(mode).name().toLatin1())) {
       
  1073                 status = QSystemNetworkInfo::Connected;
       
  1074             }
       
  1075 #endif
       
  1076         }
       
  1077         break;
       
  1078     case QSystemNetworkInfo::EthernetMode:
       
  1079         {
       
  1080             if(isInterfaceActive(interfaceForMode(mode).name().toLatin1())) {
       
  1081                 return QSystemNetworkInfo::Connected;
       
  1082             } else {
       
  1083                 return QSystemNetworkInfo::NoNetworkAvailable;
       
  1084             }
       
  1085         }
       
  1086         break;
       
  1087         case QSystemNetworkInfo::BluetoothMode:
       
  1088         {
       
  1089 
       
  1090         }
       
  1091         break;
       
  1092     case QSystemNetworkInfo::WimaxMode:
       
  1093         break;
       
  1094         default:
       
  1095         break;
       
  1096     };
       
  1097     return status;
       
  1098 }
       
  1099 
       
  1100 int QSystemNetworkInfoPrivate::networkSignalStrength(QSystemNetworkInfo::NetworkMode mode)
       
  1101 {
       
  1102     switch(mode) {
       
  1103         case QSystemNetworkInfo::GsmMode:
       
  1104         break;
       
  1105         case QSystemNetworkInfo::CdmaMode:
       
  1106         break;
       
  1107         case QSystemNetworkInfo::WcdmaMode:
       
  1108         break;
       
  1109     case QSystemNetworkInfo::WlanMode:
       
  1110         {
       
  1111             int signalQuality = 0;
       
  1112             if(hasWifi) {
       
  1113 #ifdef MAC_SDK_10_6
       
  1114                 NSAutoreleasePool *autoreleasepool = [[NSAutoreleasePool alloc] init];
       
  1115                 QString name = interfaceForMode(mode).name();
       
  1116                 CWInterface *wifiInterface = [CWInterface interfaceWithName:qstringToNSString(name)];
       
  1117 
       
  1118                 if([wifiInterface power]) {
       
  1119                     if(!rssiTimer->isActive())
       
  1120                         rssiTimer->start(5000);
       
  1121                 }  else {
       
  1122                     if(rssiTimer->isActive())
       
  1123                         rssiTimer->stop();
       
  1124                 }
       
  1125 
       
  1126                 int rssiSignal = [[wifiInterface rssi] intValue];
       
  1127 
       
  1128                 if(rssiSignal !=0 ) {
       
  1129                     int maxRssi = -40;
       
  1130                     int minRssi = [[wifiInterface noise] intValue];
       
  1131                     signalQuality = ( 100 * (maxRssi - minRssi) * (maxRssi - minRssi) - (maxRssi - rssiSignal) *
       
  1132                                       (15 * (maxRssi - minRssi) + 62 * (maxRssi - rssiSignal)) ) /
       
  1133                                     ((maxRssi - minRssi) * (maxRssi - minRssi));
       
  1134 
       
  1135                 } else {
       
  1136                     signalQuality = 0;
       
  1137                 }
       
  1138 
       
  1139                 if(signalStrengthCache != signalQuality) {
       
  1140                     if(signalStrengthCache == 0) {
       
  1141                         networkStatus(QSystemNetworkInfo::WlanMode);
       
  1142                     }
       
  1143                     signalStrengthCache = signalQuality;
       
  1144                     Q_EMIT networkSignalStrengthChanged(mode, signalQuality);
       
  1145                 }
       
  1146                 [autoreleasepool release];
       
  1147 #endif
       
  1148             }
       
  1149             return signalQuality;
       
  1150         }
       
  1151         break;
       
  1152     case QSystemNetworkInfo::EthernetMode:
       
  1153         {
       
  1154             int percent = (isInterfaceActive(interfaceForMode(mode).name().toLatin1())) ? 100 : 0;
       
  1155             return percent;
       
  1156         }
       
  1157         break;
       
  1158     case QSystemNetworkInfo::BluetoothMode:
       
  1159         {
       
  1160 #ifdef  MAC_SDK_10_6
       
  1161             NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
       
  1162             IOBluetoothHostController* controller = IOBluetoothHostController.defaultController;
       
  1163             if (controller != NULL) {
       
  1164 
       
  1165                 NSArray *devices = [IOBluetoothDevice recentDevices:0];
       
  1166                 for ( IOBluetoothDevice *btDevice in devices ) {
       
  1167                     if([btDevice isConnected]) {
       
  1168                         qWarning() <<"IOBluetoothDevice connected"<< nsstringToQString([btDevice getName]);
       
  1169 //                        delegate = [[RemoteDeviceRSSIHostControllerDelegate alloc] init];
       
  1170                         [delegate retain];
       
  1171                         [controller setDelegate:delegate];
       
  1172                         IOReturn rc = [controller readRSSIForDevice:btDevice];
       
  1173                         if (rc != noErr) {
       
  1174                             qWarning() << "ERROR: call readRSSIForDevice failed";
       
  1175                         }
       
  1176 //[delegate release];
       
  1177                     }
       
  1178                 }
       
  1179 //              [devices release];
       
  1180   //  [controller release];
       
  1181             }
       
  1182             [pool release];
       
  1183 #endif
       
  1184         }
       
  1185     case QSystemNetworkInfo::WimaxMode:
       
  1186         break;
       
  1187     default:
       
  1188         break;
       
  1189     };
       
  1190     return -1;
       
  1191 }
       
  1192 
       
  1193 int QSystemNetworkInfoPrivate::cellId()
       
  1194 {
       
  1195     return -1;
       
  1196 }
       
  1197 
       
  1198 int QSystemNetworkInfoPrivate::locationAreaCode()
       
  1199 {
       
  1200     return -1;
       
  1201 }
       
  1202 
       
  1203 QString QSystemNetworkInfoPrivate::currentMobileCountryCode()
       
  1204 {
       
  1205     QString cmcc;
       
  1206 #if defined(MAC_SDK_10_6)
       
  1207     if(hasWifi) {
       
  1208         CWInterface *primary = [CWInterface interfaceWithName:nil];
       
  1209         if([primary power]) {
       
  1210             cmcc = nsstringToQString([primary countryCode]);
       
  1211         }
       
  1212     }
       
  1213 #endif
       
  1214     return cmcc;
       
  1215 }
       
  1216 
       
  1217 QString QSystemNetworkInfoPrivate::currentMobileNetworkCode()
       
  1218 {
       
  1219     return "";
       
  1220 }
       
  1221 
       
  1222 QString QSystemNetworkInfoPrivate::homeMobileCountryCode()
       
  1223 {
       
  1224     return "";
       
  1225 }
       
  1226 
       
  1227 QString QSystemNetworkInfoPrivate::homeMobileNetworkCode()
       
  1228 {
       
  1229     return "";
       
  1230 }
       
  1231 
       
  1232 QString QSystemNetworkInfoPrivate::networkName(QSystemNetworkInfo::NetworkMode mode)
       
  1233 {
       
  1234     if(networkStatus(mode) == QSystemNetworkInfo::NoNetworkAvailable) {
       
  1235         return "";
       
  1236     }
       
  1237     switch(mode) {
       
  1238         case QSystemNetworkInfo::GsmMode:
       
  1239         break;
       
  1240         case QSystemNetworkInfo::CdmaMode:
       
  1241         break;
       
  1242         case QSystemNetworkInfo::WcdmaMode:
       
  1243         break;
       
  1244     case QSystemNetworkInfo::WlanMode:
       
  1245         {
       
  1246             QString name = interfaceForMode(mode).name();
       
  1247 #ifdef MAC_SDK_10_6
       
  1248             if(hasWifi) {
       
  1249                 CWInterface *wifiInterface = [CWInterface interfaceWithName:qstringToNSString(name)];
       
  1250                 return nsstringToQString([wifiInterface ssid]);
       
  1251             }
       
  1252 #else
       
  1253             SCDynamicStoreRef theDynamicStore;
       
  1254             theDynamicStore = SCDynamicStoreCreate(nil, CFSTR("FindCurrentInterfaceAndIP"), nil, nil);
       
  1255 
       
  1256             NSMutableString *interfaceName = [NSMutableString string];
       
  1257             NSString *airportPath = [NSString stringWithFormat:@"State:/Network/Interface/%@/AirPort", qstringToNSString(name)];
       
  1258 
       
  1259             CFDictionaryRef airportPlist = (const __CFDictionary*)SCDynamicStoreCopyValue(theDynamicStore, (CFStringRef)airportPath);
       
  1260 
       
  1261             CFRelease(theDynamicStore);
       
  1262 
       
  1263             return nsstringToQString([(NSDictionary *)airportPlist valueForKey:@"SSID_STR"]);
       
  1264 #endif
       
  1265         }
       
  1266         break;
       
  1267     case QSystemNetworkInfo::EthernetMode:
       
  1268         {
       
  1269             if(isInterfaceActive(interfaceForMode(mode).name().toLocal8Bit())) {
       
  1270                 return QHostInfo::localDomainName();
       
  1271             }
       
  1272         }
       
  1273         break;
       
  1274     case QSystemNetworkInfo::BluetoothMode:
       
  1275         break;
       
  1276     case QSystemNetworkInfo::WimaxMode:
       
  1277         break;
       
  1278     default:
       
  1279         break;
       
  1280     };
       
  1281     return "";
       
  1282 }
       
  1283 
       
  1284 QString QSystemNetworkInfoPrivate::macAddress(QSystemNetworkInfo::NetworkMode mode)
       
  1285 {
       
  1286     return interfaceForMode(mode).hardwareAddress();
       
  1287 }
       
  1288 
       
  1289 QNetworkInterface QSystemNetworkInfoPrivate::interfaceForMode(QSystemNetworkInfo::NetworkMode mode)
       
  1290 {
       
  1291     QNetworkInterface netInterface;
       
  1292     CFArrayRef interfaceArray = SCNetworkInterfaceCopyAll(); //10.4
       
  1293     CFStringRef iName;
       
  1294     CFStringRef type;
       
  1295     for ( long i = 0; i < CFArrayGetCount(interfaceArray); i++) {
       
  1296         SCNetworkInterfaceRef thisInterface =  (SCNetworkInterfaceRef ) CFArrayGetValueAtIndex(interfaceArray, i);
       
  1297         type = SCNetworkInterfaceGetInterfaceType(thisInterface);
       
  1298         iName = SCNetworkInterfaceGetBSDName(thisInterface);
       
  1299 
       
  1300         if (type != NULL) {
       
  1301             if (CFEqual(type, kSCNetworkInterfaceTypeBluetooth) && mode == QSystemNetworkInfo::BluetoothMode) {
       
  1302                 netInterface = QNetworkInterface::interfaceFromName(stringFromCFString(iName));
       
  1303                 // workaround for null MAC from SCNetworkInterfaceGetHardwareAddressString and bogus BSD name here
       
  1304 #ifdef  MAC_SDK_10_6
       
  1305                 IOBluetoothHostController* controller = IOBluetoothHostController.defaultController;
       
  1306                 QString macbtMac = nsstringToQString([controller addressAsString]).replace("-",":").toUpper();
       
  1307                 if(!macbtMac.isEmpty()) {
       
  1308                     QList<QNetworkInterface> interfaces = QNetworkInterface::allInterfaces();
       
  1309                     foreach(const QNetworkInterface thisNetInterface, interfaces) {
       
  1310                         if( thisNetInterface.hardwareAddress() == macbtMac) {
       
  1311                             netInterface = thisNetInterface;
       
  1312                             break;
       
  1313                         }
       
  1314                     }
       
  1315                 }
       
  1316 #endif
       
  1317             } else if (CFEqual(type, kSCNetworkInterfaceTypeEthernet) && mode == QSystemNetworkInfo::EthernetMode) {
       
  1318                 netInterface = QNetworkInterface::interfaceFromName(stringFromCFString(iName));
       
  1319                 break;
       
  1320             } else if (CFEqual(type, kSCNetworkInterfaceTypeIEEE80211) && mode == QSystemNetworkInfo::WlanMode) {
       
  1321                 netInterface = QNetworkInterface::interfaceFromName(stringFromCFString(iName));
       
  1322                 break;
       
  1323             }
       
  1324         }
       
  1325     }
       
  1326     CFRelease(interfaceArray);
       
  1327     return netInterface;
       
  1328 }
       
  1329 
       
  1330 void QSystemNetworkInfoPrivate::wifiNetworkChanged(const QString &notification, const QString interfaceName)
       
  1331 {
       
  1332     getDefaultInterface();
       
  1333 
       
  1334     if(notification == QLatin1String("SSID_CHANGED_NOTIFICATION")) {
       
  1335         Q_EMIT networkNameChanged(QSystemNetworkInfo::WlanMode, networkName(QSystemNetworkInfo::WlanMode));
       
  1336     }
       
  1337 
       
  1338     if(notification == QLatin1String("BSSID_CHANGED_NOTIFICATION")) {
       
  1339         QSystemNetworkInfo::NetworkStatus status =  networkStatus(QSystemNetworkInfo::WlanMode);
       
  1340         Q_EMIT networkStatusChanged( QSystemNetworkInfo::WlanMode, status);
       
  1341     }
       
  1342     if(notification == QLatin1String("POWER_CHANGED_NOTIFICATION")) {
       
  1343 #ifdef MAC_SDK_10_6
       
  1344         CWInterface *wifiInterface = [CWInterface interfaceWithName:  qstringToNSString(interfaceName)];
       
  1345         if([wifiInterface power]) {
       
  1346             if(!rssiTimer->isActive()) {
       
  1347                 rssiTimer->start(5000);
       
  1348 
       
  1349             }
       
  1350         }  else {
       
  1351             if(rssiTimer->isActive()) {
       
  1352                 rssiTimer->stop();
       
  1353             }
       
  1354             Q_EMIT networkSignalStrengthChanged(QSystemNetworkInfo::WlanMode, 0);
       
  1355         }
       
  1356 #endif
       
  1357     }
       
  1358 }
       
  1359 
       
  1360 QSystemNetworkInfo::NetworkMode QSystemNetworkInfoPrivate::currentMode()
       
  1361 {
       
  1362     return modeForInterface(getDefaultInterface());
       
  1363 }
       
  1364 
       
  1365 
       
  1366 QSystemDisplayInfoPrivate::QSystemDisplayInfoPrivate(QObject *parent)
       
  1367         : QObject(parent)
       
  1368 {
       
  1369 }
       
  1370 
       
  1371 QSystemDisplayInfoPrivate::~QSystemDisplayInfoPrivate()
       
  1372 {
       
  1373 }
       
  1374 
       
  1375 int QSystemDisplayInfoPrivate::displayBrightness(int screen)
       
  1376 {
       
  1377     int macScreens = 4;
       
  1378     CGDisplayErr dErr;
       
  1379     io_service_t service;
       
  1380     CFStringRef key = CFSTR(kIODisplayBrightnessKey);
       
  1381 
       
  1382     float brightness = HUGE_VALF;
       
  1383     int displayBrightness = -1;
       
  1384     CGDirectDisplayID screensArray[macScreens]; //support 4 screens
       
  1385     CGDisplayCount numberScreens;
       
  1386     CGGetActiveDisplayList(macScreens, screensArray, &numberScreens);
       
  1387     if(numberScreens >= (uint)screen) {
       
  1388         service = CGDisplayIOServicePort(screensArray[screen]);
       
  1389         dErr = IODisplayGetFloatParameter(service, kNilOptions, key, &brightness);
       
  1390         if (dErr == kIOReturnSuccess) {
       
  1391             displayBrightness = (int)(brightness * 100);
       
  1392         }
       
  1393     }
       
  1394     return displayBrightness;
       
  1395 }
       
  1396 
       
  1397 int QSystemDisplayInfoPrivate::colorDepth(int screen)
       
  1398 {
       
  1399     int macScreens = 4;
       
  1400     CGDirectDisplayID screensArray[macScreens]; //support 4 screens
       
  1401     CGDisplayCount numberScreens;
       
  1402     long bitsPerPixel = 0;
       
  1403     CGGetActiveDisplayList(macScreens, screensArray, &numberScreens);
       
  1404     if(numberScreens >= (uint)screen) {
       
  1405         bitsPerPixel = CGDisplayBitsPerPixel (screensArray[screen]);
       
  1406     }
       
  1407     return (int)bitsPerPixel;
       
  1408 }
       
  1409 
       
  1410 QSystemStorageInfoPrivate::QSystemStorageInfoPrivate(QObject *parent)
       
  1411         : QObject(parent)
       
  1412 {
       
  1413 }
       
  1414 
       
  1415 
       
  1416 QSystemStorageInfoPrivate::~QSystemStorageInfoPrivate()
       
  1417 {
       
  1418 }
       
  1419 
       
  1420 bool QSystemStorageInfoPrivate::updateVolumesMap()
       
  1421 {
       
  1422     struct statfs64 *buf = NULL;
       
  1423     unsigned i, count = 0;
       
  1424 
       
  1425     count = getmntinfo64(&buf, 0);
       
  1426     for (i=0; i<count; i++) {
       
  1427         char *volName = buf[i].f_mntonname;
       
  1428         mountEntriesHash.insert(buf[i].f_mntfromname,volName);
       
  1429     }
       
  1430     return true;
       
  1431 }
       
  1432 
       
  1433 
       
  1434 qint64 QSystemStorageInfoPrivate::availableDiskSpace(const QString &driveVolume)
       
  1435 {
       
  1436     qint64 totalFreeBytes=0;
       
  1437     NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
       
  1438     NSDictionary *attr = [ [NSFileManager defaultManager] attributesOfFileSystemForPath:qstringToNSString(driveVolume) error:nil];
       
  1439     totalFreeBytes = [[attr objectForKey:NSFileSystemFreeSize] doubleValue];
       
  1440     [pool release];
       
  1441 
       
  1442     return  totalFreeBytes;
       
  1443 }
       
  1444 
       
  1445 qint64 QSystemStorageInfoPrivate::totalDiskSpace(const QString &driveVolume)
       
  1446 {
       
  1447     qint64 totalBytes=0;
       
  1448     NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
       
  1449     NSDictionary *attr = [ [NSFileManager defaultManager] attributesOfFileSystemForPath:qstringToNSString(driveVolume) error:nil];
       
  1450     totalBytes = [[attr objectForKey:NSFileSystemSize] doubleValue];
       
  1451     [pool release];
       
  1452 
       
  1453     return totalBytes;
       
  1454 }
       
  1455 
       
  1456 QSystemStorageInfo::DriveType QSystemStorageInfoPrivate::typeForDrive(const QString &driveVolume)
       
  1457 {
       
  1458     updateVolumesMap();
       
  1459     OSStatus osstatusResult = noErr;
       
  1460     ItemCount volumeIndex;
       
  1461 
       
  1462     for (volumeIndex = 1; osstatusResult == noErr || osstatusResult != nsvErr; volumeIndex++) {
       
  1463         FSVolumeRefNum actualVolume;
       
  1464         HFSUniStr255 volumeName;
       
  1465         FSVolumeInfo	volumeInfo;
       
  1466 
       
  1467         bzero((void *) &volumeInfo, sizeof(volumeInfo));
       
  1468 
       
  1469         osstatusResult = FSGetVolumeInfo(kFSInvalidVolumeRefNum, volumeIndex, &actualVolume, kFSVolInfoFSInfo,
       
  1470                                          &volumeInfo, &volumeName, NULL);
       
  1471 
       
  1472         if (osstatusResult == noErr) {
       
  1473             GetVolParmsInfoBuffer volumeParmeters;
       
  1474             osstatusResult = FSGetVolumeParms(actualVolume, &volumeParmeters, sizeof(volumeParmeters));
       
  1475 
       
  1476             QString devId = QString((char *)volumeParmeters.vMDeviceID);
       
  1477             devId = devId.prepend(QLatin1String("/dev/"));
       
  1478             if(mountEntriesHash.value(devId) == driveVolume) {
       
  1479                 if (volumeParmeters.vMServerAdr == 0) { //local drive
       
  1480                     io_service_t ioService;
       
  1481                     ioService = IOServiceGetMatchingService(kIOMasterPortDefault,
       
  1482                                                             IOBSDNameMatching(kIOMasterPortDefault,
       
  1483                                                             0,
       
  1484                                                             (char *)volumeParmeters.vMDeviceID));
       
  1485 
       
  1486                     if (IOObjectConformsTo(ioService, kIOMediaClass)) {
       
  1487                         CFTypeRef wholeMedia;
       
  1488 
       
  1489                         wholeMedia = IORegistryEntryCreateCFProperty(ioService,
       
  1490                                                                      CFSTR(kIOMediaContentKey),
       
  1491                                                                      kCFAllocatorDefault,
       
  1492                                                                      0);
       
  1493 
       
  1494                         if((volumeParmeters.vMExtendedAttributes & (1L << bIsRemovable))) {
       
  1495                             IOObjectRelease(ioService);
       
  1496                             CFRelease(wholeMedia);
       
  1497                             return QSystemStorageInfo::RemovableDrive;
       
  1498                         } else {
       
  1499                             IOObjectRelease(ioService);
       
  1500                             CFRelease(wholeMedia);
       
  1501                             return QSystemStorageInfo::InternalDrive;
       
  1502                         }
       
  1503                     }
       
  1504                     IOObjectRelease(ioService);
       
  1505                 } else {
       
  1506                     return QSystemStorageInfo::RemoteDrive;
       
  1507                 }
       
  1508             }
       
  1509         }
       
  1510     }
       
  1511     return QSystemStorageInfo::NoDrive;
       
  1512 }
       
  1513 
       
  1514 QStringList QSystemStorageInfoPrivate::logicalDrives()
       
  1515 {
       
  1516     QStringList drivesList;
       
  1517 
       
  1518     struct statfs64 *buf = NULL;
       
  1519     unsigned i, count = 0;
       
  1520 
       
  1521     count = getmntinfo64(&buf, 0);
       
  1522     for (i=0; i<count; i++) {
       
  1523         char *volName = buf[i].f_mntonname;
       
  1524         if(buf[i].f_type != 19
       
  1525            && buf[i].f_type != 20) {
       
  1526             drivesList << volName;
       
  1527         }
       
  1528     }
       
  1529     return drivesList;
       
  1530 }
       
  1531 
       
  1532 void powerInfoChanged(void* context)
       
  1533 {
       
  1534     QSystemDeviceInfoPrivate *sys = reinterpret_cast<QSystemDeviceInfoPrivate *>(context);
       
  1535     sys->batteryLevel();
       
  1536     sys->currentPowerState();
       
  1537 }
       
  1538 
       
  1539 QSystemDeviceInfoPrivate::QSystemDeviceInfoPrivate(QObject *parent)
       
  1540         : QObject(parent),btThread(0), btThreadOk(0)
       
  1541 {
       
  1542     batteryLevelCache = 0;
       
  1543     currentPowerStateCache = QSystemDeviceInfo::UnknownPower;
       
  1544     batteryStatusCache = QSystemDeviceInfo::NoBatteryLevel;
       
  1545 }
       
  1546 
       
  1547 QSystemDeviceInfoPrivate::~QSystemDeviceInfoPrivate()
       
  1548 {
       
  1549     if( btThreadOk && btThread->isRunning())
       
  1550         btThread->stop();
       
  1551 }
       
  1552 
       
  1553 QSystemDeviceInfoPrivate *QSystemDeviceInfoPrivate::instance()
       
  1554 {
       
  1555     return qsystemDeviceInfoPrivate();
       
  1556 }
       
  1557 
       
  1558 void QSystemDeviceInfoPrivate::connectNotify(const char *signal)
       
  1559 {
       
  1560     if (QLatin1String(signal) == SIGNAL(bluetoothStateChanged(bool))) {
       
  1561         if(!btThread) {
       
  1562             btThread = new QBluetoothListenerThread(this);
       
  1563             btThread->start();
       
  1564             connect(btThread,SIGNAL(bluetoothPower(bool)), this, SIGNAL(bluetoothStateChanged(bool)));
       
  1565              btThreadOk = true;
       
  1566         }
       
  1567     }
       
  1568 
       
  1569     if (QLatin1String(signal) == SIGNAL(powerStateChanged(QSystemDeviceInfo::PowerState))) {
       
  1570         CFRunLoopSourceRef runLoopSource = (CFRunLoopSourceRef)IOPSNotificationCreateRunLoopSource(powerInfoChanged, this);
       
  1571         if (runLoopSource) {
       
  1572             CFRunLoopAddSource(CFRunLoopGetCurrent(), runLoopSource, kCFRunLoopDefaultMode);
       
  1573             CFRelease(runLoopSource);
       
  1574         }
       
  1575     }
       
  1576 }
       
  1577 
       
  1578 void QSystemDeviceInfoPrivate::disconnectNotify(const char *signal)
       
  1579 {
       
  1580     if (QLatin1String(signal) == SIGNAL(bluetoothStateChanged(bool))) {
       
  1581         if(btThread->isRunning()) {
       
  1582             btThread->stop();
       
  1583         }
       
  1584     }
       
  1585 }
       
  1586 
       
  1587 
       
  1588 QSystemDeviceInfo::Profile QSystemDeviceInfoPrivate::currentProfile()
       
  1589 {
       
  1590     return QSystemDeviceInfo::UnknownProfile;
       
  1591 }
       
  1592 
       
  1593 
       
  1594 QSystemDeviceInfo::InputMethodFlags QSystemDeviceInfoPrivate::inputMethodType()
       
  1595 {
       
  1596     QSystemDeviceInfo::InputMethodFlags methods = 0;
       
  1597 
       
  1598     if(hasIOServiceMatching("AppleUSBTCButtons")) {
       
  1599         methods = (methods | QSystemDeviceInfo::Keys);
       
  1600     }
       
  1601     if(hasIOServiceMatching("AppleUSBTCKeyboard")) {
       
  1602         methods = (methods | QSystemDeviceInfo::Keyboard);
       
  1603     }
       
  1604     if(hasIOServiceMatching("AppleUSBMultitouchDriver")) {
       
  1605         methods = (methods | QSystemDeviceInfo::MultiTouch);
       
  1606     }
       
  1607     if(hasIOServiceMatching("IOHIDPointing")) {
       
  1608         methods = (methods | QSystemDeviceInfo::Mouse);
       
  1609     }
       
  1610     return methods;
       
  1611 }
       
  1612 
       
  1613 
       
  1614 QSystemDeviceInfo::PowerState QSystemDeviceInfoPrivate::currentPowerState()
       
  1615 {
       
  1616     QSystemDeviceInfo::PowerState state = QSystemDeviceInfo::UnknownPower;
       
  1617 
       
  1618     CFDictionaryRef powerSourceDict = NULL;
       
  1619     CFStringRef powerStateString;
       
  1620 
       
  1621     CFTypeRef powerSourcesInfoBlob = IOPSCopyPowerSourcesInfo();
       
  1622     CFArrayRef powerSourcesList = IOPSCopyPowerSourcesList(powerSourcesInfoBlob);
       
  1623     int i;
       
  1624     for (i=0; i<CFArrayGetCount(powerSourcesList); i++) {
       
  1625         powerSourceDict = IOPSGetPowerSourceDescription(powerSourcesInfoBlob, /* [powerSourcesList objectAtIndex:0]*/ CFArrayGetValueAtIndex(powerSourcesList, i));
       
  1626         if(!powerSourceDict) {
       
  1627             state = QSystemDeviceInfo::UnknownPower;
       
  1628             break;
       
  1629         }
       
  1630 
       
  1631         powerStateString = (CFStringRef)CFDictionaryGetValue(powerSourceDict, CFSTR(kIOPSPowerSourceStateKey));
       
  1632         if(CFStringCompare(powerStateString,CFSTR(kIOPSBatteryPowerValue),0)==kCFCompareEqualTo) {
       
  1633             //has battery
       
  1634             state = QSystemDeviceInfo::BatteryPower;
       
  1635         } else {
       
  1636 
       
  1637             NSDictionary *powerSourceInfo = nil;
       
  1638             powerSourceInfo = [NSDictionary dictionaryWithDictionary:(NSDictionary*)powerSourceDict];
       
  1639             bool charging = (bool)[[powerSourceInfo valueForKey:[NSString stringWithUTF8String:kIOPSIsChargingKey]] boolValue];
       
  1640             if (charging ) {
       
  1641                 state = QSystemDeviceInfo::WallPowerChargingBattery;
       
  1642             } else {
       
  1643                 state = QSystemDeviceInfo::WallPower;
       
  1644             }
       
  1645         }
       
  1646     }
       
  1647 
       
  1648     CFRelease(powerSourcesInfoBlob);
       
  1649     CFRelease(powerSourcesList);
       
  1650 
       
  1651     if( currentPowerStateCache != state) {
       
  1652         currentPowerStateCache = state;
       
  1653         Q_EMIT powerStateChanged(state);
       
  1654     }
       
  1655     return state;
       
  1656 }
       
  1657 
       
  1658 QString QSystemDeviceInfoPrivate::imei()
       
  1659 {
       
  1660     return "";
       
  1661 }
       
  1662 
       
  1663 QString QSystemDeviceInfoPrivate::imsi()
       
  1664 {
       
  1665     return "";
       
  1666 }
       
  1667 
       
  1668 QString QSystemDeviceInfoPrivate::manufacturer()
       
  1669 {
       
  1670     return QString("Apple"); //pretty sure we can hardcode this one
       
  1671 }
       
  1672 
       
  1673 QString QSystemDeviceInfoPrivate::model()
       
  1674 {
       
  1675     char modelBuffer[256];
       
  1676     QString model;
       
  1677       size_t sz = sizeof(modelBuffer);
       
  1678       if (0 == sysctlbyname("hw.model", modelBuffer, &sz, NULL, 0)) {
       
  1679           model = QLatin1String(modelBuffer);
       
  1680       }
       
  1681     return  model;
       
  1682 }
       
  1683 
       
  1684 QString QSystemDeviceInfoPrivate::productName()
       
  1685 {
       
  1686     return nsstringToQString([[NSDictionary dictionaryWithContentsOfFile:@"/System/Library/CoreServices/SystemVersion.plist"] objectForKey:@"ProductName"]);
       
  1687 }
       
  1688 
       
  1689 int QSystemDeviceInfoPrivate::batteryLevel()
       
  1690 {
       
  1691     float level = 0;
       
  1692     CFDictionaryRef powerSourceDict = NULL;
       
  1693     CFTypeRef powerSourcesInfoBlob = IOPSCopyPowerSourcesInfo();
       
  1694     CFArrayRef powerSourcesList = IOPSCopyPowerSourcesList(powerSourcesInfoBlob);
       
  1695     int i;
       
  1696     for (i=0; i<CFArrayGetCount(powerSourcesList); i++) {
       
  1697         powerSourceDict = IOPSGetPowerSourceDescription(powerSourcesInfoBlob, /* [powerSourcesList objectAtIndex:0]*/ CFArrayGetValueAtIndex(powerSourcesList, i));
       
  1698         if(!powerSourceDict) {
       
  1699             break;
       
  1700         }
       
  1701 
       
  1702         float currentLevel = 0;
       
  1703         float maxLevel = 0;
       
  1704         const void *powerStateValue;
       
  1705 
       
  1706         powerStateValue = CFDictionaryGetValue(powerSourceDict, CFSTR(kIOPSCurrentCapacityKey));
       
  1707         CFNumberGetValue((CFNumberRef)powerStateValue, kCFNumberSInt32Type, &currentLevel);
       
  1708 
       
  1709         powerStateValue = CFDictionaryGetValue(powerSourceDict, CFSTR(kIOPSMaxCapacityKey));
       
  1710         CFNumberGetValue((CFNumberRef)powerStateValue, kCFNumberSInt32Type, &maxLevel);
       
  1711         level = (currentLevel/maxLevel) * 100;
       
  1712     }
       
  1713 
       
  1714     CFRelease(powerSourcesInfoBlob);
       
  1715     CFRelease(powerSourcesList);
       
  1716 
       
  1717     if(batteryLevelCache != level) {
       
  1718         batteryLevelCache = level;
       
  1719         Q_EMIT batteryLevelChanged(level);
       
  1720     }
       
  1721 
       
  1722     if(batteryLevelCache < 4 && batteryStatusCache != QSystemDeviceInfo::BatteryCritical) {
       
  1723         batteryStatusCache = QSystemDeviceInfo::BatteryCritical;
       
  1724         Q_EMIT batteryStatusChanged(batteryStatusCache);
       
  1725     } else if((batteryLevelCache > 3 && batteryLevelCache < 11) && batteryStatusCache != QSystemDeviceInfo::BatteryVeryLow) {
       
  1726         batteryStatusCache = QSystemDeviceInfo::BatteryVeryLow;
       
  1727         Q_EMIT batteryStatusChanged(batteryStatusCache);
       
  1728     } else if((batteryLevelCache > 10 && batteryLevelCache < 41) && batteryStatusCache != QSystemDeviceInfo::BatteryLow) {
       
  1729         batteryStatusCache = QSystemDeviceInfo::BatteryLow;
       
  1730         Q_EMIT batteryStatusChanged(batteryStatusCache);
       
  1731     } else if(batteryLevelCache > 40 && batteryStatusCache != QSystemDeviceInfo::BatteryNormal) {
       
  1732         batteryStatusCache = QSystemDeviceInfo::BatteryNormal;
       
  1733         Q_EMIT batteryStatusChanged(batteryStatusCache);
       
  1734     }
       
  1735 
       
  1736     return (int)level;
       
  1737 }
       
  1738 
       
  1739 QSystemDeviceInfo::SimStatus QSystemDeviceInfoPrivate::simStatus()
       
  1740 {
       
  1741     return QSystemDeviceInfo::SimNotAvailable;
       
  1742 }
       
  1743 
       
  1744 bool QSystemDeviceInfoPrivate::isDeviceLocked()
       
  1745 {
       
  1746     // find out if auto login is being used.
       
  1747     QSettings loginSettings("/Library/Preferences/com.apple.loginwindow.plist", QSettings::NativeFormat);
       
  1748     QString autologinname = loginSettings.value("autoLoginUser").toString();
       
  1749 
       
  1750 // find out if locked screensaver is used.
       
  1751     int passWordProtected = 0;
       
  1752 #if defined(QT_ARCH_X86_64)  && !defined(MAC_SDK_10_6)
       
  1753     ScreenSaverDefaults *ssDefaults;
       
  1754     ssDefaults = [ScreenSaverDefaults defaultsForModuleWithName:@"com.apple.screensaver"];
       
  1755     passWordProtected = [ssDefaults integerForKey:@"askForPassword"];
       
  1756 #endif
       
  1757 
       
  1758     if(autologinname.isEmpty() || passWordProtected == 1) {
       
  1759         return true;
       
  1760     } else {
       
  1761         return false;
       
  1762     }
       
  1763 }
       
  1764 
       
  1765 QSystemScreenSaverPrivate::QSystemScreenSaverPrivate(QObject *parent)
       
  1766         : QObject(parent), isInhibited(0)
       
  1767 {
       
  1768     ssTimer = new QTimer(this);
       
  1769     connect(ssTimer, SIGNAL(timeout()), this, SLOT(activityTimeout()));
       
  1770 }
       
  1771 
       
  1772 QSystemScreenSaverPrivate::~QSystemScreenSaverPrivate()
       
  1773 {
       
  1774     if(ssTimer->isActive())
       
  1775         ssTimer->stop();
       
  1776 }
       
  1777 
       
  1778 bool QSystemScreenSaverPrivate::setScreenSaverInhibit()
       
  1779 {
       
  1780     activityTimeout();
       
  1781     ssTimer->start(1000 * 60);
       
  1782     if(ssTimer->isActive()) {
       
  1783         isInhibited = true;
       
  1784         return isInhibited;
       
  1785     }
       
  1786 
       
  1787     return false;
       
  1788 }
       
  1789 
       
  1790 
       
  1791 bool QSystemScreenSaverPrivate::screenSaverInhibited()
       
  1792 {
       
  1793     return isInhibited;
       
  1794 }
       
  1795 
       
  1796 void QSystemScreenSaverPrivate::activityTimeout()
       
  1797 {
       
  1798     UpdateSystemActivity(OverallAct);
       
  1799 }
       
  1800 
       
  1801 #include "moc_qsysteminfo_mac_p.cpp"
       
  1802 
       
  1803 QTM_END_NAMESPACE