1678f1909fc6918687aedd02949bcdf0f0e1ac682jiayl@webrtc.org/*
2678f1909fc6918687aedd02949bcdf0f0e1ac682jiayl@webrtc.org *  Copyright (c) 2014 The WebRTC project authors. All Rights Reserved.
3678f1909fc6918687aedd02949bcdf0f0e1ac682jiayl@webrtc.org *
4678f1909fc6918687aedd02949bcdf0f0e1ac682jiayl@webrtc.org *  Use of this source code is governed by a BSD-style license
5678f1909fc6918687aedd02949bcdf0f0e1ac682jiayl@webrtc.org *  that can be found in the LICENSE file in the root of the source
6678f1909fc6918687aedd02949bcdf0f0e1ac682jiayl@webrtc.org *  tree. An additional intellectual property rights grant can be found
7678f1909fc6918687aedd02949bcdf0f0e1ac682jiayl@webrtc.org *  in the file PATENTS.  All contributing project authors may
8678f1909fc6918687aedd02949bcdf0f0e1ac682jiayl@webrtc.org *  be found in the AUTHORS file in the root of the source tree.
9678f1909fc6918687aedd02949bcdf0f0e1ac682jiayl@webrtc.org */
10678f1909fc6918687aedd02949bcdf0f0e1ac682jiayl@webrtc.org
11678f1909fc6918687aedd02949bcdf0f0e1ac682jiayl@webrtc.org#include "webrtc/modules/desktop_capture/mac/full_screen_chrome_window_detector.h"
12678f1909fc6918687aedd02949bcdf0f0e1ac682jiayl@webrtc.org
13678f1909fc6918687aedd02949bcdf0f0e1ac682jiayl@webrtc.org#include <assert.h>
14678f1909fc6918687aedd02949bcdf0f0e1ac682jiayl@webrtc.org#include <libproc.h>
15678f1909fc6918687aedd02949bcdf0f0e1ac682jiayl@webrtc.org#include <string>
16678f1909fc6918687aedd02949bcdf0f0e1ac682jiayl@webrtc.org
17678f1909fc6918687aedd02949bcdf0f0e1ac682jiayl@webrtc.org#include "webrtc/base/macutils.h"
18678f1909fc6918687aedd02949bcdf0f0e1ac682jiayl@webrtc.org#include "webrtc/modules/desktop_capture/mac/desktop_configuration.h"
19678f1909fc6918687aedd02949bcdf0f0e1ac682jiayl@webrtc.org#include "webrtc/modules/desktop_capture/mac/window_list_utils.h"
20678f1909fc6918687aedd02949bcdf0f0e1ac682jiayl@webrtc.org#include "webrtc/system_wrappers/interface/logging.h"
21678f1909fc6918687aedd02949bcdf0f0e1ac682jiayl@webrtc.org
22678f1909fc6918687aedd02949bcdf0f0e1ac682jiayl@webrtc.org
23678f1909fc6918687aedd02949bcdf0f0e1ac682jiayl@webrtc.orgnamespace webrtc {
24678f1909fc6918687aedd02949bcdf0f0e1ac682jiayl@webrtc.org
25678f1909fc6918687aedd02949bcdf0f0e1ac682jiayl@webrtc.orgnamespace {
26678f1909fc6918687aedd02949bcdf0f0e1ac682jiayl@webrtc.org
27678f1909fc6918687aedd02949bcdf0f0e1ac682jiayl@webrtc.orgconst int64_t kUpdateIntervalMs = 500;
28678f1909fc6918687aedd02949bcdf0f0e1ac682jiayl@webrtc.org
29678f1909fc6918687aedd02949bcdf0f0e1ac682jiayl@webrtc.org// Returns true if the window is minimized.
30678f1909fc6918687aedd02949bcdf0f0e1ac682jiayl@webrtc.orgbool IsWindowMinimized(CGWindowID id) {
31678f1909fc6918687aedd02949bcdf0f0e1ac682jiayl@webrtc.org  CFArrayRef window_id_array =
32678f1909fc6918687aedd02949bcdf0f0e1ac682jiayl@webrtc.org      CFArrayCreate(NULL, reinterpret_cast<const void **>(&id), 1, NULL);
33678f1909fc6918687aedd02949bcdf0f0e1ac682jiayl@webrtc.org  CFArrayRef window_array =
34678f1909fc6918687aedd02949bcdf0f0e1ac682jiayl@webrtc.org      CGWindowListCreateDescriptionFromArray(window_id_array);
35678f1909fc6918687aedd02949bcdf0f0e1ac682jiayl@webrtc.org  bool minimized = false;
36678f1909fc6918687aedd02949bcdf0f0e1ac682jiayl@webrtc.org
37678f1909fc6918687aedd02949bcdf0f0e1ac682jiayl@webrtc.org  if (window_array && CFArrayGetCount(window_array)) {
38678f1909fc6918687aedd02949bcdf0f0e1ac682jiayl@webrtc.org    CFDictionaryRef window = reinterpret_cast<CFDictionaryRef>(
39678f1909fc6918687aedd02949bcdf0f0e1ac682jiayl@webrtc.org        CFArrayGetValueAtIndex(window_array, 0));
40678f1909fc6918687aedd02949bcdf0f0e1ac682jiayl@webrtc.org    CFBooleanRef on_screen =  reinterpret_cast<CFBooleanRef>(
41678f1909fc6918687aedd02949bcdf0f0e1ac682jiayl@webrtc.org        CFDictionaryGetValue(window, kCGWindowIsOnscreen));
42678f1909fc6918687aedd02949bcdf0f0e1ac682jiayl@webrtc.org
43678f1909fc6918687aedd02949bcdf0f0e1ac682jiayl@webrtc.org    minimized = !on_screen;
44678f1909fc6918687aedd02949bcdf0f0e1ac682jiayl@webrtc.org  }
45678f1909fc6918687aedd02949bcdf0f0e1ac682jiayl@webrtc.org
46678f1909fc6918687aedd02949bcdf0f0e1ac682jiayl@webrtc.org  CFRelease(window_id_array);
47678f1909fc6918687aedd02949bcdf0f0e1ac682jiayl@webrtc.org  CFRelease(window_array);
48678f1909fc6918687aedd02949bcdf0f0e1ac682jiayl@webrtc.org
49678f1909fc6918687aedd02949bcdf0f0e1ac682jiayl@webrtc.org  return minimized;
50678f1909fc6918687aedd02949bcdf0f0e1ac682jiayl@webrtc.org}
51678f1909fc6918687aedd02949bcdf0f0e1ac682jiayl@webrtc.org
52678f1909fc6918687aedd02949bcdf0f0e1ac682jiayl@webrtc.org// Returns true if the window is occupying a full screen.
53678f1909fc6918687aedd02949bcdf0f0e1ac682jiayl@webrtc.orgbool IsWindowFullScreen(const MacDesktopConfiguration& desktop_config,
54678f1909fc6918687aedd02949bcdf0f0e1ac682jiayl@webrtc.org                        CFDictionaryRef window) {
55678f1909fc6918687aedd02949bcdf0f0e1ac682jiayl@webrtc.org  bool fullscreen = false;
56678f1909fc6918687aedd02949bcdf0f0e1ac682jiayl@webrtc.org
57678f1909fc6918687aedd02949bcdf0f0e1ac682jiayl@webrtc.org  CFDictionaryRef bounds_ref = reinterpret_cast<CFDictionaryRef>(
58678f1909fc6918687aedd02949bcdf0f0e1ac682jiayl@webrtc.org      CFDictionaryGetValue(window, kCGWindowBounds));
59678f1909fc6918687aedd02949bcdf0f0e1ac682jiayl@webrtc.org
60678f1909fc6918687aedd02949bcdf0f0e1ac682jiayl@webrtc.org  CGRect bounds;
61678f1909fc6918687aedd02949bcdf0f0e1ac682jiayl@webrtc.org  if (bounds_ref &&
62678f1909fc6918687aedd02949bcdf0f0e1ac682jiayl@webrtc.org      CGRectMakeWithDictionaryRepresentation(bounds_ref, &bounds)) {
63678f1909fc6918687aedd02949bcdf0f0e1ac682jiayl@webrtc.org    for (MacDisplayConfigurations::const_iterator it =
64678f1909fc6918687aedd02949bcdf0f0e1ac682jiayl@webrtc.org             desktop_config.displays.begin();
65678f1909fc6918687aedd02949bcdf0f0e1ac682jiayl@webrtc.org         it != desktop_config.displays.end(); ++it) {
66678f1909fc6918687aedd02949bcdf0f0e1ac682jiayl@webrtc.org      if (it->bounds.equals(DesktopRect::MakeXYWH(bounds.origin.x,
67678f1909fc6918687aedd02949bcdf0f0e1ac682jiayl@webrtc.org                                                  bounds.origin.y,
68678f1909fc6918687aedd02949bcdf0f0e1ac682jiayl@webrtc.org                                                  bounds.size.width,
69678f1909fc6918687aedd02949bcdf0f0e1ac682jiayl@webrtc.org                                                  bounds.size.height))) {
70678f1909fc6918687aedd02949bcdf0f0e1ac682jiayl@webrtc.org        fullscreen = true;
71678f1909fc6918687aedd02949bcdf0f0e1ac682jiayl@webrtc.org        break;
72678f1909fc6918687aedd02949bcdf0f0e1ac682jiayl@webrtc.org      }
73678f1909fc6918687aedd02949bcdf0f0e1ac682jiayl@webrtc.org    }
74678f1909fc6918687aedd02949bcdf0f0e1ac682jiayl@webrtc.org  }
75678f1909fc6918687aedd02949bcdf0f0e1ac682jiayl@webrtc.org
76678f1909fc6918687aedd02949bcdf0f0e1ac682jiayl@webrtc.org  return fullscreen;
77678f1909fc6918687aedd02949bcdf0f0e1ac682jiayl@webrtc.org}
78678f1909fc6918687aedd02949bcdf0f0e1ac682jiayl@webrtc.org
79678f1909fc6918687aedd02949bcdf0f0e1ac682jiayl@webrtc.orgstd::string GetWindowTitle(CGWindowID id) {
80678f1909fc6918687aedd02949bcdf0f0e1ac682jiayl@webrtc.org  CFArrayRef window_id_array =
81678f1909fc6918687aedd02949bcdf0f0e1ac682jiayl@webrtc.org      CFArrayCreate(NULL, reinterpret_cast<const void **>(&id), 1, NULL);
82678f1909fc6918687aedd02949bcdf0f0e1ac682jiayl@webrtc.org  CFArrayRef window_array =
83678f1909fc6918687aedd02949bcdf0f0e1ac682jiayl@webrtc.org      CGWindowListCreateDescriptionFromArray(window_id_array);
84678f1909fc6918687aedd02949bcdf0f0e1ac682jiayl@webrtc.org  std::string title;
85678f1909fc6918687aedd02949bcdf0f0e1ac682jiayl@webrtc.org
86678f1909fc6918687aedd02949bcdf0f0e1ac682jiayl@webrtc.org  if (window_array && CFArrayGetCount(window_array)) {
87678f1909fc6918687aedd02949bcdf0f0e1ac682jiayl@webrtc.org    CFDictionaryRef window = reinterpret_cast<CFDictionaryRef>(
88678f1909fc6918687aedd02949bcdf0f0e1ac682jiayl@webrtc.org        CFArrayGetValueAtIndex(window_array, 0));
89678f1909fc6918687aedd02949bcdf0f0e1ac682jiayl@webrtc.org    CFStringRef title_ref =  reinterpret_cast<CFStringRef>(
90678f1909fc6918687aedd02949bcdf0f0e1ac682jiayl@webrtc.org        CFDictionaryGetValue(window, kCGWindowName));
91678f1909fc6918687aedd02949bcdf0f0e1ac682jiayl@webrtc.org
92678f1909fc6918687aedd02949bcdf0f0e1ac682jiayl@webrtc.org    if (title_ref)
93678f1909fc6918687aedd02949bcdf0f0e1ac682jiayl@webrtc.org      rtc::ToUtf8(title_ref, &title);
94678f1909fc6918687aedd02949bcdf0f0e1ac682jiayl@webrtc.org  }
95678f1909fc6918687aedd02949bcdf0f0e1ac682jiayl@webrtc.org  CFRelease(window_id_array);
96678f1909fc6918687aedd02949bcdf0f0e1ac682jiayl@webrtc.org  CFRelease(window_array);
97678f1909fc6918687aedd02949bcdf0f0e1ac682jiayl@webrtc.org
98678f1909fc6918687aedd02949bcdf0f0e1ac682jiayl@webrtc.org  return title;
99678f1909fc6918687aedd02949bcdf0f0e1ac682jiayl@webrtc.org}
100678f1909fc6918687aedd02949bcdf0f0e1ac682jiayl@webrtc.org
101678f1909fc6918687aedd02949bcdf0f0e1ac682jiayl@webrtc.orgint GetWindowOwnerPid(CGWindowID id) {
102678f1909fc6918687aedd02949bcdf0f0e1ac682jiayl@webrtc.org  CFArrayRef window_id_array =
103678f1909fc6918687aedd02949bcdf0f0e1ac682jiayl@webrtc.org      CFArrayCreate(NULL, reinterpret_cast<const void **>(&id), 1, NULL);
104678f1909fc6918687aedd02949bcdf0f0e1ac682jiayl@webrtc.org  CFArrayRef window_array =
105678f1909fc6918687aedd02949bcdf0f0e1ac682jiayl@webrtc.org      CGWindowListCreateDescriptionFromArray(window_id_array);
106678f1909fc6918687aedd02949bcdf0f0e1ac682jiayl@webrtc.org  int pid = 0;
107678f1909fc6918687aedd02949bcdf0f0e1ac682jiayl@webrtc.org
108678f1909fc6918687aedd02949bcdf0f0e1ac682jiayl@webrtc.org  if (window_array && CFArrayGetCount(window_array)) {
109678f1909fc6918687aedd02949bcdf0f0e1ac682jiayl@webrtc.org    CFDictionaryRef window = reinterpret_cast<CFDictionaryRef>(
110678f1909fc6918687aedd02949bcdf0f0e1ac682jiayl@webrtc.org        CFArrayGetValueAtIndex(window_array, 0));
111678f1909fc6918687aedd02949bcdf0f0e1ac682jiayl@webrtc.org    CFNumberRef pid_ref =  reinterpret_cast<CFNumberRef>(
112678f1909fc6918687aedd02949bcdf0f0e1ac682jiayl@webrtc.org        CFDictionaryGetValue(window, kCGWindowOwnerPID));
113678f1909fc6918687aedd02949bcdf0f0e1ac682jiayl@webrtc.org
114678f1909fc6918687aedd02949bcdf0f0e1ac682jiayl@webrtc.org    if (pid_ref)
115678f1909fc6918687aedd02949bcdf0f0e1ac682jiayl@webrtc.org      CFNumberGetValue(pid_ref, kCFNumberIntType, &pid);
116678f1909fc6918687aedd02949bcdf0f0e1ac682jiayl@webrtc.org  }
117678f1909fc6918687aedd02949bcdf0f0e1ac682jiayl@webrtc.org  CFRelease(window_id_array);
118678f1909fc6918687aedd02949bcdf0f0e1ac682jiayl@webrtc.org  CFRelease(window_array);
119678f1909fc6918687aedd02949bcdf0f0e1ac682jiayl@webrtc.org
120678f1909fc6918687aedd02949bcdf0f0e1ac682jiayl@webrtc.org  return pid;
121678f1909fc6918687aedd02949bcdf0f0e1ac682jiayl@webrtc.org}
122678f1909fc6918687aedd02949bcdf0f0e1ac682jiayl@webrtc.org
123678f1909fc6918687aedd02949bcdf0f0e1ac682jiayl@webrtc.org// Returns the window that is full-screen and has the same title and owner pid
124678f1909fc6918687aedd02949bcdf0f0e1ac682jiayl@webrtc.org// as the input window.
125678f1909fc6918687aedd02949bcdf0f0e1ac682jiayl@webrtc.orgCGWindowID FindFullScreenWindowWithSamePidAndTitle(CGWindowID id) {
126678f1909fc6918687aedd02949bcdf0f0e1ac682jiayl@webrtc.org  int pid = GetWindowOwnerPid(id);
127678f1909fc6918687aedd02949bcdf0f0e1ac682jiayl@webrtc.org  std::string title = GetWindowTitle(id);
128678f1909fc6918687aedd02949bcdf0f0e1ac682jiayl@webrtc.org
129678f1909fc6918687aedd02949bcdf0f0e1ac682jiayl@webrtc.org  // Only get on screen, non-desktop windows.
130678f1909fc6918687aedd02949bcdf0f0e1ac682jiayl@webrtc.org  CFArrayRef window_array = CGWindowListCopyWindowInfo(
131678f1909fc6918687aedd02949bcdf0f0e1ac682jiayl@webrtc.org      kCGWindowListOptionOnScreenOnly | kCGWindowListExcludeDesktopElements,
132678f1909fc6918687aedd02949bcdf0f0e1ac682jiayl@webrtc.org      kCGNullWindowID);
133678f1909fc6918687aedd02949bcdf0f0e1ac682jiayl@webrtc.org  if (!window_array)
134678f1909fc6918687aedd02949bcdf0f0e1ac682jiayl@webrtc.org    return kCGNullWindowID;
135678f1909fc6918687aedd02949bcdf0f0e1ac682jiayl@webrtc.org
136678f1909fc6918687aedd02949bcdf0f0e1ac682jiayl@webrtc.org  CGWindowID full_screen_window = kCGNullWindowID;
137678f1909fc6918687aedd02949bcdf0f0e1ac682jiayl@webrtc.org
138678f1909fc6918687aedd02949bcdf0f0e1ac682jiayl@webrtc.org  MacDesktopConfiguration desktop_config = MacDesktopConfiguration::GetCurrent(
139678f1909fc6918687aedd02949bcdf0f0e1ac682jiayl@webrtc.org      MacDesktopConfiguration::TopLeftOrigin);
140678f1909fc6918687aedd02949bcdf0f0e1ac682jiayl@webrtc.org
141678f1909fc6918687aedd02949bcdf0f0e1ac682jiayl@webrtc.org  // Check windows to make sure they have an id, title, and use window layer
142678f1909fc6918687aedd02949bcdf0f0e1ac682jiayl@webrtc.org  // other than 0.
143678f1909fc6918687aedd02949bcdf0f0e1ac682jiayl@webrtc.org  CFIndex count = CFArrayGetCount(window_array);
144678f1909fc6918687aedd02949bcdf0f0e1ac682jiayl@webrtc.org  for (CFIndex i = 0; i < count; ++i) {
145678f1909fc6918687aedd02949bcdf0f0e1ac682jiayl@webrtc.org    CFDictionaryRef window = reinterpret_cast<CFDictionaryRef>(
146678f1909fc6918687aedd02949bcdf0f0e1ac682jiayl@webrtc.org        CFArrayGetValueAtIndex(window_array, i));
147678f1909fc6918687aedd02949bcdf0f0e1ac682jiayl@webrtc.org    CFStringRef window_title_ref = reinterpret_cast<CFStringRef>(
148678f1909fc6918687aedd02949bcdf0f0e1ac682jiayl@webrtc.org        CFDictionaryGetValue(window, kCGWindowName));
149678f1909fc6918687aedd02949bcdf0f0e1ac682jiayl@webrtc.org    CFNumberRef window_id_ref = reinterpret_cast<CFNumberRef>(
150678f1909fc6918687aedd02949bcdf0f0e1ac682jiayl@webrtc.org        CFDictionaryGetValue(window, kCGWindowNumber));
151678f1909fc6918687aedd02949bcdf0f0e1ac682jiayl@webrtc.org    CFNumberRef window_pid_ref =  reinterpret_cast<CFNumberRef>(
152678f1909fc6918687aedd02949bcdf0f0e1ac682jiayl@webrtc.org        CFDictionaryGetValue(window, kCGWindowOwnerPID));
153678f1909fc6918687aedd02949bcdf0f0e1ac682jiayl@webrtc.org
154678f1909fc6918687aedd02949bcdf0f0e1ac682jiayl@webrtc.org    if (!window_title_ref || !window_id_ref || !window_pid_ref)
155678f1909fc6918687aedd02949bcdf0f0e1ac682jiayl@webrtc.org      continue;
156678f1909fc6918687aedd02949bcdf0f0e1ac682jiayl@webrtc.org
157678f1909fc6918687aedd02949bcdf0f0e1ac682jiayl@webrtc.org    int window_pid = 0;
158678f1909fc6918687aedd02949bcdf0f0e1ac682jiayl@webrtc.org    CFNumberGetValue(window_pid_ref, kCFNumberIntType, &window_pid);
159678f1909fc6918687aedd02949bcdf0f0e1ac682jiayl@webrtc.org    if (window_pid != pid)
160678f1909fc6918687aedd02949bcdf0f0e1ac682jiayl@webrtc.org      continue;
161678f1909fc6918687aedd02949bcdf0f0e1ac682jiayl@webrtc.org
162678f1909fc6918687aedd02949bcdf0f0e1ac682jiayl@webrtc.org    std::string window_title;
163678f1909fc6918687aedd02949bcdf0f0e1ac682jiayl@webrtc.org    if (!rtc::ToUtf8(window_title_ref, &window_title) ||
164678f1909fc6918687aedd02949bcdf0f0e1ac682jiayl@webrtc.org        window_title != title) {
165678f1909fc6918687aedd02949bcdf0f0e1ac682jiayl@webrtc.org      continue;
166678f1909fc6918687aedd02949bcdf0f0e1ac682jiayl@webrtc.org    }
167678f1909fc6918687aedd02949bcdf0f0e1ac682jiayl@webrtc.org
168678f1909fc6918687aedd02949bcdf0f0e1ac682jiayl@webrtc.org    CGWindowID window_id;
169678f1909fc6918687aedd02949bcdf0f0e1ac682jiayl@webrtc.org    CFNumberGetValue(window_id_ref, kCFNumberIntType, &window_id);
170678f1909fc6918687aedd02949bcdf0f0e1ac682jiayl@webrtc.org    if (IsWindowFullScreen(desktop_config, window)) {
171678f1909fc6918687aedd02949bcdf0f0e1ac682jiayl@webrtc.org      full_screen_window = window_id;
172678f1909fc6918687aedd02949bcdf0f0e1ac682jiayl@webrtc.org      break;
173678f1909fc6918687aedd02949bcdf0f0e1ac682jiayl@webrtc.org    }
174678f1909fc6918687aedd02949bcdf0f0e1ac682jiayl@webrtc.org  }
175678f1909fc6918687aedd02949bcdf0f0e1ac682jiayl@webrtc.org
176678f1909fc6918687aedd02949bcdf0f0e1ac682jiayl@webrtc.org  CFRelease(window_array);
177678f1909fc6918687aedd02949bcdf0f0e1ac682jiayl@webrtc.org  return full_screen_window;
178678f1909fc6918687aedd02949bcdf0f0e1ac682jiayl@webrtc.org}
179678f1909fc6918687aedd02949bcdf0f0e1ac682jiayl@webrtc.org
180678f1909fc6918687aedd02949bcdf0f0e1ac682jiayl@webrtc.orgbool IsChromeWindow(CGWindowID id) {
181678f1909fc6918687aedd02949bcdf0f0e1ac682jiayl@webrtc.org  int pid = GetWindowOwnerPid(id);
182678f1909fc6918687aedd02949bcdf0f0e1ac682jiayl@webrtc.org  char buffer[PROC_PIDPATHINFO_MAXSIZE];
183678f1909fc6918687aedd02949bcdf0f0e1ac682jiayl@webrtc.org  int path_length = proc_pidpath(pid, buffer, sizeof(buffer));
184678f1909fc6918687aedd02949bcdf0f0e1ac682jiayl@webrtc.org  if (path_length <= 0)
185678f1909fc6918687aedd02949bcdf0f0e1ac682jiayl@webrtc.org    return false;
186678f1909fc6918687aedd02949bcdf0f0e1ac682jiayl@webrtc.org
187678f1909fc6918687aedd02949bcdf0f0e1ac682jiayl@webrtc.org  const char* last_slash = strrchr(buffer, '/');
188678f1909fc6918687aedd02949bcdf0f0e1ac682jiayl@webrtc.org  std::string name(last_slash ? last_slash + 1 : buffer);
189678f1909fc6918687aedd02949bcdf0f0e1ac682jiayl@webrtc.org  return name.find("Google Chrome") == 0 || name == "Chromium";
190678f1909fc6918687aedd02949bcdf0f0e1ac682jiayl@webrtc.org}
191678f1909fc6918687aedd02949bcdf0f0e1ac682jiayl@webrtc.org
192678f1909fc6918687aedd02949bcdf0f0e1ac682jiayl@webrtc.org}  // namespace
193678f1909fc6918687aedd02949bcdf0f0e1ac682jiayl@webrtc.org
194678f1909fc6918687aedd02949bcdf0f0e1ac682jiayl@webrtc.orgFullScreenChromeWindowDetector::FullScreenChromeWindowDetector()
195678f1909fc6918687aedd02949bcdf0f0e1ac682jiayl@webrtc.org    : ref_count_(0) {}
196678f1909fc6918687aedd02949bcdf0f0e1ac682jiayl@webrtc.org
197678f1909fc6918687aedd02949bcdf0f0e1ac682jiayl@webrtc.orgFullScreenChromeWindowDetector::~FullScreenChromeWindowDetector() {}
198678f1909fc6918687aedd02949bcdf0f0e1ac682jiayl@webrtc.org
199678f1909fc6918687aedd02949bcdf0f0e1ac682jiayl@webrtc.orgCGWindowID FullScreenChromeWindowDetector::FindFullScreenWindow(
200678f1909fc6918687aedd02949bcdf0f0e1ac682jiayl@webrtc.org    CGWindowID original_window) {
201678f1909fc6918687aedd02949bcdf0f0e1ac682jiayl@webrtc.org  if (!IsChromeWindow(original_window) || !IsWindowMinimized(original_window))
202678f1909fc6918687aedd02949bcdf0f0e1ac682jiayl@webrtc.org    return kCGNullWindowID;
203678f1909fc6918687aedd02949bcdf0f0e1ac682jiayl@webrtc.org
204678f1909fc6918687aedd02949bcdf0f0e1ac682jiayl@webrtc.org  CGWindowID full_screen_window_id =
205678f1909fc6918687aedd02949bcdf0f0e1ac682jiayl@webrtc.org      FindFullScreenWindowWithSamePidAndTitle(original_window);
206678f1909fc6918687aedd02949bcdf0f0e1ac682jiayl@webrtc.org
207678f1909fc6918687aedd02949bcdf0f0e1ac682jiayl@webrtc.org  if (full_screen_window_id == kCGNullWindowID)
208678f1909fc6918687aedd02949bcdf0f0e1ac682jiayl@webrtc.org    return kCGNullWindowID;
209678f1909fc6918687aedd02949bcdf0f0e1ac682jiayl@webrtc.org
210678f1909fc6918687aedd02949bcdf0f0e1ac682jiayl@webrtc.org  for (WindowCapturer::WindowList::iterator it = previous_window_list_.begin();
211678f1909fc6918687aedd02949bcdf0f0e1ac682jiayl@webrtc.org       it != previous_window_list_.end(); ++it) {
212678f1909fc6918687aedd02949bcdf0f0e1ac682jiayl@webrtc.org    if (static_cast<CGWindowID>(it->id) != full_screen_window_id)
213678f1909fc6918687aedd02949bcdf0f0e1ac682jiayl@webrtc.org      continue;
214678f1909fc6918687aedd02949bcdf0f0e1ac682jiayl@webrtc.org
215678f1909fc6918687aedd02949bcdf0f0e1ac682jiayl@webrtc.org    int64_t time_interval =
216678f1909fc6918687aedd02949bcdf0f0e1ac682jiayl@webrtc.org        (TickTime::Now() - last_udpate_time_).Milliseconds();
217678f1909fc6918687aedd02949bcdf0f0e1ac682jiayl@webrtc.org    LOG(LS_WARNING) << "The full-screen window exists in the list, "
218678f1909fc6918687aedd02949bcdf0f0e1ac682jiayl@webrtc.org                    << "which was updated " << time_interval << "ms ago.";
219678f1909fc6918687aedd02949bcdf0f0e1ac682jiayl@webrtc.org    return kCGNullWindowID;
220678f1909fc6918687aedd02949bcdf0f0e1ac682jiayl@webrtc.org  }
221678f1909fc6918687aedd02949bcdf0f0e1ac682jiayl@webrtc.org
222678f1909fc6918687aedd02949bcdf0f0e1ac682jiayl@webrtc.org  return full_screen_window_id;
223678f1909fc6918687aedd02949bcdf0f0e1ac682jiayl@webrtc.org}
224678f1909fc6918687aedd02949bcdf0f0e1ac682jiayl@webrtc.org
225678f1909fc6918687aedd02949bcdf0f0e1ac682jiayl@webrtc.orgvoid FullScreenChromeWindowDetector::UpdateWindowListIfNeeded(
226678f1909fc6918687aedd02949bcdf0f0e1ac682jiayl@webrtc.org    CGWindowID original_window) {
227678f1909fc6918687aedd02949bcdf0f0e1ac682jiayl@webrtc.org  if (IsChromeWindow(original_window) &&
228678f1909fc6918687aedd02949bcdf0f0e1ac682jiayl@webrtc.org      (TickTime::Now() - last_udpate_time_).Milliseconds()
229678f1909fc6918687aedd02949bcdf0f0e1ac682jiayl@webrtc.org          > kUpdateIntervalMs) {
230678f1909fc6918687aedd02949bcdf0f0e1ac682jiayl@webrtc.org    previous_window_list_.clear();
231678f1909fc6918687aedd02949bcdf0f0e1ac682jiayl@webrtc.org    previous_window_list_.swap(current_window_list_);
232678f1909fc6918687aedd02949bcdf0f0e1ac682jiayl@webrtc.org
233678f1909fc6918687aedd02949bcdf0f0e1ac682jiayl@webrtc.org    // No need to update the window list when the window is minimized.
234678f1909fc6918687aedd02949bcdf0f0e1ac682jiayl@webrtc.org    if (IsWindowMinimized(original_window)) {
235678f1909fc6918687aedd02949bcdf0f0e1ac682jiayl@webrtc.org      previous_window_list_.clear();
236678f1909fc6918687aedd02949bcdf0f0e1ac682jiayl@webrtc.org      return;
237678f1909fc6918687aedd02949bcdf0f0e1ac682jiayl@webrtc.org    }
238678f1909fc6918687aedd02949bcdf0f0e1ac682jiayl@webrtc.org
239678f1909fc6918687aedd02949bcdf0f0e1ac682jiayl@webrtc.org    GetWindowList(&current_window_list_);
240678f1909fc6918687aedd02949bcdf0f0e1ac682jiayl@webrtc.org    last_udpate_time_ = TickTime::Now();
241678f1909fc6918687aedd02949bcdf0f0e1ac682jiayl@webrtc.org  }
242678f1909fc6918687aedd02949bcdf0f0e1ac682jiayl@webrtc.org}
243678f1909fc6918687aedd02949bcdf0f0e1ac682jiayl@webrtc.org
244678f1909fc6918687aedd02949bcdf0f0e1ac682jiayl@webrtc.org}  // namespace webrtc
245