Bug 1058766 - Include window count for each application, r=jesup.
authorMatthew A. Miller <linuxwolf@outer-planes.net>
Tue, 26 Aug 2014 16:29:35 -0600
changeset 223616 5229e47c07b24318b6b96f684a248c23b271b420
parent 223615 ffc10f34de13e81ad5ff359dc6297983ac81f929
child 223617 226c2201e2854f4711f8cb2f6c2838a7e4ab7bab
push id3979
push userraliiev@mozilla.com
push dateMon, 13 Oct 2014 16:35:44 +0000
treeherdermozilla-beta@30f2cc610691 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjesup
bugs1058766
milestone34.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1058766 - Include window count for each application, r=jesup.
media/webrtc/trunk/webrtc/modules/desktop_capture/desktop_device_info.cc
media/webrtc/trunk/webrtc/modules/desktop_capture/desktop_device_info.h
media/webrtc/trunk/webrtc/modules/desktop_capture/mac/desktop_device_info_mac.mm
media/webrtc/trunk/webrtc/modules/desktop_capture/win/desktop_device_info_win.cc
media/webrtc/trunk/webrtc/modules/desktop_capture/x11/desktop_device_info_x11.cc
--- a/media/webrtc/trunk/webrtc/modules/desktop_capture/desktop_device_info.cc
+++ b/media/webrtc/trunk/webrtc/modules/desktop_capture/desktop_device_info.cc
@@ -80,20 +80,21 @@ DesktopDisplayDevice& DesktopDisplayDevi
   setUniqueIdName(other.getUniqueIdName());
   setDeviceName(other.getDeviceName());
 
   return *this;
 }
 
 
 DesktopApplication::DesktopApplication() {
-  processId_ =0;
+  processId_ = 0;
   processPathNameUTF8_= NULL;
   applicationNameUTF8_= NULL;
   processUniqueIdUTF8_= NULL;
+  windowCount_ = 0;
 }
 
 DesktopApplication::~DesktopApplication() {
 }
 
 void DesktopApplication::setProcessId(const ProcessId processId) {
   processId_ = processId;
 }
@@ -105,32 +106,40 @@ void DesktopApplication::setProcessPathN
 void DesktopApplication::setUniqueIdName(const char *appUniqueIdUTF8) {
   SetStringMember(&processUniqueIdUTF8_, appUniqueIdUTF8);
 }
 
 void DesktopApplication::setProcessAppName(const char *appNameUTF8) {
   SetStringMember(&applicationNameUTF8_, appNameUTF8);
 }
 
+void DesktopApplication::setWindowCount(const uint32_t count) {
+  windowCount_ = count;
+}
+
 ProcessId DesktopApplication::getProcessId() {
   return processId_;
 }
 
 const char *DesktopApplication::getProcessPathName() {
   return processPathNameUTF8_;
 }
 
 const char *DesktopApplication::getUniqueIdName() {
   return processUniqueIdUTF8_;
 }
 
 const char *DesktopApplication::getProcessAppName() {
   return applicationNameUTF8_;
 }
 
+uint32_t DesktopApplication::getWindowCount() {
+  return windowCount_;
+}
+
 DesktopApplication& DesktopApplication::operator= (DesktopApplication& other) {
   processId_ = other.getProcessId();
   setProcessPathName(other.getProcessPathName());
   setUniqueIdName(other.getUniqueIdName());
   setProcessAppName(other.getProcessAppName());
 
   return *this;
 }
--- a/media/webrtc/trunk/webrtc/modules/desktop_capture/desktop_device_info.h
+++ b/media/webrtc/trunk/webrtc/modules/desktop_capture/desktop_device_info.h
@@ -37,32 +37,35 @@ class DesktopApplication {
 public:
   DesktopApplication();
   ~DesktopApplication();
 
   void setProcessId(const ProcessId processId);
   void setProcessPathName(const char *appPathNameUTF8);
   void setUniqueIdName(const char *appUniqueIdUTF8);
   void setProcessAppName(const char *appNameUTF8);
+  void setWindowCount(const uint32_t count);
 
   ProcessId getProcessId();
   const char *getProcessPathName();
   const char *getUniqueIdName();
   const char *getProcessAppName();
+  uint32_t getWindowCount();
 
   DesktopApplication& operator= (DesktopApplication& other);
 
 protected:
   ProcessId processId_;
   char* processPathNameUTF8_;
   char* applicationNameUTF8_;
   char* processUniqueIdUTF8_;
+  uint32_t windowCount_;
 };
 
-typedef std::map<intptr_t,DesktopApplication*> DesktopApplicationList;
+typedef std::map<intptr_t, DesktopApplication*> DesktopApplicationList;
 
 class DesktopDeviceInfo {
 public:
   virtual ~DesktopDeviceInfo() {};
 
   virtual int32_t Init() = 0;
   virtual int32_t Refresh() = 0;
   virtual int32_t getDisplayDeviceCount() = 0;
--- a/media/webrtc/trunk/webrtc/modules/desktop_capture/mac/desktop_device_info_mac.mm
+++ b/media/webrtc/trunk/webrtc/modules/desktop_capture/mac/desktop_device_info_mac.mm
@@ -2,19 +2,23 @@
  * License, v. 2.0. If a copy of the MPL was not distributed with this file,
  * You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "webrtc/modules/desktop_capture/mac/desktop_device_info_mac.h"
 #include <AppKit/AppKit.h>
 #include <Cocoa/Cocoa.h>
 #include <unistd.h>
 #include <stdio.h>
+#include <map>
 
 namespace webrtc {
 
+// Helper type to track the number of window instances for a given process
+typedef std::map<ProcessId, uint32_t> AppWindowCountMap;
+
 #define MULTI_MONITOR_NO_SUPPORT 1
 
 DesktopDeviceInfo * DesktopDeviceInfoImpl::Create() {
   DesktopDeviceInfoMac * pDesktopDeviceInfo = new DesktopDeviceInfoMac();
   if (pDesktopDeviceInfo && pDesktopDeviceInfo->Init() != 0){
     delete pDesktopDeviceInfo;
     pDesktopDeviceInfo = NULL;
   }
@@ -44,16 +48,38 @@ void DesktopDeviceInfoMac::MultiMonitorS
 void DesktopDeviceInfoMac::InitializeScreenList() {
 #if !defined(MULTI_MONITOR_SCREENSHARE)
   MultiMonitorScreenshare();
 #endif
 }
 void DesktopDeviceInfoMac::InitializeApplicationList() {
   //List all running applications (excluding background processes).
 
+  // Get a list of all windows, to match to applications
+  AppWindowCountMap appWins;
+  CFArrayRef windowInfos = CGWindowListCopyWindowInfo(
+      kCGWindowListOptionOnScreenOnly | kCGWindowListExcludeDesktopElements,
+      kCGNullWindowID);
+  CFIndex windowInfosCount = CFArrayGetCount(windowInfos);
+  for (CFIndex idx = 0; idx < windowInfosCount; idx++) {
+    CFDictionaryRef info = reinterpret_cast<CFDictionaryRef>(
+        CFArrayGetValueAtIndex(windowInfos, idx));
+    CFNumberRef winOwner = reinterpret_cast<CFNumberRef>(
+        CFDictionaryGetValue(info, kCGWindowOwnerPID));
+
+    pid_t owner;
+    CFNumberGetValue(winOwner, kCFNumberIntType, &owner);
+    AppWindowCountMap::iterator itr = appWins.find(owner);
+    if (itr == appWins.end()) {
+      appWins[owner] = 1;
+    } else {
+      appWins[owner]++;
+    }
+  }
+
   NSArray *running = [[NSWorkspace sharedWorkspace] runningApplications];
   for (NSRunningApplication *ra in running) {
     if (ra.activationPolicy != NSApplicationActivationPolicyRegular)
       continue;
 
     ProcessId pid = ra.processIdentifier;
     if (pid == 0) {
       continue;
@@ -63,23 +89,28 @@ void DesktopDeviceInfoMac::InitializeApp
     }
 
     DesktopApplication *pDesktopApplication = new DesktopApplication;
     if (!pDesktopApplication) {
       continue;
     }
 
     pDesktopApplication->setProcessId(pid);
+    pDesktopApplication->setWindowCount(appWins[pid]);
 
     NSString *str;
     str = [ra.executableURL absoluteString];
     pDesktopApplication->setProcessPathName([str UTF8String]);
 
+    // Record <window count> then <localized name>
+    // NOTE: localized names can get *VERY* long
     str = ra.localizedName;
-    pDesktopApplication->setProcessAppName([str UTF8String]);
+    char nameStr[BUFSIZ];
+    snprintf(nameStr, sizeof(nameStr), "%d\x1e%s", pDesktopApplication->getWindowCount(), [str UTF8String]);
+    pDesktopApplication->setProcessAppName(nameStr);
 
     char idStr[64];
     snprintf(idStr, sizeof(idStr), "%ld", pDesktopApplication->getProcessId());
     pDesktopApplication->setUniqueIdName(idStr);
 
     desktop_application_list_[pDesktopApplication->getProcessId()] = pDesktopApplication;
   }
 }
--- a/media/webrtc/trunk/webrtc/modules/desktop_capture/win/desktop_device_info_win.cc
+++ b/media/webrtc/trunk/webrtc/modules/desktop_capture/win/desktop_device_info_win.cc
@@ -49,36 +49,45 @@ void DesktopDeviceInfoWin::InitializeScr
 #if !defined(MULTI_MONITOR_SCREENSHARE)
   MultiMonitorScreenshare();
 #endif
 }
 void DesktopDeviceInfoWin::InitializeApplicationList() {
   // List all running applications exclude background process.
   HWND hWnd;
   for (hWnd = GetWindow(GetDesktopWindow(), GW_CHILD); hWnd; hWnd = GetWindow(hWnd, GW_HWNDNEXT)) {
-    if (!IsWindowVisible(hWnd))
+    if (!IsWindowVisible(hWnd)) {
       continue;
+    }
 
     DWORD dwProcessId = 0;
     GetWindowThreadProcessId(hWnd, &dwProcessId);
 
-    // filter out non-process, current process, or any already seen processes
-    if (dwProcessId == 0 || dwProcessId == GetCurrentProcessId() ||
-        desktop_application_list_.find(dwProcessId) != desktop_application_list_.end()) {
+    // filter out non-process, current process
+    if (dwProcessId == 0 || dwProcessId == GetCurrentProcessId()) {
+      continue;
+    }
+
+    // filter out already-seen processes, after updating the window count
+    DesktopApplicationList::iterator itr = desktop_application_list_.find(dwProcessId);
+    if (itr != desktop_application_list_.end()) {
+      itr->second->setWindowCount(itr->second->getWindowCount() + 1);
       continue;
     }
 
     // Add one application
     DesktopApplication *pDesktopApplication = new DesktopApplication;
     if (!pDesktopApplication) {
       continue;
     }
 
     // process id
     pDesktopApplication->setProcessId(dwProcessId);
+    // initialize window count to 1 (updated on subsequent finds)
+    pDesktopApplication->setWindowCount(1);
 
     // process path name
     WCHAR szFilePathName[MAX_PATH]={0};
     decltype(QueryFullProcessImageName) *lpfnQueryFullProcessImageNameProc =
       reinterpret_cast<decltype(QueryFullProcessImageName) *>(GetProcAddress(GetModuleHandle(TEXT("kernel32.dll")), "QueryFullProcessImageNameW"));
     if (lpfnQueryFullProcessImageNameProc) {
       // After Vista
       DWORD dwMaxSize = _MAX_PATH;
@@ -117,11 +126,23 @@ void DesktopDeviceInfoWin::InitializeApp
 
     // unique id name
     char idStr[64];
     _snprintf_s(idStr, sizeof(idStr), sizeof(idStr) - 1, "%ld", pDesktopApplication->getProcessId());
     pDesktopApplication->setUniqueIdName(idStr);
 
     desktop_application_list_[pDesktopApplication->getProcessId()] = pDesktopApplication;
   }
+
+  // re-walk the application list, prepending the window count to the application name
+  DesktopApplicationList::iterator itr;
+  for (itr = desktop_application_list_.begin(); itr != desktop_application_list_.end(); itr++) {
+    DesktopApplication *pApp = itr->second;
+
+    // localized application names can be *VERY* large
+    char nameStr[BUFSIZ];
+    _snprintf_s(nameStr, sizeof(nameStr), sizeof(nameStr) - 1, "%d\x1e%s",
+                pApp->getWindowCount(), pApp->getProcessAppName());
+    pApp->setProcessAppName(nameStr);
+  }
 }
 
 } // namespace webrtc
--- a/media/webrtc/trunk/webrtc/modules/desktop_capture/x11/desktop_device_info_x11.cc
+++ b/media/webrtc/trunk/webrtc/modules/desktop_capture/x11/desktop_device_info_x11.cc
@@ -82,39 +82,59 @@ void DesktopDeviceInfoX11::InitializeApp
       if (processId == 0) {
         continue;
       }
       // filter out current process
       if (processId == getpid()) {
         continue;
       }
 
+      // filter out existing applications, after incrementing its window count
+      DesktopApplicationList::iterator itr = desktop_application_list_.find(processId);
+      if (itr != desktop_application_list_.end()) {
+        itr->second->setWindowCount(itr->second->getWindowCount() + 1);
+        continue;
+      }
+
       // Add one application
       DesktopApplication *pDesktopApplication = new DesktopApplication;
       if (!pDesktopApplication) {
         continue;
       }
 
       // process id
       pDesktopApplication->setProcessId(processId);
+      // initialize count to 1
+      pDesktopApplication->setWindowCount(1);
 
       // process path name
       pDesktopApplication->setProcessPathName("");
 
       // application name
       std::string strAppName;
       window_util_x11.GetWindowTitle(app_window, &strAppName);
       pDesktopApplication->setProcessAppName(strAppName.c_str());
 
       // unique id name
       char idStr[64];
       snprintf(idStr, sizeof(idStr), "%ld", pDesktopApplication->getProcessId());
       pDesktopApplication->setUniqueIdName(idStr);
       desktop_application_list_[processId] = pDesktopApplication;
     }
 
+    // re-walk the application list, prepending the window count to the application name
+    DesktopApplicationList::iterator itr;
+    for (itr = desktop_application_list_.begin(); itr != desktop_application_list_.end(); itr++) {
+      DesktopApplication *pApp = itr->second;
+      // localized name can be *VERY* large
+      char nameStr[BUFSIZ];
+      snprintf(nameStr, sizeof(nameStr), "%d\x1e%s",
+               pApp->getWindowCount(), pApp->getProcessAppName());
+      pApp->setProcessAppName(nameStr);
+    }
+
     if (children) {
       XFree(children);
     }
   }
 }
 
 } //namespace webrtc