Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(197)

Unified Diff: third_party/mojo/src/mojo/public/python/mojo_bindings/interface_reflection.py

Issue 1127293003: Update mojo sdk to rev f84766d3b6420b7cf6a113d9d65d73cb5fe18d90 (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: formatting Created 5 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: third_party/mojo/src/mojo/public/python/mojo_bindings/interface_reflection.py
diff --git a/third_party/mojo/src/mojo/public/python/mojo_bindings/reflection.py b/third_party/mojo/src/mojo/public/python/mojo_bindings/interface_reflection.py
similarity index 59%
copy from third_party/mojo/src/mojo/public/python/mojo_bindings/reflection.py
copy to third_party/mojo/src/mojo/public/python/mojo_bindings/interface_reflection.py
index e41601a6d0c8960e06e0049f94fbe0d28d7c2fe1..8ce3882106ba7deb30bd3b0b562365e5fc8bebdb 100644
--- a/third_party/mojo/src/mojo/public/python/mojo_bindings/reflection.py
+++ b/third_party/mojo/src/mojo/public/python/mojo_bindings/interface_reflection.py
@@ -1,145 +1,26 @@
-# Copyright 2014 The Chromium Authors. All rights reserved.
+# Copyright 2015 The Chromium Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
-"""The metaclasses used by the mojo python bindings."""
+"""
+The metaclasses used by the mojo python bindings for interfaces.
+
+It is splitted from mojo_bindings.reflection because it uses some generated code
+that would create a cyclic dependency.
+"""
-import itertools
import logging
import sys
# pylint: disable=F0401
+import interface_control_messages_mojom
import mojo_bindings.messaging as messaging
import mojo_bindings.promise as promise
+import mojo_bindings.reflection as reflection
import mojo_bindings.serialization as serialization
import mojo_system
-class MojoEnumType(type):
- """Meta class for enumerations.
-
- Usage:
- class MyEnum(object):
- __metaclass__ = MojoEnumType
- VALUES = [
- ('A', 0),
- 'B',
- ('C', 5),
- ]
-
- This will define a enum with 3 values, 'A' = 0, 'B' = 1 and 'C' = 5.
- """
-
- def __new__(mcs, name, bases, dictionary):
- dictionary['__slots__'] = ()
- dictionary['__new__'] = None
- for value in dictionary.pop('VALUES', []):
- if not isinstance(value, tuple):
- raise ValueError('incorrect value: %r' % value)
- key, enum_value = value
- if isinstance(key, str) and isinstance(enum_value, int):
- dictionary[key] = enum_value
- else:
- raise ValueError('incorrect value: %r' % value)
- return type.__new__(mcs, name, bases, dictionary)
-
- def __setattr__(cls, key, value):
- raise AttributeError('can\'t set attribute')
-
- def __delattr__(cls, key):
- raise AttributeError('can\'t delete attribute')
-
-
-class MojoStructType(type):
- """Meta class for structs.
-
- Usage:
- class MyStruct(object):
- __metaclass__ = MojoStructType
- DESCRIPTOR = {
- 'constants': {
- 'C1': 1,
- 'C2': 2,
- },
- 'enums': {
- 'ENUM1': [
- ('V1', 1),
- 'V2',
- ],
- 'ENUM2': [
- ('V1', 1),
- 'V2',
- ],
- },
- 'fields': [
- SingleFieldGroup('x', _descriptor.TYPE_INT32, 0, 0),
- ],
- }
-
- This will define an struct, with:
- - 2 constants 'C1' and 'C2';
- - 2 enums 'ENUM1' and 'ENUM2', each of those having 2 values, 'V1' and
- 'V2';
- - 1 int32 field named 'x'.
- """
-
- def __new__(mcs, name, bases, dictionary):
- dictionary['__slots__'] = ('_fields')
- descriptor = dictionary.pop('DESCRIPTOR', {})
-
- # Add constants
- dictionary.update(descriptor.get('constants', {}))
-
- # Add enums
- enums = descriptor.get('enums', {})
- for key in enums:
- dictionary[key] = MojoEnumType(key, (object,), { 'VALUES': enums[key] })
-
- # Add fields
- groups = descriptor.get('fields', [])
-
- fields = list(
- itertools.chain.from_iterable([group.descriptors for group in groups]))
- fields.sort(key=lambda f: f.index)
- for field in fields:
- dictionary[field.name] = _BuildProperty(field)
-
- # Add init
- dictionary['__init__'] = _StructInit(fields)
-
- # Add serialization method
- serialization_object = serialization.Serialization(groups)
- def Serialize(self, handle_offset=0):
- return serialization_object.Serialize(self, handle_offset)
- dictionary['Serialize'] = Serialize
-
- # pylint: disable=W0212
- def AsDict(self):
- return self._fields
- dictionary['AsDict'] = AsDict
-
- def Deserialize(cls, context):
- result = cls.__new__(cls)
- fields = {}
- serialization_object.Deserialize(fields, context)
- result._fields = fields
- return result
- dictionary['Deserialize'] = classmethod(Deserialize)
-
- dictionary['__eq__'] = _StructEq(fields)
- dictionary['__ne__'] = _StructNe
-
- return type.__new__(mcs, name, bases, dictionary)
-
- # Prevent adding new attributes, or mutating constants.
- def __setattr__(cls, key, value):
- raise AttributeError('can\'t set attribute')
-
- # Prevent deleting constants.
- def __delattr__(cls, key):
- raise AttributeError('can\'t delete attribute')
-
-
class MojoInterfaceType(type):
"""Meta class for interfaces.
@@ -147,6 +28,8 @@ class MojoInterfaceType(type):
class MyInterface(object):
__metaclass__ = MojoInterfaceType
DESCRIPTOR = {
+ 'fully_qualified_name': 'service::MyInterface'
+ 'version': 3,
'methods': [
{
'name': 'FireAndForget',
@@ -183,7 +66,8 @@ class MojoInterfaceType(type):
dictionary[method.name] = _NotImplemented
fully_qualified_name = descriptor['fully_qualified_name']
- interface_manager = InterfaceManager(fully_qualified_name, methods)
+ interface_manager = InterfaceManager(
+ fully_qualified_name, descriptor['version'], methods)
dictionary.update({
'manager': None,
'_interface_manager': interface_manager,
@@ -206,34 +90,6 @@ class MojoInterfaceType(type):
raise AttributeError('can\'t delete attribute')
-class InterfaceProxy(object):
- """
- A proxy allows to access a remote interface through a message pipe.
- """
- pass
-
-
-class InterfaceRequest(object):
- """
- An interface request allows to send a request for an interface to a remote
- object and start using it immediately.
- """
-
- def __init__(self, handle):
- self._handle = handle
-
- def IsPending(self):
- return self._handle.IsValid()
-
- def PassMessagePipe(self):
- result = self._handle
- self._handle = None
- return result
-
- def Bind(self, impl):
- type(impl).manager.Bind(impl, self.PassMessagePipe())
-
-
class InterfaceManager(object):
"""
Manager for an interface class. The manager contains the operation that allows
@@ -241,19 +97,20 @@ class InterfaceManager(object):
over a pipe.
"""
- def __init__(self, name, methods):
+ def __init__(self, name, version, methods):
self.name = name
+ self.version = version
self.methods = methods
self.interface_class = None
self._proxy_class = None
self._stub_class = None
- def Proxy(self, handle):
+ def Proxy(self, handle, version=0):
router = messaging.Router(handle)
error_handler = _ProxyErrorHandler()
router.SetErrorHandler(error_handler)
router.Start()
- return self._InternalProxy(router, error_handler)
+ return self._InternalProxy(router, error_handler, version)
# pylint: disable=W0212
def Bind(self, impl, handle):
@@ -270,15 +127,15 @@ class InterfaceManager(object):
# Give an instance manager to the implementation to allow it to close
# the connection.
- impl.manager = InstanceManager(router, error_handler)
+ impl.manager = InstanceManager(self, router, error_handler)
router.Start()
def NewRequest(self):
pipe = mojo_system.MessagePipe()
- return (self.Proxy(pipe.handle0), InterfaceRequest(pipe.handle1))
+ return (self.Proxy(pipe.handle0), reflection.InterfaceRequest(pipe.handle1))
- def _InternalProxy(self, router, error_handler):
+ def _InternalProxy(self, router, error_handler, version):
if error_handler is None:
error_handler = _ProxyErrorHandler()
@@ -289,13 +146,15 @@ class InterfaceManager(object):
}
for method in self.methods:
dictionary[method.name] = _ProxyMethodCall(method)
- self._proxy_class = type('%sProxy' % self.name,
- (self.interface_class, InterfaceProxy),
- dictionary)
+ self._proxy_class = type(
+ '%sProxy' % self.name,
+ (self.interface_class, reflection.InterfaceProxy),
+ dictionary)
proxy = self._proxy_class(router, error_handler)
# Give an instance manager to the proxy to allow to close the connection.
- proxy.manager = InstanceManager(router, error_handler)
+ proxy.manager = ProxyInstanceManager(
+ self, proxy, router, error_handler, version)
return proxy
def _Stub(self, impl):
@@ -318,7 +177,8 @@ class InstanceManager(object):
Manager for the implementation of an interface or a proxy. The manager allows
to control the connection over the pipe.
"""
- def __init__(self, router, error_handler):
+ def __init__(self, interface_manager, router, error_handler):
+ self.interface_manager = interface_manager
self._router = router
self._error_handler = error_handler
assert self._error_handler is not None
@@ -335,25 +195,79 @@ class InstanceManager(object):
self._error_handler.AddCallback(lambda _: callback(), False)
-class _MethodDescriptor(object):
+class ProxyInstanceManager(InstanceManager):
+ """
+ Manager for the implementation of a proxy. The manager allows to control the
+ connection over the pipe.
+ """
+ def __init__(self, interface_manager, proxy, router, error_handler, version):
+ super(ProxyInstanceManager, self).__init__(
+ interface_manager, router, error_handler)
+ self.proxy = proxy
+ self.version = version
+ self._run_method = _ProxyMethodCall(_BaseMethodDescriptor(
+ 'Run',
+ interface_control_messages_mojom.RUN_MESSAGE_ID,
+ interface_control_messages_mojom.RunMessageParams,
+ interface_control_messages_mojom.RunResponseMessageParams))
+ self._run_or_close_pipe_method = _ProxyMethodCall(_BaseMethodDescriptor(
+ 'RunOrClosePipe',
+ interface_control_messages_mojom.RUN_OR_CLOSE_PIPE_MESSAGE_ID,
+ interface_control_messages_mojom.RunOrClosePipeMessageParams,
+ None))
+
+ def QueryVersion(self):
+ params = interface_control_messages_mojom.RunMessageParams()
+ params.reserved0 = 16
+ params.reserved1 = 0
+ params.query_version = (
+ interface_control_messages_mojom.QueryVersion())
+ def ToVersion(r):
+ self.version = r.query_version_result.version
+ return self.version
+ return self._run_method(self.proxy, **params.AsDict()).Then(ToVersion)
+
+ def RequireVersion(self, version):
+ if self.version >= version:
+ return
+ self.version = version
+ params = interface_control_messages_mojom.RunOrClosePipeMessageParams()
+ params.reserved0 = 16
+ params.reserved1 = 0
+ params.require_version = interface_control_messages_mojom.RequireVersion()
+ params.require_version.version = version
+ return self._run_or_close_pipe_method(self.proxy, **params.AsDict())
+
+
+class _BaseMethodDescriptor(object):
+ def __init__(self, name, ordinal, parameters_struct, response_struct):
+ self.name = name
+ self.ordinal = ordinal
+ self.parameters_struct = parameters_struct
+ self.response_struct = response_struct
+
+
+class _MethodDescriptor(_BaseMethodDescriptor):
def __init__(self, descriptor):
- self.name = descriptor['name']
- self.ordinal = descriptor['ordinal']
- self.parameters_struct = _ConstructParameterStruct(
- descriptor['parameters'], self.name, "Parameters")
- self.response_struct = _ConstructParameterStruct(
- descriptor.get('responses'), self.name, "Responses")
+ name = descriptor['name']
+ super(_MethodDescriptor, self).__init__(
+ name,
+ descriptor['ordinal'],
+ _ConstructParameterStruct(
+ descriptor['parameters'], name, "Parameters"),
+ _ConstructParameterStruct(
+ descriptor.get('responses'), name, "Responses"))
def _ConstructParameterStruct(descriptor, name, suffix):
if descriptor is None:
return None
parameter_dictionary = {
- '__metaclass__': MojoStructType,
+ '__metaclass__': reflection.MojoStructType,
'__module__': __name__,
'DESCRIPTOR': descriptor,
}
- return MojoStructType(
+ return reflection.MojoStructType(
'%s%s' % (name, suffix),
(object,),
parameter_dictionary)
@@ -404,56 +318,6 @@ class _Retainer(object):
_Retainer._RETAINED.remove(self)
-def _StructInit(fields):
- def _Init(self, *args, **kwargs):
- if len(args) + len(kwargs) > len(fields):
- raise TypeError('__init__() takes %d argument (%d given)' %
- (len(fields), len(args) + len(kwargs)))
- self._fields = {}
- for f, a in zip(fields, args):
- self.__setattr__(f.name, a)
- remaining_fields = set(x.name for x in fields[len(args):])
- for name in kwargs:
- if not name in remaining_fields:
- if name in (x.name for x in fields[:len(args)]):
- raise TypeError(
- '__init__() got multiple values for keyword argument %r' % name)
- raise TypeError('__init__() got an unexpected keyword argument %r' %
- name)
- self.__setattr__(name, kwargs[name])
- return _Init
-
-
-def _BuildProperty(field):
- """Build the property for the given field."""
-
- # pylint: disable=W0212
- def Get(self):
- if field.name not in self._fields:
- self._fields[field.name] = field.GetDefaultValue()
- return self._fields[field.name]
-
- # pylint: disable=W0212
- def Set(self, value):
- self._fields[field.name] = field.field_type.Convert(value)
-
- return property(Get, Set)
-
-
-def _StructEq(fields):
- def _Eq(self, other):
- if type(self) is not type(other):
- return False
- for field in fields:
- if getattr(self, field.name) != getattr(other, field.name):
- return False
- return True
- return _Eq
-
-def _StructNe(self, other):
- return not self.__eq__(other)
-
-
def _ProxyInit(self, router, error_handler):
self._router = router
self._error_handler = error_handler
@@ -466,7 +330,7 @@ def _ProxyMethodCall(method):
flags = messaging.MESSAGE_EXPECTS_RESPONSE_FLAG
def _Call(self, *args, **kwargs):
def GenerationMethod(resolve, reject):
- message = _GetMessage(method, flags, *args, **kwargs)
+ message = _GetMessage(method, flags, None, *args, **kwargs)
if method.response_struct:
def Accept(message):
try:
@@ -504,18 +368,23 @@ def _ProxyMethodCall(method):
return _Call
-def _GetMessage(method, flags, *args, **kwargs):
- if flags == messaging.MESSAGE_IS_RESPONSE_FLAG:
- struct = method.response_struct(*args, **kwargs)
- else:
- struct = method.parameters_struct(*args, **kwargs)
- header = messaging.MessageHeader(method.ordinal, flags)
+def _GetMessageWithStruct(struct, ordinal, flags, request_id):
+ header = messaging.MessageHeader(
+ ordinal, flags, 0 if request_id is None else request_id)
data = header.Serialize()
(payload, handles) = struct.Serialize()
data.extend(payload)
return messaging.Message(data, handles, header)
+def _GetMessage(method, flags, request_id, *args, **kwargs):
+ if flags == messaging.MESSAGE_IS_RESPONSE_FLAG:
+ struct = method.response_struct(*args, **kwargs)
+ else:
+ struct = method.parameters_struct(*args, **kwargs)
+ return _GetMessageWithStruct(struct, method.ordinal, flags, request_id)
+
+
def _StubInit(self, impl):
self.impl = impl
@@ -526,6 +395,11 @@ def _StubAccept(methods):
try:
header = message.header
assert header.expects_response == bool(responder)
+ if header.message_type == interface_control_messages_mojom.RUN_MESSAGE_ID:
+ return _RunMessage(self.impl.manager, message, responder)
+ if (header.message_type ==
+ interface_control_messages_mojom.RUN_OR_CLOSE_PIPE_MESSAGE_ID):
+ return _RunMessageOrClosePipe(self.impl.manager, message)
assert header.message_type in methods_by_ordinal
method = methods_by_ordinal[header.message_type]
payload = message.payload
@@ -539,12 +413,13 @@ def _StubAccept(methods):
if isinstance(response, dict):
response_message = _GetMessage(method,
messaging.MESSAGE_IS_RESPONSE_FLAG,
+ header.request_id,
**response)
else:
response_message = _GetMessage(method,
messaging.MESSAGE_IS_RESPONSE_FLAG,
+ header.request_id,
response)
- response_message.header.request_id = header.request_id
return responder.Accept(response_message)
p = SendResponse(response)
if self.impl.manager:
@@ -563,5 +438,29 @@ def _StubAccept(methods):
return Accept
+def _RunMessage(manager, message, responder):
+ response = interface_control_messages_mojom.RunResponseMessageParams()
+ response.reserved0 = 16
+ response.reserved1 = 0
+ response.query_version_result = (
+ interface_control_messages_mojom.QueryVersionResult())
+ response.query_version_result.version = manager.interface_manager.version
+ response_message = _GetMessageWithStruct(
+ response,
+ interface_control_messages_mojom.RUN_MESSAGE_ID,
+ messaging.MESSAGE_IS_RESPONSE_FLAG,
+ message.header.request_id)
+ return responder.Accept(response_message)
+
+
+def _RunMessageOrClosePipe(manager, message):
+ payload = message.payload
+ query = (
+ interface_control_messages_mojom.RunOrClosePipeMessageParams.Deserialize(
+ serialization.RootDeserializationContext(payload.data,
+ payload.handles)))
+ return query.require_version.version <= manager.interface_manager.version
+
+
def _NotImplemented(*_1, **_2):
raise NotImplementedError()

Powered by Google App Engine
This is Rietveld 408576698