qtmobility/src/systeminfo/qsysteminfo_mac.mm
changeset 14 6fbed849b4f4
parent 11 06b8e2af4411
equal deleted inserted replaced
11:06b8e2af4411 14:6fbed849b4f4
   121 #include <net/if_types.h>
   121 #include <net/if_types.h>
   122 #include <net/if_media.h>
   122 #include <net/if_media.h>
   123 #include <sys/ioctl.h>
   123 #include <sys/ioctl.h>
   124 #include <sys/socket.h>
   124 #include <sys/socket.h>
   125 
   125 
       
   126 
   126 static QString stringFromCFString(CFStringRef value) {
   127 static QString stringFromCFString(CFStringRef value) {
   127     QString retVal;
   128     QString retVal;
   128     if(CFStringGetLength(value) > 1) {
   129     if(CFStringGetLength(value) > 1) {
   129         CFIndex maxLength = 2 * CFStringGetLength(value) + 1/*zero term*/; // max UTF8
   130         CFIndex maxLength = 2 * CFStringGetLength(value) + 1/*zero term*/; // max UTF8
   130         char *cstring = new char[maxLength];
   131         char *cstring = new char[maxLength];
   304 #endif
   305 #endif
   305 NSObject* delegate;
   306 NSObject* delegate;
   306 
   307 
   307 QTM_BEGIN_NAMESPACE
   308 QTM_BEGIN_NAMESPACE
   308 
   309 
       
   310 Q_GLOBAL_STATIC(QSystemDeviceInfoPrivate, qsystemDeviceInfoPrivate)
       
   311 
   309 QSystemInfoPrivate *QSystemInfoPrivate::self = 0;
   312 QSystemInfoPrivate *QSystemInfoPrivate::self = 0;
   310 
   313 
   311 QSystemInfoPrivate::QSystemInfoPrivate(QObject *parent)
   314 QSystemInfoPrivate::QSystemInfoPrivate(QObject *parent)
   312  : QObject(parent)
   315  : QObject(parent)
   313 {
   316 {
   317 
   320 
   318 QSystemInfoPrivate::~QSystemInfoPrivate()
   321 QSystemInfoPrivate::~QSystemInfoPrivate()
   319 {
   322 {
   320     if(langloopThread->isRunning()) {
   323     if(langloopThread->isRunning()) {
   321         langloopThread->quit();
   324         langloopThread->quit();
   322         langloopThread->wait();
       
   323     }
   325     }
   324 }
   326 }
   325 
   327 
   326 QString QSystemInfoPrivate::currentLanguage() const
   328 QString QSystemInfoPrivate::currentLanguage() const
   327 {
   329 {
   521 
   523 
   522     return;
   524     return;
   523 }
   525 }
   524 
   526 
   525 #ifdef MAC_SDK_10_6
   527 #ifdef MAC_SDK_10_6
   526 #endif
   528 QtMLangListener *langListener;
       
   529 #endif
       
   530 
       
   531 
   527 QLangLoopThread::QLangLoopThread(QObject *parent)
   532 QLangLoopThread::QLangLoopThread(QObject *parent)
   528     :QThread(parent)
   533     :QThread(parent)
   529 {
   534 {
   530 }
   535 }
   531 
   536 
   535 
   540 
   536 void QLangLoopThread::quit()
   541 void QLangLoopThread::quit()
   537 {
   542 {
   538     mutex.lock();
   543     mutex.lock();
   539     keepRunning = false;
   544     keepRunning = false;
       
   545     CFRunLoopStop(CFRunLoopGetCurrent());
       
   546 #ifdef MAC_SDK_10_6
       
   547     [langListener release];
       
   548 #endif
   540     mutex.unlock();
   549     mutex.unlock();
       
   550     wait();
   541 }
   551 }
   542 
   552 
   543 void QLangLoopThread::run()
   553 void QLangLoopThread::run()
   544 {
   554 {
   545 #ifdef MAC_SDK_10_6
   555 #ifdef MAC_SDK_10_6
   546     mutex.lock();
   556     mutex.lock();
   547     keepRunning = true;
   557     keepRunning = true;
   548     mutex.unlock();
   558     mutex.unlock();
   549     NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
   559     NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
   550 
   560 
   551     QtMLangListener *listener;
   561     langListener = [[QtMLangListener alloc] init];
   552     listener = [[QtMLangListener alloc] init];
       
   553 
   562 
   554     NSDate *loopUntil = [NSDate dateWithTimeIntervalSinceNow:1.0];
   563     NSDate *loopUntil = [NSDate dateWithTimeIntervalSinceNow:1.0];
   555     while (keepRunning &&
   564     while (keepRunning &&
   556         [[NSRunLoop currentRunLoop] runMode: NSDefaultRunLoopMode beforeDate: loopUntil]) {
   565         [[NSRunLoop currentRunLoop] runMode: NSDefaultRunLoopMode beforeDate: loopUntil]) {
   557         loopUntil = [NSDate dateWithTimeIntervalSinceNow:1.0];
   566         loopUntil = [NSDate dateWithTimeIntervalSinceNow:1.0];
   569 {
   578 {
   570 }
   579 }
   571 
   580 
   572 QRunLoopThread::~QRunLoopThread()
   581 QRunLoopThread::~QRunLoopThread()
   573 {
   582 {
   574 #ifdef MAC_SDK_10_6
   583 }
   575     [listener dealloc];
   584 
   576 #endif
   585 void QRunLoopThread::stop()
   577 }
   586 {
   578 
       
   579 void QRunLoopThread::quit()
       
   580 {
       
   581     CFRelease(runloopSource);
       
   582     mutex.lock();
   587     mutex.lock();
   583     keepRunning = false;
   588     keepRunning = false;
   584     mutex.unlock();
   589     mutex.unlock();
   585     CFRelease(storeSession);
   590 #ifdef MAC_SDK_10_6
       
   591     [listener release];
       
   592     [delegate release];
       
   593 #endif
       
   594     if(currentThread() != this) {
       
   595         QMetaObject::invokeMethod(this, "quit",
       
   596                                   Qt::QueuedConnection);
       
   597     } else {
       
   598         quit();
       
   599     }
       
   600     wait();
   586 }
   601 }
   587 
   602 
   588 
   603 
   589 void QRunLoopThread::run()
   604 void QRunLoopThread::run()
   590 {
   605 {
   598     keepRunning = true;
   613     keepRunning = true;
   599     mutex.unlock();
   614     mutex.unlock();
   600 
   615 
   601     listener = [[QtMNSListener alloc] init];
   616     listener = [[QtMNSListener alloc] init];
   602 
   617 
   603     NSDate *loopUntil = [NSDate dateWithTimeIntervalSinceNow:1.0];
   618     SInt32 result;
   604     while (keepRunning &&
   619     while (keepRunning &&
   605         [[NSRunLoop currentRunLoop] runMode: NSDefaultRunLoopMode beforeDate: loopUntil]) {
   620            (result = CFRunLoopRunInMode(kCFRunLoopDefaultMode ,5, YES))) {
   606         loopUntil = [NSDate dateWithTimeIntervalSinceNow:1.0];
   621     }
   607     }
   622     CFRunLoopStop(CFRunLoopGetCurrent());
   608     [pool release];
   623     [pool release];
   609 #endif
   624 #endif
   610 }
   625 }
   611 
   626 
   612 void QRunLoopThread::startNetworkChangeLoop()
   627 void QRunLoopThread::startNetworkChangeLoop()
   685         CFRelease(storeSession);
   700         CFRelease(storeSession);
   686         return;
   701         return;
   687     }
   702     }
   688 
   703 
   689     CFRunLoopAddSource(CFRunLoopGetCurrent(), runloopSource, kCFRunLoopDefaultMode);
   704     CFRunLoopAddSource(CFRunLoopGetCurrent(), runloopSource, kCFRunLoopDefaultMode);
       
   705     CFRelease(runloopSource);
       
   706     CFRelease(storeSession);
   690     return;
   707     return;
       
   708 }
       
   709 
       
   710 
       
   711 static bool isBtPowerOn()
       
   712 {
       
   713     //depreciated yes, but what's the replacement?
       
   714     BluetoothHCIPowerState powerState;
       
   715     IOBluetoothLocalDeviceGetPowerState(&powerState);
       
   716     if(powerState == kBluetoothHCIPowerStateON)
       
   717         return true;
       
   718     return false;
       
   719 }
       
   720 
       
   721 void btPowerStateChange(void *ref, io_service_t /*service*/, natural_t messageType, void */*info*/)
       
   722 {
       
   723     QBluetoothListenerThread * thread = reinterpret_cast< QBluetoothListenerThread *>(ref);
       
   724     switch (messageType) {
       
   725     case kIOMessageDeviceWillPowerOff:
       
   726         {
       
   727             if(!isBtPowerOn())
       
   728                 thread->emitBtPower(false);
       
   729         }
       
   730         break;
       
   731     case kIOMessageDeviceHasPoweredOn:
       
   732         {
       
   733             if(isBtPowerOn())
       
   734                 thread->emitBtPower(true);
       
   735         }
       
   736         break;
       
   737     }
       
   738 }
       
   739 
       
   740 QBluetoothListenerThread::QBluetoothListenerThread(QObject *parent)
       
   741     :QThread(parent)
       
   742 {
       
   743     setTerminationEnabled(true);
       
   744 }
       
   745 
       
   746 QBluetoothListenerThread::~QBluetoothListenerThread()
       
   747 {
       
   748     if(isRunning()) {
       
   749         terminate();
       
   750         wait();
       
   751     }
       
   752 }
       
   753 
       
   754 void QBluetoothListenerThread::stop()
       
   755 {
       
   756     mutex.lock();
       
   757     keepRunning = false;
       
   758     mutex.unlock();
       
   759 
       
   760     if(CFRunLoopContainsSource(rl,rls,kCFRunLoopDefaultMode)) {
       
   761         CFRunLoopRemoveSource(rl,
       
   762                               rls,
       
   763                               kCFRunLoopDefaultMode);
       
   764         CFRunLoopStop(rl);
       
   765     }
       
   766     if(currentThread() != this) {
       
   767         QMetaObject::invokeMethod(this, "quit",
       
   768                                   Qt::QueuedConnection);
       
   769     } else {
       
   770         quit();
       
   771     }
       
   772     mutex.lock();
       
   773     IONotificationPortDestroy(port);
       
   774     mutex.unlock();
       
   775 }
       
   776 
       
   777 void QBluetoothListenerThread::run()
       
   778 {
       
   779 #ifdef MAC_SDK_10_6
       
   780     mutex.lock();
       
   781     keepRunning = true;
       
   782     mutex.unlock();
       
   783     NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
       
   784     io_object_t notifyObject;
       
   785     io_service_t bluetoothservice;
       
   786 
       
   787     io_iterator_t ioIterator;
       
   788     mach_port_t masterPort;
       
   789     CFMutableDictionaryRef serviceMatchDict;
       
   790 
       
   791     if (0 != IOMasterPort(MACH_PORT_NULL, &masterPort)) {
       
   792         qDebug() << "IOMasterPort failed";
       
   793     }
       
   794 
       
   795     serviceMatchDict = IOServiceMatching("IOBluetoothHCIController");
       
   796     if (NULL == serviceMatchDict) {
       
   797         qDebug() << "IOServiceMatching failed";
       
   798     }
       
   799 
       
   800     if (0 != IOServiceGetMatchingServices(masterPort, serviceMatchDict, &ioIterator)) {
       
   801         qDebug() << "IOServiceGetMatchingServices failed";
       
   802     }
       
   803 
       
   804     IOReturn ret;
       
   805 
       
   806     bluetoothservice = IOIteratorNext(ioIterator);
       
   807     if (0 == bluetoothservice) {
       
   808         IOObjectRelease(ioIterator);
       
   809         qDebug() << "IOIteratorNext failed";
       
   810     }
       
   811     IOObjectRelease(ioIterator);
       
   812 
       
   813     port = IONotificationPortCreate(masterPort);
       
   814     if (0 == port) {
       
   815         qDebug() << "IONotificationPortCreate failed";
       
   816     }
       
   817 
       
   818     ret = IOServiceAddInterestNotification(port, bluetoothservice,
       
   819                                            kIOGeneralInterest, btPowerStateChange,
       
   820                                            this, &notifyObject);
       
   821     if(ret != kIOReturnSuccess) {
       
   822         qDebug() << "IOServiceAddInterestNotification failed";
       
   823         return;
       
   824     }
       
   825 
       
   826     rl = CFRunLoopGetCurrent();
       
   827     rls = IONotificationPortGetRunLoopSource(port);
       
   828 
       
   829     CFRunLoopAddSource(rl,
       
   830                        rls,
       
   831                        kCFRunLoopDefaultMode);
       
   832     SInt32 result;
       
   833     while (keepRunning &&
       
   834            (result = CFRunLoopRunInMode(kCFRunLoopDefaultMode ,1, NO))) {
       
   835     }
       
   836 
       
   837     CFRunLoopStop(rl);
       
   838 
       
   839     IOObjectRelease(bluetoothservice);
       
   840     CFRunLoopRemoveSource(rl,
       
   841                           rls,
       
   842                           kCFRunLoopDefaultMode);
       
   843     [pool release];
       
   844 #endif
       
   845 }
       
   846 
       
   847 void QBluetoothListenerThread::emitBtPower(bool b)
       
   848 {
       
   849     Q_EMIT bluetoothPower(b);
   691 }
   850 }
   692 
   851 
   693 
   852 
   694 QSystemNetworkInfoPrivate::QSystemNetworkInfoPrivate(QObject *parent)
   853 QSystemNetworkInfoPrivate::QSystemNetworkInfoPrivate(QObject *parent)
   695         : QObject(parent), signalStrengthCache(0)
   854         : QObject(parent), signalStrengthCache(0)
   696 {
   855 {
   697      defaultInterface = "";
   856      defaultInterface = "";
   698     qRegisterMetaType<QSystemNetworkInfo::NetworkMode>("QSystemNetworkInfo::NetworkMode");
   857     qRegisterMetaType<QSystemNetworkInfo::NetworkMode>("QSystemNetworkInfo::NetworkMode");
   699     qRegisterMetaType<QSystemNetworkInfo::NetworkStatus>("QSystemNetworkInfo::NetworkStatus");
   858     qRegisterMetaType<QSystemNetworkInfo::NetworkStatus>("QSystemNetworkInfo::NetworkStatus");
       
   859 
   700 #ifdef MAC_SDK_10_6
   860 #ifdef MAC_SDK_10_6
   701 if([[CWInterface supportedInterfaces] count] > 0 ) {
   861 if([[CWInterface supportedInterfaces] count] > 0 ) {
   702         hasWifi = true;
   862         hasWifi = true;
   703     } else {
   863     } else {
   704         hasWifi = false;
   864         hasWifi = false;
   713 
   873 
   714 QSystemNetworkInfoPrivate::~QSystemNetworkInfoPrivate()
   874 QSystemNetworkInfoPrivate::~QSystemNetworkInfoPrivate()
   715 {
   875 {
   716 #ifdef MAC_SDK_10_6
   876 #ifdef MAC_SDK_10_6
   717     if(hasWifi && runloopThread->isRunning()) {
   877     if(hasWifi && runloopThread->isRunning()) {
   718         runloopThread->quit();
   878         runloopThread->stop();
   719         runloopThread->wait();
       
   720         [delegate release];
       
   721     }
   879     }
   722 #endif
   880 #endif
   723 }
   881 }
   724 
   882 
   725 void QSystemNetworkInfoPrivate::primaryInterface()
   883 void QSystemNetworkInfoPrivate::primaryInterface()
  1375         }
  1533         }
  1376     }
  1534     }
  1377     return drivesList;
  1535     return drivesList;
  1378 }
  1536 }
  1379 
  1537 
  1380 QSystemDeviceInfoPrivate *QSystemDeviceInfoPrivate::self = 0;
       
  1381 
       
  1382 void powerInfoChanged(void* runLoopInfo)
  1538 void powerInfoChanged(void* runLoopInfo)
  1383 {
  1539 {
  1384     Q_UNUSED(runLoopInfo)
  1540     Q_UNUSED(runLoopInfo)
  1385     QSystemDeviceInfoPrivate::instance()->batteryLevel();
  1541     QSystemDeviceInfoPrivate::instance()->batteryLevel();
  1386     QSystemDeviceInfoPrivate::instance()->currentPowerState();
  1542     QSystemDeviceInfoPrivate::instance()->currentPowerState();
  1387 }
  1543 }
  1388 
  1544 
  1389 QSystemDeviceInfoPrivate::QSystemDeviceInfoPrivate(QObject *parent)
  1545 QSystemDeviceInfoPrivate::QSystemDeviceInfoPrivate(QObject *parent)
  1390         : QObject(parent)
  1546         : QObject(parent),btThread(0)
  1391 {
  1547 {
  1392     batteryLevelCache = 0;
  1548     batteryLevelCache = 0;
  1393     currentPowerStateCache = QSystemDeviceInfo::UnknownPower;
  1549     currentPowerStateCache = QSystemDeviceInfo::UnknownPower;
  1394     batteryStatusCache = QSystemDeviceInfo::NoBatteryLevel;
  1550     batteryStatusCache = QSystemDeviceInfo::NoBatteryLevel;
  1395     CFRunLoopSourceRef runLoopSource = (CFRunLoopSourceRef)IOPSNotificationCreateRunLoopSource(powerInfoChanged, this);
       
  1396     if (runLoopSource) {
       
  1397         CFRunLoopAddSource(CFRunLoopGetCurrent(), runLoopSource, kCFRunLoopDefaultMode);
       
  1398         CFRelease(runLoopSource);
       
  1399     }
       
  1400     if(!self)
       
  1401         self = this;
       
  1402 }
  1551 }
  1403 
  1552 
  1404 QSystemDeviceInfoPrivate::~QSystemDeviceInfoPrivate()
  1553 QSystemDeviceInfoPrivate::~QSystemDeviceInfoPrivate()
  1405 {
  1554 {
  1406 }
  1555     btThread->stop();
       
  1556 }
       
  1557 
       
  1558 QSystemDeviceInfoPrivate *QSystemDeviceInfoPrivate::instance()
       
  1559 {
       
  1560     return qsystemDeviceInfoPrivate();
       
  1561 }
       
  1562 
       
  1563 void QSystemDeviceInfoPrivate::connectNotify(const char *signal)
       
  1564 {
       
  1565     if (QLatin1String(signal) == SIGNAL(bluetoothStateChanged(bool))) {
       
  1566         if(!btThread) {
       
  1567             btThread = new QBluetoothListenerThread(this);
       
  1568             btThread->start();
       
  1569             connect(btThread,SIGNAL(bluetoothPower(bool)), this, SIGNAL(bluetoothStateChanged(bool)));
       
  1570         }
       
  1571     }
       
  1572 
       
  1573     if (QLatin1String(signal) == SIGNAL(powerStateChanged(QSystemDeviceInfo::PowerState))) {
       
  1574         CFRunLoopSourceRef runLoopSource = (CFRunLoopSourceRef)IOPSNotificationCreateRunLoopSource(powerInfoChanged, this);
       
  1575         if (runLoopSource) {
       
  1576             CFRunLoopAddSource(CFRunLoopGetCurrent(), runLoopSource, kCFRunLoopDefaultMode);
       
  1577             CFRelease(runLoopSource);
       
  1578         }
       
  1579     }
       
  1580 }
       
  1581 
       
  1582 void QSystemDeviceInfoPrivate::disconnectNotify(const char *signal)
       
  1583 {
       
  1584     if (QLatin1String(signal) == SIGNAL(bluetoothStateChanged(bool))) {
       
  1585         if(btThread->isRunning()) {
       
  1586             btThread->stop();
       
  1587         }
       
  1588     }
       
  1589 }
       
  1590 
  1407 
  1591 
  1408 QSystemDeviceInfo::Profile QSystemDeviceInfoPrivate::currentProfile()
  1592 QSystemDeviceInfo::Profile QSystemDeviceInfoPrivate::currentProfile()
  1409 {
  1593 {
  1410     return QSystemDeviceInfo::UnknownProfile;
  1594     return QSystemDeviceInfo::UnknownProfile;
  1411 }
  1595 }