 Chromium Code Reviews
 Chromium Code Reviews Issue 13006006:
  chromeos: Support turning displays off in extended mode.  (Closed) 
  Base URL: svn://svn.chromium.org/chrome/trunk/src
    
  
    Issue 13006006:
  chromeos: Support turning displays off in extended mode.  (Closed) 
  Base URL: svn://svn.chromium.org/chrome/trunk/src| OLD | NEW | 
|---|---|
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be | 
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. | 
| 4 | 4 | 
| 5 #include "chromeos/display/output_configurator.h" | 5 #include "chromeos/display/output_configurator.h" | 
| 6 | 6 | 
| 7 #include <cmath> | 7 #include <cmath> | 
| 8 | 8 | 
| 9 #include <X11/Xatom.h> | 9 #include <X11/Xatom.h> | 
| 10 #include <X11/Xlib.h> | 10 #include <X11/Xlib.h> | 
| (...skipping 579 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 590 | 590 | 
| 591 chromeos::DBusThreadManager::Get()->GetPowerManagerClient()-> | 591 chromeos::DBusThreadManager::Get()->GetPowerManagerClient()-> | 
| 592 SetIsProjecting(is_projecting); | 592 SetIsProjecting(is_projecting); | 
| 593 } | 593 } | 
| 594 | 594 | 
| 595 void OutputConfigurator::Stop() { | 595 void OutputConfigurator::Stop() { | 
| 596 configure_display_ = false; | 596 configure_display_ = false; | 
| 597 } | 597 } | 
| 598 | 598 | 
| 599 bool OutputConfigurator::SetDisplayPower(DisplayPowerState power_state, | 599 bool OutputConfigurator::SetDisplayPower(DisplayPowerState power_state, | 
| 600 bool force_probe) { | 600 bool force_probe, | 
| 601 bool only_if_single_internal_display) { | |
| 601 TRACE_EVENT0("chromeos", "OutputConfigurator::SetDisplayPower"); | 602 TRACE_EVENT0("chromeos", "OutputConfigurator::SetDisplayPower"); | 
| 602 VLOG(1) << "OutputConfigurator::SetDisplayPower: power_state=" << power_state | 603 VLOG(1) << "OutputConfigurator::SetDisplayPower: power_state=" << power_state | 
| 603 << " force_probe=" << force_probe; | 604 << " force_probe=" << force_probe | 
| 605 << " only_if_single_internal_display=" | |
| 606 << only_if_single_internal_display; | |
| 604 | 607 | 
| 605 if (!configure_display_) | 608 if (!configure_display_) | 
| 606 return false; | 609 return false; | 
| 607 if (power_state == power_state_ && !force_probe) | 610 if (power_state == power_state_ && !force_probe) | 
| 608 return true; | 611 return true; | 
| 609 | 612 | 
| 610 Display* display = base::MessagePumpAuraX11::GetDefaultXDisplay(); | 613 Display* display = base::MessagePumpAuraX11::GetDefaultXDisplay(); | 
| 611 CHECK(display); | 614 CHECK(display); | 
| 612 XGrabServer(display); | 615 XGrabServer(display); | 
| 613 Window window = DefaultRootWindow(display); | 616 Window window = DefaultRootWindow(display); | 
| 614 XRRScreenResources* screen = GetScreenResourcesAndRecordUMA(display, window); | 617 XRRScreenResources* screen = GetScreenResourcesAndRecordUMA(display, window); | 
| 615 CHECK(screen); | 618 CHECK(screen); | 
| 616 std::vector<OutputSnapshot> outputs = GetDualOutputs(display, screen); | 619 std::vector<OutputSnapshot> outputs = GetDualOutputs(display, screen); | 
| 617 connected_output_count_ = outputs.size(); | 620 connected_output_count_ = outputs.size(); | 
| 618 | 621 | 
| 619 if (EnterState(display, screen, window, output_state_, power_state, | 622 bool single_internal_display = outputs.size() == 1 && outputs[0].is_internal; | 
| 623 if ((single_internal_display || !only_if_single_internal_display) && | |
| 624 EnterState(display, screen, window, output_state_, power_state, | |
| 620 outputs)) { | 625 outputs)) { | 
| 621 power_state_ = power_state; | 626 power_state_ = power_state; | 
| 622 if (power_state != DISPLAY_POWER_ALL_OFF) { | 627 if (power_state != DISPLAY_POWER_ALL_OFF) { | 
| 623 // Force the DPMS on since the driver doesn't always detect that it | 628 // Force the DPMS on since the driver doesn't always detect that it | 
| 624 // should turn on. This is needed when coming back from idle suspend. | 629 // should turn on. This is needed when coming back from idle suspend. | 
| 625 CHECK(DPMSEnable(display)); | 630 CHECK(DPMSEnable(display)); | 
| 626 CHECK(DPMSForceLevel(display, DPMSModeOn)); | 631 CHECK(DPMSForceLevel(display, DPMSModeOn)); | 
| 627 } | 632 } | 
| 628 } | 633 } | 
| 629 | 634 | 
| 630 XRRFreeScreenResources(screen); | 635 XRRFreeScreenResources(screen); | 
| 631 XUngrabServer(display); | 636 XUngrabServer(display); | 
| 632 | |
| 633 return true; | 637 return true; | 
| 634 } | 638 } | 
| 635 | 639 | 
| 636 bool OutputConfigurator::SetDisplayMode(OutputState new_state) { | 640 bool OutputConfigurator::SetDisplayMode(OutputState new_state) { | 
| 637 TRACE_EVENT0("chromeos", "OutputConfigurator::SetDisplayMode"); | 641 TRACE_EVENT0("chromeos", "OutputConfigurator::SetDisplayMode"); | 
| 638 if (output_state_ == STATE_INVALID || | 642 if (output_state_ == STATE_INVALID || | 
| 639 output_state_ == STATE_HEADLESS || | 643 output_state_ == STATE_HEADLESS || | 
| 640 output_state_ == STATE_SINGLE) | 644 output_state_ == STATE_SINGLE) | 
| 641 return false; | 645 return false; | 
| 642 | 646 | 
| (...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 750 void OutputConfigurator::RemoveObserver(Observer* observer) { | 754 void OutputConfigurator::RemoveObserver(Observer* observer) { | 
| 751 observers_.RemoveObserver(observer); | 755 observers_.RemoveObserver(observer); | 
| 752 } | 756 } | 
| 753 | 757 | 
| 754 // static | 758 // static | 
| 755 bool OutputConfigurator::IsInternalOutputName(const std::string& name) { | 759 bool OutputConfigurator::IsInternalOutputName(const std::string& name) { | 
| 756 return name.find(kInternal_LVDS) == 0 || name.find(kInternal_eDP) == 0; | 760 return name.find(kInternal_LVDS) == 0 || name.find(kInternal_eDP) == 0; | 
| 757 } | 761 } | 
| 758 | 762 | 
| 759 void OutputConfigurator::SuspendDisplays() { | 763 void OutputConfigurator::SuspendDisplays() { | 
| 760 // Turn internal displays on before suspend. At this point, the backlight | 764 // If the display is off due to user inactivity and there's only a single | 
| 761 // is off, so we turn on the internal display so that we can resume | 765 // internal display connected, switch to the all-on state before | 
| 762 // directly into "on" state. This greatly reduces resume times. | 766 // suspending. This shouldn't be very noticeable to the user since the | 
| 763 SetDisplayPower(DISPLAY_POWER_INTERNAL_ON_EXTERNAL_OFF, false); | 767 // backlight is off at this point, and doing this lets us resume directly | 
| 768 // into the "on" state, which greatly reduces resume times. | |
| 769 if (power_state_ == DISPLAY_POWER_ALL_OFF) { | |
| 770 SetDisplayPower(DISPLAY_POWER_ALL_ON, false, | |
| 771 true /* only_if_single_internal_display */); | |
| 
Daniel Erat
2013/03/27 23:15:19
I think that we can only do this safely when there
 | |
| 772 } | |
| 764 | 773 | 
| 765 // We need to make sure that the monitor configuration we just did actually | 774 // We need to make sure that the monitor configuration we just did actually | 
| 766 // completes before we return, because otherwise the X message could be | 775 // completes before we return, because otherwise the X message could be | 
| 767 // racing with the HandleSuspendReadiness message. | 776 // racing with the HandleSuspendReadiness message. | 
| 768 XSync(base::MessagePumpAuraX11::GetDefaultXDisplay(), 0); | 777 XSync(base::MessagePumpAuraX11::GetDefaultXDisplay(), 0); | 
| 769 } | 778 } | 
| 770 | 779 | 
| 771 void OutputConfigurator::ResumeDisplays() { | 780 void OutputConfigurator::ResumeDisplays() { | 
| 772 // Force probing to ensure that we pick up any changes that were made | 781 // Force probing to ensure that we pick up any changes that were made | 
| 773 // while the system was suspended. | 782 // while the system was suspended. | 
| 774 SetDisplayPower(DISPLAY_POWER_ALL_ON, true); | 783 SetDisplayPower(power_state_, true /* force_probe */, false); | 
| 775 } | 784 } | 
| 776 | 785 | 
| 777 void OutputConfigurator::NotifyOnDisplayChanged() { | 786 void OutputConfigurator::NotifyOnDisplayChanged() { | 
| 778 TRACE_EVENT0("chromeos", "OutputConfigurator::NotifyOnDisplayChanged"); | 787 TRACE_EVENT0("chromeos", "OutputConfigurator::NotifyOnDisplayChanged"); | 
| 779 FOR_EACH_OBSERVER(Observer, observers_, OnDisplayModeChanged()); | 788 FOR_EACH_OBSERVER(Observer, observers_, OnDisplayModeChanged()); | 
| 780 } | 789 } | 
| 781 | 790 | 
| 782 std::vector<OutputSnapshot> OutputConfigurator::GetDualOutputs( | 791 std::vector<OutputSnapshot> OutputConfigurator::GetDualOutputs( | 
| 783 Display* display, | 792 Display* display, | 
| 784 XRRScreenResources* screen) { | 793 XRRScreenResources* screen) { | 
| (...skipping 310 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1095 } | 1104 } | 
| 1096 | 1105 | 
| 1097 bool OutputConfigurator::EnterState( | 1106 bool OutputConfigurator::EnterState( | 
| 1098 Display* display, | 1107 Display* display, | 
| 1099 XRRScreenResources* screen, | 1108 XRRScreenResources* screen, | 
| 1100 Window window, | 1109 Window window, | 
| 1101 OutputState output_state, | 1110 OutputState output_state, | 
| 1102 DisplayPowerState power_state, | 1111 DisplayPowerState power_state, | 
| 1103 const std::vector<OutputSnapshot>& outputs) { | 1112 const std::vector<OutputSnapshot>& outputs) { | 
| 1104 TRACE_EVENT0("chromeos", "OutputConfigurator::EnterState"); | 1113 TRACE_EVENT0("chromeos", "OutputConfigurator::EnterState"); | 
| 1114 | |
| 1115 std::vector<RRCrtc> crtcs(outputs.size()); | |
| 1116 std::vector<bool> output_power(outputs.size()); | |
| 1117 bool all_outputs_off = true; | |
| 1118 | |
| 1119 RRCrtc prev_crtc = None; | |
| 1120 for (size_t i = 0; i < outputs.size(); prev_crtc = crtcs[i], ++i) { | |
| 1121 crtcs[i] = GetNextCrtcAfter(display, screen, outputs[i].output, prev_crtc); | |
| 1122 output_power[i] = power_state == DISPLAY_POWER_ALL_ON || | |
| 1123 (power_state == DISPLAY_POWER_INTERNAL_OFF_EXTERNAL_ON && | |
| 1124 !outputs[i].is_internal) || | |
| 1125 (power_state == DISPLAY_POWER_INTERNAL_ON_EXTERNAL_OFF && | |
| 1126 outputs[i].is_internal); | |
| 1127 if (output_power[i]) | |
| 1128 all_outputs_off = false; | |
| 1129 } | |
| 1130 | |
| 1105 switch (outputs.size()) { | 1131 switch (outputs.size()) { | 
| 1106 case 0: | 1132 case 0: | 
| 1107 // Do nothing as no 0-display states are supported. | 1133 // Do nothing as no 0-display states are supported. | 
| 1108 break; | 1134 break; | 
| 1109 case 1: { | 1135 case 1: { | 
| 1110 // Re-allocate the framebuffer to fit. | 1136 // Re-allocate the framebuffer to fit. | 
| 1111 XRRModeInfo* mode_info = ModeInfoForID(screen, outputs[0].native_mode); | 1137 XRRModeInfo* mode_info = ModeInfoForID(screen, outputs[0].native_mode); | 
| 1112 if (mode_info == NULL) { | 1138 if (!mode_info) { | 
| 1113 UMA_HISTOGRAM_COUNTS("Display.EnterState.single_failures", 1); | 1139 UMA_HISTOGRAM_COUNTS("Display.EnterState.single_failures", 1); | 
| 1114 return false; | 1140 return false; | 
| 1115 } | 1141 } | 
| 1116 | 1142 | 
| 1117 bool power_on = power_state == DISPLAY_POWER_ALL_ON || | 1143 CrtcConfig config(crtcs[0], 0, 0, | 
| 1118 (power_state == DISPLAY_POWER_INTERNAL_OFF_EXTERNAL_ON && | 1144 output_power[0] ? outputs[0].native_mode : None, | 
| 1119 !outputs[0].is_internal) || | 1145 outputs[0].output); | 
| 1120 (power_state == DISPLAY_POWER_INTERNAL_ON_EXTERNAL_OFF && | |
| 1121 outputs[0].is_internal); | |
| 1122 CrtcConfig config( | |
| 1123 GetNextCrtcAfter(display, screen, outputs[0].output, None), | |
| 1124 0, 0, power_on ? outputs[0].native_mode : None, outputs[0].output); | |
| 1125 | |
| 1126 CreateFrameBuffer(display, screen, window, mode_info->width, | 1146 CreateFrameBuffer(display, screen, window, mode_info->width, | 
| 1127 mode_info->height, &config, NULL); | 1147 mode_info->height, &config, NULL); | 
| 1128 | |
| 1129 ConfigureCrtc(display, screen, &config); | 1148 ConfigureCrtc(display, screen, &config); | 
| 1130 | 1149 if (outputs[0].touch_device_id) { | 
| 1131 // Restore identity transformation for single monitor in native mode. | 1150 // Restore identity transformation for single monitor in native mode. | 
| 1132 if (outputs[0].touch_device_id != None) { | 1151 ConfigureCTM(display, outputs[0].touch_device_id, | 
| 1133 CoordinateTransformation ctm; // Defaults to identity | 1152 CoordinateTransformation()); | 
| 1134 ConfigureCTM(display, outputs[0].touch_device_id, ctm); | |
| 1135 } | 1153 } | 
| 1136 break; | 1154 break; | 
| 1137 } | 1155 } | 
| 1138 case 2: { | 1156 case 2: { | 
| 1139 RRCrtc primary_crtc = | |
| 1140 GetNextCrtcAfter(display, screen, outputs[0].output, None); | |
| 1141 RRCrtc secondary_crtc = | |
| 1142 GetNextCrtcAfter(display, screen, outputs[1].output, primary_crtc); | |
| 1143 | |
| 1144 // Workaround for crbug.com/148365: leave internal display on for | |
| 1145 // internal-off, external-on so user can move cursor (and hence | |
| 1146 // windows) onto internal display even when it's off. | |
| 1147 bool primary_power_on = power_state == DISPLAY_POWER_ALL_ON || | |
| 1148 (power_state == DISPLAY_POWER_INTERNAL_ON_EXTERNAL_OFF && | |
| 1149 outputs[0].is_internal); | |
| 1150 bool secondary_power_on = power_state == DISPLAY_POWER_ALL_ON || | |
| 1151 (power_state == DISPLAY_POWER_INTERNAL_ON_EXTERNAL_OFF && | |
| 1152 outputs[1].is_internal); | |
| 1153 | |
| 1154 if (output_state == STATE_DUAL_MIRROR) { | 1157 if (output_state == STATE_DUAL_MIRROR) { | 
| 1155 XRRModeInfo* mode_info = ModeInfoForID(screen, outputs[0].mirror_mode); | 1158 XRRModeInfo* mode_info = ModeInfoForID(screen, outputs[0].mirror_mode); | 
| 1156 if (mode_info == NULL) { | 1159 if (!mode_info) { | 
| 1157 UMA_HISTOGRAM_COUNTS("Display.EnterState.mirror_failures", 1); | 1160 UMA_HISTOGRAM_COUNTS("Display.EnterState.mirror_failures", 1); | 
| 1158 return false; | 1161 return false; | 
| 1159 } | 1162 } | 
| 1160 | 1163 | 
| 1161 CrtcConfig config1(primary_crtc, 0, 0, | 1164 std::vector<CrtcConfig> configs(outputs.size()); | 
| 1162 primary_power_on ? outputs[0].mirror_mode : None, | 1165 for (size_t i = 0; i < outputs.size(); ++i) { | 
| 1163 outputs[0].output); | 1166 configs[i] = CrtcConfig( | 
| 1164 CrtcConfig config2(secondary_crtc, 0, 0, | 1167 crtcs[i], 0, 0, | 
| 1165 secondary_power_on ? outputs[1].mirror_mode : None, | 1168 output_power[i] ? outputs[i].mirror_mode : None, | 
| 1166 outputs[1].output); | 1169 outputs[i].output); | 
| 1170 } | |
| 1167 | 1171 | 
| 1168 CreateFrameBuffer(display, screen, window, mode_info->width, | 1172 CreateFrameBuffer(display, screen, window, mode_info->width, | 
| 1169 mode_info->height, &config1, &config2); | 1173 mode_info->height, &configs[0], &configs[1]); | 
| 1170 | 1174 | 
| 1171 ConfigureCrtc(display, screen, &config1); | 1175 for (size_t i = 0; i < outputs.size(); ++i) { | 
| 1172 ConfigureCrtc(display, screen, &config2); | 1176 ConfigureCrtc(display, screen, &configs[i]); | 
| 1177 if (outputs[i].touch_device_id) { | |
| 1178 CoordinateTransformation ctm; | |
| 1179 // CTM needs to be calculated if aspect preserving scaling is used. | |
| 1180 // Otherwise, assume it is full screen, and use identity CTM. | |
| 1181 if (outputs[i].mirror_mode != outputs[i].native_mode && | |
| 1182 outputs[i].is_aspect_preserving_scaling) { | |
| 1183 ctm = GetMirrorModeCTM(screen, &outputs[i]); | |
| 1184 } | |
| 1185 ConfigureCTM(display, outputs[i].touch_device_id, ctm); | |
| 1186 } | |
| 1187 } | |
| 1188 } else { // STATE_DUAL_EXTENDED | |
| 1189 std::vector<XRRModeInfo*> mode_infos(outputs.size()); | |
| 1190 std::vector<CrtcConfig> configs(outputs.size()); | |
| 1191 int width = 0, height = 0; | |
| 1173 | 1192 | 
| 1174 for (size_t i = 0; i < outputs.size(); i++) { | 1193 for (size_t i = 0; i < outputs.size(); ++i) { | 
| 1175 if (outputs[i].touch_device_id == None) | 1194 mode_infos[i] = ModeInfoForID(screen, outputs[i].native_mode); | 
| 1176 continue; | 1195 if (!mode_infos[i]) { | 
| 1196 UMA_HISTOGRAM_COUNTS("Display.EnterState.dual_failures", 1); | |
| 1197 return false; | |
| 1198 } | |
| 1177 | 1199 | 
| 1178 CoordinateTransformation ctm; | 1200 configs[i] = CrtcConfig( | 
| 1179 // CTM needs to be calculated if aspect preserving scaling is used. | 1201 crtcs[i], 0, height, | 
| 1180 // Otherwise, assume it is full screen, and use identity CTM. | 1202 output_power[i] ? outputs[i].native_mode : None, | 
| 1181 if (outputs[i].mirror_mode != outputs[i].native_mode && | 1203 outputs[i].output); | 
| 1182 outputs[i].is_aspect_preserving_scaling) { | 1204 | 
| 1183 ctm = GetMirrorModeCTM(screen, &outputs[i]); | 1205 // Retain the full screen size if all outputs are off so the same | 
| 1206 // desktop configuration can be restored when the outputs are | |
| 1207 // turned back on. | |
| 1208 if (output_power[i] || all_outputs_off) { | |
| 1209 width = std::max<int>(width, mode_infos[i]->width); | |
| 1210 height += (height ? kVerticalGap : 0) + mode_infos[i]->height; | |
| 1184 } | 1211 } | 
| 1185 ConfigureCTM(display, outputs[i].touch_device_id, ctm); | |
| 1186 } | |
| 1187 } else { | |
| 1188 XRRModeInfo* primary_mode_info = | |
| 1189 ModeInfoForID(screen, outputs[0].native_mode); | |
| 1190 XRRModeInfo* secondary_mode_info = | |
| 1191 ModeInfoForID(screen, outputs[1].native_mode); | |
| 1192 if (primary_mode_info == NULL || secondary_mode_info == NULL) { | |
| 1193 UMA_HISTOGRAM_COUNTS("Display.EnterState.dual_failures", 1); | |
| 1194 return false; | |
| 1195 } | 1212 } | 
| 1196 | 1213 | 
| 1197 int primary_height = primary_mode_info->height; | 1214 CreateFrameBuffer(display, screen, window, width, height, | 
| 1198 int secondary_height = secondary_mode_info->height; | 1215 &configs[0], &configs[1]); | 
| 1199 CrtcConfig config1(primary_crtc, 0, 0, | |
| 1200 primary_power_on ? outputs[0].native_mode : None, | |
| 1201 outputs[0].output); | |
| 1202 CrtcConfig config2(secondary_crtc, 0, 0, | |
| 1203 secondary_power_on ? outputs[1].native_mode : None, | |
| 1204 outputs[1].output); | |
| 1205 | 1216 | 
| 1206 if (output_state == STATE_DUAL_EXTENDED) | 1217 for (size_t i = 0; i < outputs.size(); ++i) { | 
| 1207 config2.y = primary_height + kVerticalGap; | 1218 ConfigureCrtc(display, screen, &configs[i]); | 
| 1208 else | 1219 if (outputs[i].touch_device_id) { | 
| 1209 config1.y = secondary_height + kVerticalGap; | 1220 CoordinateTransformation ctm; | 
| 1210 | 1221 ctm.x_scale = static_cast<float>(mode_infos[i]->width) / width; | 
| 1211 int width = std::max<int>( | 1222 ctm.x_offset = static_cast<float>(configs[i].x) / width; | 
| 1212 primary_mode_info->width, secondary_mode_info->width); | 1223 ctm.y_scale = static_cast<float>(mode_infos[i]->height) / height; | 
| 1213 int height = primary_height + secondary_height + kVerticalGap; | 1224 ctm.y_offset = static_cast<float>(configs[i].y) / height; | 
| 1214 | 1225 ConfigureCTM(display, outputs[i].touch_device_id, ctm); | 
| 1215 CreateFrameBuffer(display, screen, window, width, height, &config1, | 1226 } | 
| 1216 &config2); | |
| 1217 | |
| 1218 ConfigureCrtc(display, screen, &config1); | |
| 1219 ConfigureCrtc(display, screen, &config2); | |
| 1220 | |
| 1221 if (outputs[0].touch_device_id != None) { | |
| 1222 CoordinateTransformation ctm; | |
| 1223 ctm.x_scale = static_cast<float>(primary_mode_info->width) / width; | |
| 1224 ctm.x_offset = static_cast<float>(config1.x) / width; | |
| 1225 ctm.y_scale = static_cast<float>(primary_height) / height; | |
| 1226 ctm.y_offset = static_cast<float>(config1.y) / height; | |
| 1227 ConfigureCTM(display, outputs[0].touch_device_id, ctm); | |
| 1228 } | |
| 1229 if (outputs[1].touch_device_id != None) { | |
| 1230 CoordinateTransformation ctm; | |
| 1231 ctm.x_scale = static_cast<float>(secondary_mode_info->width) / | |
| 1232 width; | |
| 1233 ctm.x_offset = static_cast<float>(config2.x) / width; | |
| 1234 ctm.y_scale = static_cast<float>(secondary_height) / height; | |
| 1235 ctm.y_offset = static_cast<float>(config2.y) / height; | |
| 1236 ConfigureCTM(display, outputs[1].touch_device_id, ctm); | |
| 1237 } | 1227 } | 
| 1238 } | 1228 } | 
| 1239 break; | 1229 break; | 
| 1240 } | 1230 } | 
| 1241 default: | 1231 default: | 
| 1242 CHECK(false); | 1232 NOTREACHED() << "Got " << outputs.size() << " outputs"; | 
| 1243 } | 1233 } | 
| 1244 | 1234 | 
| 1245 RecordPreviousStateUMA(); | 1235 RecordPreviousStateUMA(); | 
| 1246 | |
| 1247 return true; | 1236 return true; | 
| 1248 } | 1237 } | 
| 1249 | 1238 | 
| 1250 void OutputConfigurator::RecordPreviousStateUMA() { | 1239 void OutputConfigurator::RecordPreviousStateUMA() { | 
| 1251 base::TimeDelta duration = base::TimeTicks::Now() - last_enter_state_time_; | 1240 base::TimeDelta duration = base::TimeTicks::Now() - last_enter_state_time_; | 
| 1252 | 1241 | 
| 1253 // |output_state_| can be used for the state being left, | 1242 // |output_state_| can be used for the state being left, | 
| 1254 // since RecordPreviousStateUMA is called from EnterState, | 1243 // since RecordPreviousStateUMA is called from EnterState, | 
| 1255 // and |output_state_| is always updated after EnterState is called. | 1244 // and |output_state_| is always updated after EnterState is called. | 
| 1256 switch (output_state_) { | 1245 switch (output_state_) { | 
| (...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1332 // static | 1321 // static | 
| 1333 RRMode OutputConfigurator::GetOutputNativeMode( | 1322 RRMode OutputConfigurator::GetOutputNativeMode( | 
| 1334 const XRROutputInfo* output_info) { | 1323 const XRROutputInfo* output_info) { | 
| 1335 if (output_info->nmode <= 0) | 1324 if (output_info->nmode <= 0) | 
| 1336 return None; | 1325 return None; | 
| 1337 | 1326 | 
| 1338 return output_info->modes[0]; | 1327 return output_info->modes[0]; | 
| 1339 } | 1328 } | 
| 1340 | 1329 | 
| 1341 } // namespace chromeos | 1330 } // namespace chromeos | 
| OLD | NEW |