1 // Copyright 2015 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 package org.chromium.mojo.bindings;
6 
7 import androidx.test.filters.SmallTest;
8 
9 import org.junit.After;
10 import org.junit.Assert;
11 import org.junit.Rule;
12 import org.junit.Test;
13 import org.junit.runner.RunWith;
14 
15 import org.chromium.base.test.BaseJUnit4ClassRunner;
16 import org.chromium.mojo.MojoTestRule;
17 import org.chromium.mojo.bindings.Callbacks.Callback1;
18 import org.chromium.mojo.bindings.test.mojom.sample.IntegerAccessor;
19 import org.chromium.mojo.system.MojoException;
20 
21 import java.io.Closeable;
22 import java.util.ArrayList;
23 import java.util.Collections;
24 import java.util.List;
25 
26 /**
27  * Tests for interface control messages.
28  */
29 @RunWith(BaseJUnit4ClassRunner.class)
30 public class InterfaceControlMessageTest {
31     @Rule
32     public MojoTestRule mTestRule = new MojoTestRule();
33 
34     private final List<Closeable> mCloseablesToClose = new ArrayList<Closeable>();
35 
36     /**
37      * See mojo/public/interfaces/bindings/tests/sample_interfaces.mojom.
38      */
39     class IntegerAccessorImpl extends SideEffectFreeCloseable implements IntegerAccessor {
40         private long mValue;
41         private int mEnum;
42         private boolean mEncounteredError;
43 
44         /**
45          * @see ConnectionErrorHandler#onConnectionError(MojoException)
46          */
47         @Override
onConnectionError(MojoException e)48         public void onConnectionError(MojoException e) {
49             mEncounteredError = true;
50         }
51 
52         /**
53          * @see IntegerAccessor#getInteger(IntegerAccessor.GetIntegerResponse)
54          */
55         @Override
getInteger(GetIntegerResponse response)56         public void getInteger(GetIntegerResponse response) {
57             response.call(mValue, mEnum);
58         }
59 
60         /**
61          * @see IntegerAccessor#setInteger(long, int)
62          */
63         @Override
setInteger(long value, int enumValue)64         public void setInteger(long value, int enumValue) {
65             mValue = value;
66             mEnum = enumValue;
67         }
68 
getValue()69         public long getValue() {
70             return mValue;
71         }
72 
encounteredError()73         public boolean encounteredError() {
74             return mEncounteredError;
75         }
76     }
77 
78     /**
79      * @see MojoTestCase#tearDown()
80      */
81     @After
tearDown()82     public void tearDown() throws Exception {
83         // Close the elements in the reverse order they were added. This is needed because it is an
84         // error to close the handle of a proxy without closing the proxy first.
85         Collections.reverse(mCloseablesToClose);
86         for (Closeable c : mCloseablesToClose) {
87             c.close();
88         }
89     }
90 
91     @Test
92     @SmallTest
testQueryVersion()93     public void testQueryVersion() {
94         IntegerAccessor.Proxy p = BindingsTestUtils.newProxyOverPipe(
95                 IntegerAccessor.MANAGER, new IntegerAccessorImpl(), mCloseablesToClose);
96         Assert.assertEquals(0, p.getProxyHandler().getVersion());
97         p.getProxyHandler().queryVersion(new Callback1<Integer>() {
98             @Override
99             public void call(Integer version) {
100                 Assert.assertEquals(3, version.intValue());
101             }
102         });
103         mTestRule.runLoopUntilIdle();
104         Assert.assertEquals(3, p.getProxyHandler().getVersion());
105     }
106 
107     @Test
108     @SmallTest
testRequireVersion()109     public void testRequireVersion() {
110         IntegerAccessorImpl impl = new IntegerAccessorImpl();
111         IntegerAccessor.Proxy p = BindingsTestUtils.newProxyOverPipe(
112                 IntegerAccessor.MANAGER, impl, mCloseablesToClose);
113 
114         Assert.assertEquals(0, p.getProxyHandler().getVersion());
115 
116         p.getProxyHandler().requireVersion(1);
117         Assert.assertEquals(1, p.getProxyHandler().getVersion());
118         p.setInteger(123, Enum.VALUE);
119         mTestRule.runLoopUntilIdle();
120         Assert.assertFalse(impl.encounteredError());
121         Assert.assertEquals(123, impl.getValue());
122 
123         p.getProxyHandler().requireVersion(3);
124         Assert.assertEquals(3, p.getProxyHandler().getVersion());
125         p.setInteger(456, Enum.VALUE);
126         mTestRule.runLoopUntilIdle();
127         Assert.assertFalse(impl.encounteredError());
128         Assert.assertEquals(456, impl.getValue());
129 
130         // Require a version that is not supported by the implementation side.
131         p.getProxyHandler().requireVersion(4);
132         // getVersion() is updated synchronously.
133         Assert.assertEquals(4, p.getProxyHandler().getVersion());
134         p.setInteger(789, Enum.VALUE);
135         mTestRule.runLoopUntilIdle();
136         Assert.assertTrue(impl.encounteredError());
137         // The call to setInteger() after requireVersion() is ignored.
138         Assert.assertEquals(456, impl.getValue());
139     }
140 }
141