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 "ppapi/tests/test_instance_deprecated.h" | 5 #include "ppapi/tests/test_instance_deprecated.h" |
6 | 6 |
7 #include <assert.h> | 7 #include <assert.h> |
8 | 8 |
9 #include "ppapi/c/ppb_var.h" | 9 #include "ppapi/c/ppb_var.h" |
10 #include "ppapi/cpp/module.h" | 10 #include "ppapi/cpp/module.h" |
(...skipping 22 matching lines...) Expand all Loading... | |
33 TestInstance* test_instance_; | 33 TestInstance* test_instance_; |
34 // For out-of-process, the InstanceSO might be deleted after the instance was | 34 // For out-of-process, the InstanceSO might be deleted after the instance was |
35 // already destroyed, so we can't rely on test_instance_->testing_interface() | 35 // already destroyed, so we can't rely on test_instance_->testing_interface() |
36 // being valid. Therefore we store our own. | 36 // being valid. Therefore we store our own. |
37 const PPB_Testing_Private* testing_interface_; | 37 const PPB_Testing_Private* testing_interface_; |
38 }; | 38 }; |
39 | 39 |
40 InstanceSO::InstanceSO(TestInstance* i) | 40 InstanceSO::InstanceSO(TestInstance* i) |
41 : test_instance_(i), | 41 : test_instance_(i), |
42 testing_interface_(i->testing_interface()) { | 42 testing_interface_(i->testing_interface()) { |
43 // Set up a post-condition for the test so that we can ensure our destructor | 43 if (testing_interface_->IsOutOfProcess() == PP_FALSE) |
44 // is called. This only works reliably in-process. Out-of-process, it only | 44 test_instance_->set_instance_object_destroyed(false); |
45 // can work when the renderer stays alive a short while after the plugin | |
46 // instance is destroyed. If the renderer is being shut down, too much happens | |
47 // asynchronously for the out-of-process case to work reliably. In | |
48 // particular: | |
49 // - The Var ReleaseObject message is asynchronous. | |
50 // - The PPB_Var_Deprecated host-side proxy posts a task to actually release | |
51 // the object when the ReleaseObject message is received. | |
52 // - The PPP_Class Deallocate message is asynchronous. | |
53 // At time of writing this comment, if you modify the code so that the above | |
54 // happens synchronously, and you remove the restriction that the plugin can't | |
55 // be unblocked by a sync message, then this check actually passes reliably | |
56 // for out-of-process. But we don't want to make any of those changes, so we | |
57 // just skip the check. | |
58 if (testing_interface_->IsOutOfProcess() == PP_FALSE) { | |
59 i->instance()->AddPostCondition( | |
dmichael (off chromium)
2014/08/20 17:55:53
FWIW, I think this was the only usage of "AddPostC
| |
60 "window.document.getElementById('container').instance_object_destroyed" | |
61 ); | |
62 } | |
63 } | 45 } |
64 | 46 |
65 InstanceSO::~InstanceSO() { | 47 InstanceSO::~InstanceSO() { |
66 if (testing_interface_->IsOutOfProcess() == PP_FALSE) { | 48 test_instance_->set_instance_object_destroyed(true); |
67 // TODO(dmichael): It would probably be best to make in-process consistent | |
68 // with out-of-process. That would mean that the instance | |
69 // would already be destroyed at this point. | |
70 pp::Var ret = test_instance_->instance()->ExecuteScript( | |
71 "document.getElementById('container').instance_object_destroyed=true;"); | |
72 } else { | |
73 // Out-of-process, this destructor might not actually get invoked. See the | |
74 // comment in InstanceSO's constructor for an explanation. Also, instance() | |
75 // has already been destroyed :-(. So we can't really do anything here. | |
76 } | |
77 } | 49 } |
78 | 50 |
79 bool InstanceSO::HasMethod(const pp::Var& name, pp::Var* exception) { | 51 bool InstanceSO::HasMethod(const pp::Var& name, pp::Var* exception) { |
80 if (!name.is_string()) | 52 if (!name.is_string()) |
81 return false; | 53 return false; |
82 return name.AsString() == kSetValueFunction || | 54 return name.AsString() == kSetValueFunction || |
83 name.AsString() == kSetExceptionFunction || | 55 name.AsString() == kSetExceptionFunction || |
84 name.AsString() == kReturnValueFunction; | 56 name.AsString() == kReturnValueFunction; |
85 } | 57 } |
86 | 58 |
(...skipping 23 matching lines...) Expand all Loading... | |
110 *exception = pp::Var("Bad function call"); | 82 *exception = pp::Var("Bad function call"); |
111 } | 83 } |
112 | 84 |
113 return pp::Var(); | 85 return pp::Var(); |
114 } | 86 } |
115 | 87 |
116 } // namespace | 88 } // namespace |
117 | 89 |
118 REGISTER_TEST_CASE(Instance); | 90 REGISTER_TEST_CASE(Instance); |
119 | 91 |
120 TestInstance::TestInstance(TestingInstance* instance) : TestCase(instance) { | 92 TestInstance::TestInstance(TestingInstance* instance) |
121 } | 93 : TestCase(instance), |
94 instance_object_destroyed_(false) {} | |
122 | 95 |
123 bool TestInstance::Init() { | 96 bool TestInstance::Init() { |
124 return true; | 97 return true; |
125 } | 98 } |
126 | 99 |
127 TestInstance::~TestInstance() { | 100 TestInstance::~TestInstance() { |
128 ResetTestObject(); | 101 ResetTestObject(); |
129 // When running tests in process, some post conditions check that teardown | 102 if (testing_interface_->IsOutOfProcess() == PP_FALSE) { |
130 // happened successfully. We need to run the garbage collector to ensure that | 103 // This should cause the instance objects descructor to be called. |
131 // vars get released. | |
132 if (testing_interface_->IsOutOfProcess() == PP_FALSE) | |
133 testing_interface_->RunV8GC(instance_->pp_instance()); | 104 testing_interface_->RunV8GC(instance_->pp_instance()); |
105 | |
106 // Test a post-condition which ensures the instance objects destructor is | |
107 // called. This only works reliably in-process. Out-of-process, it only | |
108 // can work when the renderer stays alive a short while after the plugin | |
109 // instance is destroyed. If the renderer is being shut down, too much | |
110 // happens asynchronously for the out-of-process case to work reliably. In | |
111 // particular: | |
112 // - The Var ReleaseObject message is asynchronous. | |
113 // - The PPB_Var_Deprecated host-side proxy posts a task to actually | |
114 // release the object when the ReleaseObject message is received. | |
115 // - The PPP_Class Deallocate message is asynchronous. | |
116 // At time of writing this comment, if you modify the code so that the above | |
117 // happens synchronously, and you remove the restriction that the plugin | |
118 // can't be unblocked by a sync message, then this check actually passes | |
119 // reliably for out-of-process. But we don't want to make any of those | |
120 // changes so we just skip the check. | |
121 PP_DCHECK(instance_object_destroyed_); | |
122 } else { | |
123 // Out-of-process, this destructor might not actually get invoked. See the | |
124 // comment in InstanceSO's constructor for an explanation. Also, instance() | |
125 // has already been destroyed :-(. So we can't really do anything here. | |
126 } | |
127 | |
134 // Save the fact that we were destroyed in sessionStorage. This tests that | 128 // Save the fact that we were destroyed in sessionStorage. This tests that |
135 // we can ExecuteScript at instance destruction without crashing. It also | 129 // we can ExecuteScript at instance destruction without crashing. It also |
136 // allows us to check that ExecuteScript will run and succeed in certain | 130 // allows us to check that ExecuteScript will run and succeed in certain |
137 // cases. In particular, when the instance is destroyed by normal DOM | 131 // cases. In particular, when the instance is destroyed by normal DOM |
138 // deletion, ExecuteScript will actually work. See | 132 // deletion, ExecuteScript will actually work. See |
139 // TestExecuteScriptInInstanceShutdown for that test. Note, however, that | 133 // TestExecuteScriptInInstanceShutdown for that test. Note, however, that |
140 // ExecuteScript will *not* have an effect when the instance is destroyed | 134 // ExecuteScript will *not* have an effect when the instance is destroyed |
141 // because the renderer was shut down. | 135 // because the renderer was shut down. |
142 pp::Var ret = instance()->ExecuteScript( | 136 pp::Var ret = instance()->ExecuteScript( |
143 "sessionStorage.setItem('instance_destroyed', 'true');"); | 137 "sessionStorage.setItem('instance_destroyed', 'true');"); |
(...skipping 148 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
292 // that it was set as expected. | 286 // that it was set as expected. |
293 pp::Var result = instance()->ExecuteScript( | 287 pp::Var result = instance()->ExecuteScript( |
294 "sessionStorage.getItem('instance_destroyed');"); | 288 "sessionStorage.getItem('instance_destroyed');"); |
295 ASSERT_TRUE(result.is_string()); | 289 ASSERT_TRUE(result.is_string()); |
296 ASSERT_EQ(std::string("true"), result.AsString()); | 290 ASSERT_EQ(std::string("true"), result.AsString()); |
297 instance()->ExecuteScript("sessionStorage.removeItem('instance_destroyed');"); | 291 instance()->ExecuteScript("sessionStorage.removeItem('instance_destroyed');"); |
298 | 292 |
299 PASS(); | 293 PASS(); |
300 } | 294 } |
301 | 295 |
OLD | NEW |