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
3// found in the LICENSE file.
4
5#include "ppapi/tests/test_flash_fullscreen.h"
6
7#include <stdio.h>
8#include <string.h>
9#include <string>
10
11#include "ppapi/c/private/ppb_flash_fullscreen.h"
12#include "ppapi/cpp/graphics_2d.h"
13#include "ppapi/cpp/instance.h"
14#include "ppapi/cpp/module.h"
15#include "ppapi/cpp/point.h"
16#include "ppapi/cpp/private/flash_fullscreen.h"
17#include "ppapi/cpp/rect.h"
18#include "ppapi/cpp/size.h"
19#include "ppapi/tests/test_utils.h"
20#include "ppapi/tests/testing_instance.h"
21
22REGISTER_TEST_CASE(FlashFullscreen);
23
24namespace {
25
26bool IsFullscreenView(const pp::Rect& position,
27                      const pp::Rect& clip,
28                      const pp::Size& screen_size) {
29  return (position.point() == pp::Point(0, 0) &&
30          position.size() == screen_size &&
31          clip.point() == pp::Point(0, 0) &&
32          clip.size() == screen_size);
33}
34
35}  // namespace
36
37TestFlashFullscreen::TestFlashFullscreen(TestingInstance* instance)
38    : TestCase(instance),
39      screen_mode_(instance),
40      fullscreen_pending_(false),
41      normal_pending_(false),
42      fullscreen_event_(instance->pp_instance()),
43      normal_event_(instance->pp_instance()) {
44  screen_mode_.GetScreenSize(&screen_size_);
45}
46
47bool TestFlashFullscreen::Init() {
48  return CheckTestingInterface();
49}
50
51void TestFlashFullscreen::RunTests(const std::string& filter) {
52  RUN_TEST(GetScreenSize, filter);
53  RUN_TEST(NormalToFullscreenToNormal, filter);
54}
55
56std::string TestFlashFullscreen::TestGetScreenSize() {
57  if (screen_size_.width() < 320 || screen_size_.width() > 2560)
58    return ReportError("screen_size.width()", screen_size_.width());
59  if (screen_size_.height() < 200 || screen_size_.height() > 2048)
60    return ReportError("screen_size.height()", screen_size_.height());
61  PASS();
62}
63
64std::string TestFlashFullscreen::TestNormalToFullscreenToNormal() {
65  // 0. Start in normal mode.
66  if (screen_mode_.IsFullscreen())
67    return ReportError("IsFullscreen() at start", true);
68
69  // 1. Switch to fullscreen.
70  // The transition is asynchronous and ends at the next DidChangeView().
71  // No graphics devices can be bound while in transition.
72  fullscreen_pending_ = true;
73  if (!screen_mode_.SetFullscreen(true))
74    return ReportError("SetFullscreen(true) in normal", false);
75  pp::Graphics2D graphics2d_fullscreen(instance_, pp::Size(10, 10), false);
76  if (graphics2d_fullscreen.is_null())
77    return "Failed to create graphics2d_fullscreen";
78  // The out-of-process proxy is asynchronous, so testing for the following
79  // conditions is flaky and can only be done reliably in-process.
80  if (!testing_interface_->IsOutOfProcess()) {
81    if (instance_->BindGraphics(graphics2d_fullscreen))
82      return ReportError("BindGraphics() in fullscreen transition", true);
83    if (screen_mode_.IsFullscreen())
84      return ReportError("IsFullscreen() in fullscreen transtion", true);
85  }
86
87  // DidChangeView() will call the callback once in fullscreen mode.
88  fullscreen_event_.Wait();
89  if (fullscreen_pending_)
90    return "fullscreen_pending_ has not been reset";
91  if (!screen_mode_.IsFullscreen())
92    return ReportError("IsFullscreen() in fullscreen", false);
93  if (!instance_->BindGraphics(graphics2d_fullscreen))
94    return ReportError("BindGraphics() in fullscreen", false);
95
96  // 2. Stay in fullscreen. No change.
97  if (!screen_mode_.SetFullscreen(true))
98    return ReportError("SetFullscreen(true) in fullscreen", false);
99  if (!screen_mode_.IsFullscreen())
100    return ReportError("IsFullscreen() in fullscreen^2", false);
101
102  // 3. Switch to normal.
103  // The transition is synchronous in-process and asynchornous out-of-process
104  // because proxied IsFullscreen saves a roundtrip by relying on information
105  // communicated via a previous call to DidChangeView.
106  // Graphics devices can be bound right away.
107  normal_pending_ = true;
108  if (!screen_mode_.SetFullscreen(false))
109    return ReportError("SetFullscreen(false) in fullscreen", false);
110  pp::Graphics2D graphics2d_normal(instance_, pp::Size(15, 15), false);
111  if (graphics2d_normal.is_null())
112    return "Failed to create graphics2d_normal";
113  if (!instance_->BindGraphics(graphics2d_normal))
114    return ReportError("BindGraphics() in normal transition", false);
115  if (testing_interface_->IsOutOfProcess()) {
116    if (!screen_mode_.IsFullscreen())
117      return ReportError("IsFullscreen() in normal transition", false);
118    normal_event_.Wait();
119    if (normal_pending_)
120      return "normal_pending_ has not been reset";
121  }
122  if (screen_mode_.IsFullscreen())
123    return ReportError("IsFullscreen() in normal", true);
124
125  // 4. Stay in normal. No change.
126  if (!screen_mode_.SetFullscreen(false))
127    return ReportError("SetFullscreen(false) in normal", false);
128  if (screen_mode_.IsFullscreen())
129    return ReportError("IsFullscreen() in normal^2", true);
130
131  PASS();
132}
133
134// Transition to fullscreen is asynchornous ending at DidChangeView.
135// Transition to normal is synchronous in-process and asynchronous
136// out-of-process ending at DidChangeView.
137void TestFlashFullscreen::DidChangeView(const pp::View& view) {
138  pp::Rect position = view.GetRect();
139  pp::Rect clip = view.GetClipRect();
140  if (fullscreen_pending_ && IsFullscreenView(position, clip, screen_size_)) {
141    fullscreen_pending_ = false;
142    fullscreen_event_.Signal();
143  } else if (normal_pending_ &&
144             !IsFullscreenView(position, clip, screen_size_)) {
145    normal_pending_ = false;
146    if (testing_interface_->IsOutOfProcess())
147      normal_event_.Signal();
148  }
149}
150