OLD | NEW |
---|---|
(Empty) | |
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.examples.android; | |
6 | |
7 import android.content.Context; | |
8 import android.util.Log; | |
9 | |
10 import org.chromium.mojo.bindings.Interface; | |
11 import org.chromium.mojo.bindings.Interface.Proxy; | |
12 import org.chromium.mojo.bindings.InterfaceRequest; | |
13 import org.chromium.mojo.system.Core; | |
14 import org.chromium.mojo.system.MessagePipeHandle; | |
15 import org.chromium.mojo.system.MojoException; | |
16 import org.chromium.mojo.system.RunLoop; | |
17 import org.chromium.mojom.mojo.Application; | |
18 import org.chromium.mojom.mojo.ExampleService; | |
19 import org.chromium.mojom.mojo.ServiceProvider; | |
20 import org.chromium.mojom.mojo.Shell; | |
21 | |
22 import java.lang.reflect.Field; | |
23 import java.lang.reflect.InvocationTargetException; | |
24 import java.util.ArrayList; | |
25 import java.util.HashMap; | |
26 import java.util.List; | |
27 import java.util.Map; | |
28 | |
29 /** | |
30 * App holds all the code for this example application. | |
31 */ | |
32 class App { | |
33 private static String sTAG = "AndroidTestApp"; | |
qsr
2015/02/05 16:50:07
We usually name this just TAG.
etiennej
2015/02/06 16:22:29
Done. We should remove the presubmit error that re
| |
34 | |
35 public static class ApplicationImpl implements Application { | |
36 private Shell mShell; | |
37 private List<ServiceProvider> mProviders = new ArrayList<ServiceProvider >(); | |
38 | |
39 public ApplicationImpl(MessagePipeHandle applicationRequest) { | |
40 ApplicationImpl.MANAGER.bind(this, applicationRequest); | |
41 } | |
42 | |
43 @Override | |
44 public void initialize(Shell shell, String[] args) { | |
45 mShell = shell; | |
46 } | |
47 | |
48 @Override | |
49 public void acceptConnection(String requestorUrl, | |
50 InterfaceRequest<ServiceProvider> services, ServiceProvider expo sedServices) { | |
51 ServiceProviderImpl serviceProvider = new ServiceProviderImpl(servic es); | |
52 serviceProvider.addService(ExampleServiceImpl.class); | |
53 ServiceProvider.MANAGER.bind(serviceProvider, services); | |
54 mProviders.add(serviceProvider); | |
qsr
2015/02/05 16:50:07
If you are not using exposedServices, you should c
etiennej
2015/02/06 16:22:29
Done.
| |
55 }; | |
56 | |
57 @Override | |
58 public void requestQuit() {} | |
qsr
2015/02/05 16:50:07
This should stop the runloop.
etiennej
2015/02/06 16:22:29
Done.
| |
59 | |
60 @Override | |
61 public void close() {} | |
qsr
2015/02/05 16:50:07
This should probably close mShell.
etiennej
2015/02/06 16:22:29
Done.
| |
62 | |
63 @Override | |
64 public void onConnectionError(MojoException e) {} | |
65 } | |
66 | |
67 public static class ServiceProviderImpl implements ServiceProvider { | |
68 /** | |
69 * ServiceFactoryBinder holds the necessary information to bind a servic e interface to a | |
70 * message pipe. | |
71 */ | |
72 private static class ServiceFactoryBinder { | |
73 private final Class<Interface> mServiceClass; | |
74 private final Manager<Interface, ? extends Proxy> mManager; | |
75 | |
76 public ServiceFactoryBinder(Class<Interface> serviceClass) { | |
77 mServiceClass = serviceClass; | |
78 Field managerField; | |
79 try { | |
80 managerField = serviceClass.getField("MANAGER"); | |
81 } catch (NoSuchFieldException e) { | |
82 throw new RuntimeException(e); | |
83 } | |
84 try { | |
85 // localManager is used to limit the scope of | |
86 // @SuppressWarnings. | |
87 @SuppressWarnings("unchecked") | |
88 Manager<Interface, ? extends Proxy> localManager = | |
89 (Manager<Interface, ? extends Proxy>) managerField.g et(null); | |
90 this.mManager = localManager; | |
91 } catch (IllegalAccessException e) { | |
92 throw new RuntimeException(e); | |
93 } | |
94 } | |
95 | |
96 public void bindNewInstanceToMessagePipe(MessagePipeHandle pipe) { | |
97 try { | |
98 mManager.bind(mServiceClass.getConstructor().newInstance(), pipe); | |
qsr
2015/02/05 16:50:07
Can you not to use reflection? You can define an
etiennej
2015/02/06 16:22:29
Done.
| |
99 } catch (NoSuchMethodException e) { | |
100 throw new RuntimeException(e); | |
101 } catch (InstantiationException e) { | |
102 throw new RuntimeException(e); | |
103 } catch (IllegalAccessException e) { | |
104 throw new RuntimeException(e); | |
105 } catch (InvocationTargetException e) { | |
106 throw new RuntimeException(e); | |
107 } | |
108 } | |
109 | |
110 public String getInterfaceName() { | |
111 return mManager.getName(); | |
112 } | |
113 } | |
114 | |
115 private InterfaceRequest<ServiceProvider> mProvider; | |
qsr
2015/02/05 16:50:07
You do not need to keep this object alive.
etiennej
2015/02/06 16:22:29
Done.
| |
116 private Map<String, ServiceFactoryBinder> mNameToServiceMap = | |
117 new HashMap<String, ServiceFactoryBinder>(); | |
118 | |
119 public ServiceProviderImpl(InterfaceRequest<ServiceProvider> provider) { | |
120 mProvider = provider; | |
121 } | |
122 | |
123 /** | |
124 * AddService adds a new service to the list of services provided by thi s application. | |
125 */ | |
126 public void addService(Class serviceImpl) { | |
127 @SuppressWarnings("unchecked") | |
128 ServiceFactoryBinder binder = new ServiceFactoryBinder(serviceImpl); | |
129 mNameToServiceMap.put(binder.getInterfaceName(), binder); | |
130 } | |
131 | |
132 @Override | |
133 public void connectToService(String interfaceName, MessagePipeHandle pip e) { | |
134 if (mNameToServiceMap.containsKey(interfaceName)) { | |
135 mNameToServiceMap.get(interfaceName).bindNewInstanceToMessagePip e(pipe); | |
136 } | |
qsr
2015/02/05 16:50:07
You and to close the pipe if you do not bind it.
etiennej
2015/02/06 16:22:29
Done.
| |
137 } | |
138 | |
139 @Override | |
140 public void close() {} | |
141 | |
142 @Override | |
143 public void onConnectionError(MojoException e) {} | |
144 } | |
145 | |
146 public static class ExampleServiceImpl implements ExampleService { | |
147 public ExampleServiceImpl() {} | |
148 | |
149 @Override | |
150 public void ping(short pingValue, ExampleService.PingResponse callback) { | |
151 callback.call(pingValue); | |
152 } | |
153 | |
154 @Override | |
155 public void close() {} | |
156 | |
157 @Override | |
158 public void onConnectionError(MojoException e) {} | |
159 } | |
160 | |
161 public static void mojoMain(Context context, Core core, int applicationReque stHandle) { | |
162 Log.i(sTAG, "App.MojoMain called"); | |
163 RunLoop runLoop = core.createDefaultRunLoop(); | |
164 Log.i(sTAG, "Run loop created"); | |
165 | |
166 MessagePipeHandle handle = | |
167 core.acquireNativeHandle(applicationRequestHandle).toMessagePipe Handle(); | |
168 Application application = new ApplicationImpl(handle); | |
169 | |
170 Log.i(sTAG, "Setup done, starting run loop"); | |
171 runLoop.run(); | |
172 Log.i(sTAG, "Run loop exited"); | |
173 } | |
174 } | |
OLD | NEW |