diff --git a/mojo/dart/packages/mojo_services/lib/activity/activity.mojom.dart b/mojo/dart/packages/mojo_services/lib/activity/activity.mojom.dart
new file mode 100644
index 0000000..ef2fc79
--- /dev/null
+++ b/mojo/dart/packages/mojo_services/lib/activity/activity.mojom.dart
@@ -0,0 +1,2324 @@
+// Copyright 2014 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.
+
+library activity_mojom;
+
+import 'dart:async';
+
+import 'package:mojo/bindings.dart' as bindings;
+import 'package:mojo/core.dart' as core;
+class SystemUiVisibility extends bindings.MojoEnum {
+  static const STANDARD = const SystemUiVisibility._(0);
+  static const FULLSCREEN = const SystemUiVisibility._(1);
+  static const IMMERSIVE = const SystemUiVisibility._(2);
+
+  const SystemUiVisibility._(int v) : super(v);
+
+  static const Map<String, SystemUiVisibility> valuesMap = const {
+    "STANDARD": STANDARD,
+    "FULLSCREEN": FULLSCREEN,
+    "IMMERSIVE": IMMERSIVE,
+  };
+  static const List<SystemUiVisibility> values = const [
+    STANDARD,
+    FULLSCREEN,
+    IMMERSIVE,
+  ];
+
+  static SystemUiVisibility valueOf(String name) => valuesMap[name];
+
+  factory SystemUiVisibility(int v) {
+    switch (v) {
+      case 0:
+        return STANDARD;
+      case 1:
+        return FULLSCREEN;
+      case 2:
+        return IMMERSIVE;
+      default:
+        return null;
+    }
+  }
+
+  static SystemUiVisibility decode(bindings.Decoder decoder0, int offset) {
+    int v = decoder0.decodeUint32(offset);
+    SystemUiVisibility result = new SystemUiVisibility(v);
+    if (result == null) {
+      throw new bindings.MojoCodecError(
+          'Bad value $v for enum SystemUiVisibility.');
+    }
+    return result;
+  }
+
+  String toString() {
+    switch(this) {
+      case STANDARD:
+        return 'SystemUiVisibility.STANDARD';
+      case FULLSCREEN:
+        return 'SystemUiVisibility.FULLSCREEN';
+      case IMMERSIVE:
+        return 'SystemUiVisibility.IMMERSIVE';
+    }
+  }
+
+  int toJson() => value;
+}
+class ScreenOrientation extends bindings.MojoEnum {
+  static const UNSPECIFIED = const ScreenOrientation._(0);
+  static const LANDSCAPE = const ScreenOrientation._(1);
+  static const PORTRAIT = const ScreenOrientation._(2);
+  static const NOSENSOR = const ScreenOrientation._(3);
+
+  const ScreenOrientation._(int v) : super(v);
+
+  static const Map<String, ScreenOrientation> valuesMap = const {
+    "UNSPECIFIED": UNSPECIFIED,
+    "LANDSCAPE": LANDSCAPE,
+    "PORTRAIT": PORTRAIT,
+    "NOSENSOR": NOSENSOR,
+  };
+  static const List<ScreenOrientation> values = const [
+    UNSPECIFIED,
+    LANDSCAPE,
+    PORTRAIT,
+    NOSENSOR,
+  ];
+
+  static ScreenOrientation valueOf(String name) => valuesMap[name];
+
+  factory ScreenOrientation(int v) {
+    switch (v) {
+      case 0:
+        return UNSPECIFIED;
+      case 1:
+        return LANDSCAPE;
+      case 2:
+        return PORTRAIT;
+      case 3:
+        return NOSENSOR;
+      default:
+        return null;
+    }
+  }
+
+  static ScreenOrientation decode(bindings.Decoder decoder0, int offset) {
+    int v = decoder0.decodeUint32(offset);
+    ScreenOrientation result = new ScreenOrientation(v);
+    if (result == null) {
+      throw new bindings.MojoCodecError(
+          'Bad value $v for enum ScreenOrientation.');
+    }
+    return result;
+  }
+
+  String toString() {
+    switch(this) {
+      case UNSPECIFIED:
+        return 'ScreenOrientation.UNSPECIFIED';
+      case LANDSCAPE:
+        return 'ScreenOrientation.LANDSCAPE';
+      case PORTRAIT:
+        return 'ScreenOrientation.PORTRAIT';
+      case NOSENSOR:
+        return 'ScreenOrientation.NOSENSOR';
+    }
+  }
+
+  int toJson() => value;
+}
+class HapticFeedbackType extends bindings.MojoEnum {
+  static const LONG_PRESS = const HapticFeedbackType._(0);
+  static const VIRTUAL_KEY = const HapticFeedbackType._(1);
+  static const KEYBOARD_TAP = const HapticFeedbackType._(2);
+  static const CLOCK_TICK = const HapticFeedbackType._(3);
+
+  const HapticFeedbackType._(int v) : super(v);
+
+  static const Map<String, HapticFeedbackType> valuesMap = const {
+    "LONG_PRESS": LONG_PRESS,
+    "VIRTUAL_KEY": VIRTUAL_KEY,
+    "KEYBOARD_TAP": KEYBOARD_TAP,
+    "CLOCK_TICK": CLOCK_TICK,
+  };
+  static const List<HapticFeedbackType> values = const [
+    LONG_PRESS,
+    VIRTUAL_KEY,
+    KEYBOARD_TAP,
+    CLOCK_TICK,
+  ];
+
+  static HapticFeedbackType valueOf(String name) => valuesMap[name];
+
+  factory HapticFeedbackType(int v) {
+    switch (v) {
+      case 0:
+        return LONG_PRESS;
+      case 1:
+        return VIRTUAL_KEY;
+      case 2:
+        return KEYBOARD_TAP;
+      case 3:
+        return CLOCK_TICK;
+      default:
+        return null;
+    }
+  }
+
+  static HapticFeedbackType decode(bindings.Decoder decoder0, int offset) {
+    int v = decoder0.decodeUint32(offset);
+    HapticFeedbackType result = new HapticFeedbackType(v);
+    if (result == null) {
+      throw new bindings.MojoCodecError(
+          'Bad value $v for enum HapticFeedbackType.');
+    }
+    return result;
+  }
+
+  String toString() {
+    switch(this) {
+      case LONG_PRESS:
+        return 'HapticFeedbackType.LONG_PRESS';
+      case VIRTUAL_KEY:
+        return 'HapticFeedbackType.VIRTUAL_KEY';
+      case KEYBOARD_TAP:
+        return 'HapticFeedbackType.KEYBOARD_TAP';
+      case CLOCK_TICK:
+        return 'HapticFeedbackType.CLOCK_TICK';
+    }
+  }
+
+  int toJson() => value;
+}
+class AuralFeedbackType extends bindings.MojoEnum {
+  static const CLICK = const AuralFeedbackType._(0);
+  static const NAVIGATION_LEFT = const AuralFeedbackType._(1);
+  static const NAVIGATION_UP = const AuralFeedbackType._(2);
+  static const NAVIGATION_RIGHT = const AuralFeedbackType._(3);
+  static const NAVIGATION_DOWN = const AuralFeedbackType._(4);
+
+  const AuralFeedbackType._(int v) : super(v);
+
+  static const Map<String, AuralFeedbackType> valuesMap = const {
+    "CLICK": CLICK,
+    "NAVIGATION_LEFT": NAVIGATION_LEFT,
+    "NAVIGATION_UP": NAVIGATION_UP,
+    "NAVIGATION_RIGHT": NAVIGATION_RIGHT,
+    "NAVIGATION_DOWN": NAVIGATION_DOWN,
+  };
+  static const List<AuralFeedbackType> values = const [
+    CLICK,
+    NAVIGATION_LEFT,
+    NAVIGATION_UP,
+    NAVIGATION_RIGHT,
+    NAVIGATION_DOWN,
+  ];
+
+  static AuralFeedbackType valueOf(String name) => valuesMap[name];
+
+  factory AuralFeedbackType(int v) {
+    switch (v) {
+      case 0:
+        return CLICK;
+      case 1:
+        return NAVIGATION_LEFT;
+      case 2:
+        return NAVIGATION_UP;
+      case 3:
+        return NAVIGATION_RIGHT;
+      case 4:
+        return NAVIGATION_DOWN;
+      default:
+        return null;
+    }
+  }
+
+  static AuralFeedbackType decode(bindings.Decoder decoder0, int offset) {
+    int v = decoder0.decodeUint32(offset);
+    AuralFeedbackType result = new AuralFeedbackType(v);
+    if (result == null) {
+      throw new bindings.MojoCodecError(
+          'Bad value $v for enum AuralFeedbackType.');
+    }
+    return result;
+  }
+
+  String toString() {
+    switch(this) {
+      case CLICK:
+        return 'AuralFeedbackType.CLICK';
+      case NAVIGATION_LEFT:
+        return 'AuralFeedbackType.NAVIGATION_LEFT';
+      case NAVIGATION_UP:
+        return 'AuralFeedbackType.NAVIGATION_UP';
+      case NAVIGATION_RIGHT:
+        return 'AuralFeedbackType.NAVIGATION_RIGHT';
+      case NAVIGATION_DOWN:
+        return 'AuralFeedbackType.NAVIGATION_DOWN';
+    }
+  }
+
+  int toJson() => value;
+}
+
+
+
+class StringExtra extends bindings.Struct {
+  static const List<bindings.StructDataHeader> kVersions = const [
+    const bindings.StructDataHeader(24, 0)
+  ];
+  String name = null;
+  String value = null;
+
+  StringExtra() : super(kVersions.last.size);
+
+  static StringExtra deserialize(bindings.Message message) {
+    var decoder = new bindings.Decoder(message);
+    var result = decode(decoder);
+    if (decoder.excessHandles != null) {
+      decoder.excessHandles.forEach((h) => h.close());
+    }
+    return result;
+  }
+
+  static StringExtra decode(bindings.Decoder decoder0) {
+    if (decoder0 == null) {
+      return null;
+    }
+    StringExtra result = new StringExtra();
+
+    var mainDataHeader = decoder0.decodeStructDataHeader();
+    if (mainDataHeader.version <= kVersions.last.version) {
+      // Scan in reverse order to optimize for more recent versions.
+      for (int i = kVersions.length - 1; i >= 0; --i) {
+        if (mainDataHeader.version >= kVersions[i].version) {
+          if (mainDataHeader.size == kVersions[i].size) {
+            // Found a match.
+            break;
+          }
+          throw new bindings.MojoCodecError(
+              'Header size doesn\'t correspond to known version size.');
+        }
+      }
+    } else if (mainDataHeader.size < kVersions.last.size) {
+      throw new bindings.MojoCodecError(
+        'Message newer than the last known version cannot be shorter than '
+        'required by the last known version.');
+    }
+    if (mainDataHeader.version >= 0) {
+      
+      result.name = decoder0.decodeString(8, false);
+    }
+    if (mainDataHeader.version >= 0) {
+      
+      result.value = decoder0.decodeString(16, false);
+    }
+    return result;
+  }
+
+  void encode(bindings.Encoder encoder) {
+    var encoder0 = encoder.getStructEncoderAtOffset(kVersions.last);
+    
+    encoder0.encodeString(name, 8, false);
+    
+    encoder0.encodeString(value, 16, false);
+  }
+
+  String toString() {
+    return "StringExtra("
+           "name: $name" ", "
+           "value: $value" ")";
+  }
+
+  Map toJson() {
+    Map map = new Map();
+    map["name"] = name;
+    map["value"] = value;
+    return map;
+  }
+}
+
+
+class ComponentName extends bindings.Struct {
+  static const List<bindings.StructDataHeader> kVersions = const [
+    const bindings.StructDataHeader(24, 0)
+  ];
+  String packageName = null;
+  String className = null;
+
+  ComponentName() : super(kVersions.last.size);
+
+  static ComponentName deserialize(bindings.Message message) {
+    var decoder = new bindings.Decoder(message);
+    var result = decode(decoder);
+    if (decoder.excessHandles != null) {
+      decoder.excessHandles.forEach((h) => h.close());
+    }
+    return result;
+  }
+
+  static ComponentName decode(bindings.Decoder decoder0) {
+    if (decoder0 == null) {
+      return null;
+    }
+    ComponentName result = new ComponentName();
+
+    var mainDataHeader = decoder0.decodeStructDataHeader();
+    if (mainDataHeader.version <= kVersions.last.version) {
+      // Scan in reverse order to optimize for more recent versions.
+      for (int i = kVersions.length - 1; i >= 0; --i) {
+        if (mainDataHeader.version >= kVersions[i].version) {
+          if (mainDataHeader.size == kVersions[i].size) {
+            // Found a match.
+            break;
+          }
+          throw new bindings.MojoCodecError(
+              'Header size doesn\'t correspond to known version size.');
+        }
+      }
+    } else if (mainDataHeader.size < kVersions.last.size) {
+      throw new bindings.MojoCodecError(
+        'Message newer than the last known version cannot be shorter than '
+        'required by the last known version.');
+    }
+    if (mainDataHeader.version >= 0) {
+      
+      result.packageName = decoder0.decodeString(8, false);
+    }
+    if (mainDataHeader.version >= 0) {
+      
+      result.className = decoder0.decodeString(16, false);
+    }
+    return result;
+  }
+
+  void encode(bindings.Encoder encoder) {
+    var encoder0 = encoder.getStructEncoderAtOffset(kVersions.last);
+    
+    encoder0.encodeString(packageName, 8, false);
+    
+    encoder0.encodeString(className, 16, false);
+  }
+
+  String toString() {
+    return "ComponentName("
+           "packageName: $packageName" ", "
+           "className: $className" ")";
+  }
+
+  Map toJson() {
+    Map map = new Map();
+    map["packageName"] = packageName;
+    map["className"] = className;
+    return map;
+  }
+}
+
+
+class Intent extends bindings.Struct {
+  static const List<bindings.StructDataHeader> kVersions = const [
+    const bindings.StructDataHeader(56, 0)
+  ];
+  String action = null;
+  String url = null;
+  int flags = 0;
+  ComponentName component = null;
+  List<StringExtra> stringExtras = null;
+  String type = null;
+
+  Intent() : super(kVersions.last.size);
+
+  static Intent deserialize(bindings.Message message) {
+    var decoder = new bindings.Decoder(message);
+    var result = decode(decoder);
+    if (decoder.excessHandles != null) {
+      decoder.excessHandles.forEach((h) => h.close());
+    }
+    return result;
+  }
+
+  static Intent decode(bindings.Decoder decoder0) {
+    if (decoder0 == null) {
+      return null;
+    }
+    Intent result = new Intent();
+
+    var mainDataHeader = decoder0.decodeStructDataHeader();
+    if (mainDataHeader.version <= kVersions.last.version) {
+      // Scan in reverse order to optimize for more recent versions.
+      for (int i = kVersions.length - 1; i >= 0; --i) {
+        if (mainDataHeader.version >= kVersions[i].version) {
+          if (mainDataHeader.size == kVersions[i].size) {
+            // Found a match.
+            break;
+          }
+          throw new bindings.MojoCodecError(
+              'Header size doesn\'t correspond to known version size.');
+        }
+      }
+    } else if (mainDataHeader.size < kVersions.last.size) {
+      throw new bindings.MojoCodecError(
+        'Message newer than the last known version cannot be shorter than '
+        'required by the last known version.');
+    }
+    if (mainDataHeader.version >= 0) {
+      
+      result.action = decoder0.decodeString(8, false);
+    }
+    if (mainDataHeader.version >= 0) {
+      
+      result.url = decoder0.decodeString(16, false);
+    }
+    if (mainDataHeader.version >= 0) {
+      
+      result.flags = decoder0.decodeUint32(24);
+    }
+    if (mainDataHeader.version >= 0) {
+      
+      var decoder1 = decoder0.decodePointer(32, true);
+      result.component = ComponentName.decode(decoder1);
+    }
+    if (mainDataHeader.version >= 0) {
+      
+      var decoder1 = decoder0.decodePointer(40, true);
+      if (decoder1 == null) {
+        result.stringExtras = null;
+      } else {
+        var si1 = decoder1.decodeDataHeaderForPointerArray(bindings.kUnspecifiedArrayLength);
+        result.stringExtras = new List<StringExtra>(si1.numElements);
+        for (int i1 = 0; i1 < si1.numElements; ++i1) {
+          
+          var decoder2 = decoder1.decodePointer(bindings.ArrayDataHeader.kHeaderSize + bindings.kPointerSize * i1, false);
+          result.stringExtras[i1] = StringExtra.decode(decoder2);
+        }
+      }
+    }
+    if (mainDataHeader.version >= 0) {
+      
+      result.type = decoder0.decodeString(48, true);
+    }
+    return result;
+  }
+
+  void encode(bindings.Encoder encoder) {
+    var encoder0 = encoder.getStructEncoderAtOffset(kVersions.last);
+    
+    encoder0.encodeString(action, 8, false);
+    
+    encoder0.encodeString(url, 16, false);
+    
+    encoder0.encodeUint32(flags, 24);
+    
+    encoder0.encodeStruct(component, 32, true);
+    
+    if (stringExtras == null) {
+      encoder0.encodeNullPointer(40, true);
+    } else {
+      var encoder1 = encoder0.encodePointerArray(stringExtras.length, 40, bindings.kUnspecifiedArrayLength);
+      for (int i0 = 0; i0 < stringExtras.length; ++i0) {
+        
+        encoder1.encodeStruct(stringExtras[i0], bindings.ArrayDataHeader.kHeaderSize + bindings.kPointerSize * i0, false);
+      }
+    }
+    
+    encoder0.encodeString(type, 48, true);
+  }
+
+  String toString() {
+    return "Intent("
+           "action: $action" ", "
+           "url: $url" ", "
+           "flags: $flags" ", "
+           "component: $component" ", "
+           "stringExtras: $stringExtras" ", "
+           "type: $type" ")";
+  }
+
+  Map toJson() {
+    Map map = new Map();
+    map["action"] = action;
+    map["url"] = url;
+    map["flags"] = flags;
+    map["component"] = component;
+    map["stringExtras"] = stringExtras;
+    map["type"] = type;
+    return map;
+  }
+}
+
+
+class TaskDescription extends bindings.Struct {
+  static const List<bindings.StructDataHeader> kVersions = const [
+    const bindings.StructDataHeader(24, 0)
+  ];
+  String label = null;
+  int primaryColor = 0;
+
+  TaskDescription() : super(kVersions.last.size);
+
+  static TaskDescription deserialize(bindings.Message message) {
+    var decoder = new bindings.Decoder(message);
+    var result = decode(decoder);
+    if (decoder.excessHandles != null) {
+      decoder.excessHandles.forEach((h) => h.close());
+    }
+    return result;
+  }
+
+  static TaskDescription decode(bindings.Decoder decoder0) {
+    if (decoder0 == null) {
+      return null;
+    }
+    TaskDescription result = new TaskDescription();
+
+    var mainDataHeader = decoder0.decodeStructDataHeader();
+    if (mainDataHeader.version <= kVersions.last.version) {
+      // Scan in reverse order to optimize for more recent versions.
+      for (int i = kVersions.length - 1; i >= 0; --i) {
+        if (mainDataHeader.version >= kVersions[i].version) {
+          if (mainDataHeader.size == kVersions[i].size) {
+            // Found a match.
+            break;
+          }
+          throw new bindings.MojoCodecError(
+              'Header size doesn\'t correspond to known version size.');
+        }
+      }
+    } else if (mainDataHeader.size < kVersions.last.size) {
+      throw new bindings.MojoCodecError(
+        'Message newer than the last known version cannot be shorter than '
+        'required by the last known version.');
+    }
+    if (mainDataHeader.version >= 0) {
+      
+      result.label = decoder0.decodeString(8, true);
+    }
+    if (mainDataHeader.version >= 0) {
+      
+      result.primaryColor = decoder0.decodeUint32(16);
+    }
+    return result;
+  }
+
+  void encode(bindings.Encoder encoder) {
+    var encoder0 = encoder.getStructEncoderAtOffset(kVersions.last);
+    
+    encoder0.encodeString(label, 8, true);
+    
+    encoder0.encodeUint32(primaryColor, 16);
+  }
+
+  String toString() {
+    return "TaskDescription("
+           "label: $label" ", "
+           "primaryColor: $primaryColor" ")";
+  }
+
+  Map toJson() {
+    Map map = new Map();
+    map["label"] = label;
+    map["primaryColor"] = primaryColor;
+    return map;
+  }
+}
+
+
+class ActivityGetUserFeedbackParams extends bindings.Struct {
+  static const List<bindings.StructDataHeader> kVersions = const [
+    const bindings.StructDataHeader(16, 0)
+  ];
+  Object userFeedback = null;
+
+  ActivityGetUserFeedbackParams() : super(kVersions.last.size);
+
+  static ActivityGetUserFeedbackParams deserialize(bindings.Message message) {
+    var decoder = new bindings.Decoder(message);
+    var result = decode(decoder);
+    if (decoder.excessHandles != null) {
+      decoder.excessHandles.forEach((h) => h.close());
+    }
+    return result;
+  }
+
+  static ActivityGetUserFeedbackParams decode(bindings.Decoder decoder0) {
+    if (decoder0 == null) {
+      return null;
+    }
+    ActivityGetUserFeedbackParams result = new ActivityGetUserFeedbackParams();
+
+    var mainDataHeader = decoder0.decodeStructDataHeader();
+    if (mainDataHeader.version <= kVersions.last.version) {
+      // Scan in reverse order to optimize for more recent versions.
+      for (int i = kVersions.length - 1; i >= 0; --i) {
+        if (mainDataHeader.version >= kVersions[i].version) {
+          if (mainDataHeader.size == kVersions[i].size) {
+            // Found a match.
+            break;
+          }
+          throw new bindings.MojoCodecError(
+              'Header size doesn\'t correspond to known version size.');
+        }
+      }
+    } else if (mainDataHeader.size < kVersions.last.size) {
+      throw new bindings.MojoCodecError(
+        'Message newer than the last known version cannot be shorter than '
+        'required by the last known version.');
+    }
+    if (mainDataHeader.version >= 0) {
+      
+      result.userFeedback = decoder0.decodeInterfaceRequest(8, false, UserFeedbackStub.newFromEndpoint);
+    }
+    return result;
+  }
+
+  void encode(bindings.Encoder encoder) {
+    var encoder0 = encoder.getStructEncoderAtOffset(kVersions.last);
+    
+    encoder0.encodeInterfaceRequest(userFeedback, 8, false);
+  }
+
+  String toString() {
+    return "ActivityGetUserFeedbackParams("
+           "userFeedback: $userFeedback" ")";
+  }
+
+  Map toJson() {
+    throw new bindings.MojoCodecError(
+        'Object containing handles cannot be encoded to JSON.');
+  }
+}
+
+
+class ActivityStartActivityParams extends bindings.Struct {
+  static const List<bindings.StructDataHeader> kVersions = const [
+    const bindings.StructDataHeader(16, 0)
+  ];
+  Intent intent = null;
+
+  ActivityStartActivityParams() : super(kVersions.last.size);
+
+  static ActivityStartActivityParams deserialize(bindings.Message message) {
+    var decoder = new bindings.Decoder(message);
+    var result = decode(decoder);
+    if (decoder.excessHandles != null) {
+      decoder.excessHandles.forEach((h) => h.close());
+    }
+    return result;
+  }
+
+  static ActivityStartActivityParams decode(bindings.Decoder decoder0) {
+    if (decoder0 == null) {
+      return null;
+    }
+    ActivityStartActivityParams result = new ActivityStartActivityParams();
+
+    var mainDataHeader = decoder0.decodeStructDataHeader();
+    if (mainDataHeader.version <= kVersions.last.version) {
+      // Scan in reverse order to optimize for more recent versions.
+      for (int i = kVersions.length - 1; i >= 0; --i) {
+        if (mainDataHeader.version >= kVersions[i].version) {
+          if (mainDataHeader.size == kVersions[i].size) {
+            // Found a match.
+            break;
+          }
+          throw new bindings.MojoCodecError(
+              'Header size doesn\'t correspond to known version size.');
+        }
+      }
+    } else if (mainDataHeader.size < kVersions.last.size) {
+      throw new bindings.MojoCodecError(
+        'Message newer than the last known version cannot be shorter than '
+        'required by the last known version.');
+    }
+    if (mainDataHeader.version >= 0) {
+      
+      var decoder1 = decoder0.decodePointer(8, false);
+      result.intent = Intent.decode(decoder1);
+    }
+    return result;
+  }
+
+  void encode(bindings.Encoder encoder) {
+    var encoder0 = encoder.getStructEncoderAtOffset(kVersions.last);
+    
+    encoder0.encodeStruct(intent, 8, false);
+  }
+
+  String toString() {
+    return "ActivityStartActivityParams("
+           "intent: $intent" ")";
+  }
+
+  Map toJson() {
+    Map map = new Map();
+    map["intent"] = intent;
+    return map;
+  }
+}
+
+
+class ActivityFinishCurrentActivityParams extends bindings.Struct {
+  static const List<bindings.StructDataHeader> kVersions = const [
+    const bindings.StructDataHeader(8, 0)
+  ];
+
+  ActivityFinishCurrentActivityParams() : super(kVersions.last.size);
+
+  static ActivityFinishCurrentActivityParams deserialize(bindings.Message message) {
+    var decoder = new bindings.Decoder(message);
+    var result = decode(decoder);
+    if (decoder.excessHandles != null) {
+      decoder.excessHandles.forEach((h) => h.close());
+    }
+    return result;
+  }
+
+  static ActivityFinishCurrentActivityParams decode(bindings.Decoder decoder0) {
+    if (decoder0 == null) {
+      return null;
+    }
+    ActivityFinishCurrentActivityParams result = new ActivityFinishCurrentActivityParams();
+
+    var mainDataHeader = decoder0.decodeStructDataHeader();
+    if (mainDataHeader.version <= kVersions.last.version) {
+      // Scan in reverse order to optimize for more recent versions.
+      for (int i = kVersions.length - 1; i >= 0; --i) {
+        if (mainDataHeader.version >= kVersions[i].version) {
+          if (mainDataHeader.size == kVersions[i].size) {
+            // Found a match.
+            break;
+          }
+          throw new bindings.MojoCodecError(
+              'Header size doesn\'t correspond to known version size.');
+        }
+      }
+    } else if (mainDataHeader.size < kVersions.last.size) {
+      throw new bindings.MojoCodecError(
+        'Message newer than the last known version cannot be shorter than '
+        'required by the last known version.');
+    }
+    return result;
+  }
+
+  void encode(bindings.Encoder encoder) {
+    encoder.getStructEncoderAtOffset(kVersions.last);
+  }
+
+  String toString() {
+    return "ActivityFinishCurrentActivityParams("")";
+  }
+
+  Map toJson() {
+    Map map = new Map();
+    return map;
+  }
+}
+
+
+class ActivitySetTaskDescriptionParams extends bindings.Struct {
+  static const List<bindings.StructDataHeader> kVersions = const [
+    const bindings.StructDataHeader(16, 0)
+  ];
+  TaskDescription description = null;
+
+  ActivitySetTaskDescriptionParams() : super(kVersions.last.size);
+
+  static ActivitySetTaskDescriptionParams deserialize(bindings.Message message) {
+    var decoder = new bindings.Decoder(message);
+    var result = decode(decoder);
+    if (decoder.excessHandles != null) {
+      decoder.excessHandles.forEach((h) => h.close());
+    }
+    return result;
+  }
+
+  static ActivitySetTaskDescriptionParams decode(bindings.Decoder decoder0) {
+    if (decoder0 == null) {
+      return null;
+    }
+    ActivitySetTaskDescriptionParams result = new ActivitySetTaskDescriptionParams();
+
+    var mainDataHeader = decoder0.decodeStructDataHeader();
+    if (mainDataHeader.version <= kVersions.last.version) {
+      // Scan in reverse order to optimize for more recent versions.
+      for (int i = kVersions.length - 1; i >= 0; --i) {
+        if (mainDataHeader.version >= kVersions[i].version) {
+          if (mainDataHeader.size == kVersions[i].size) {
+            // Found a match.
+            break;
+          }
+          throw new bindings.MojoCodecError(
+              'Header size doesn\'t correspond to known version size.');
+        }
+      }
+    } else if (mainDataHeader.size < kVersions.last.size) {
+      throw new bindings.MojoCodecError(
+        'Message newer than the last known version cannot be shorter than '
+        'required by the last known version.');
+    }
+    if (mainDataHeader.version >= 0) {
+      
+      var decoder1 = decoder0.decodePointer(8, false);
+      result.description = TaskDescription.decode(decoder1);
+    }
+    return result;
+  }
+
+  void encode(bindings.Encoder encoder) {
+    var encoder0 = encoder.getStructEncoderAtOffset(kVersions.last);
+    
+    encoder0.encodeStruct(description, 8, false);
+  }
+
+  String toString() {
+    return "ActivitySetTaskDescriptionParams("
+           "description: $description" ")";
+  }
+
+  Map toJson() {
+    Map map = new Map();
+    map["description"] = description;
+    return map;
+  }
+}
+
+
+class ActivitySetSystemUiVisibilityParams extends bindings.Struct {
+  static const List<bindings.StructDataHeader> kVersions = const [
+    const bindings.StructDataHeader(16, 0)
+  ];
+  SystemUiVisibility visibility = null;
+
+  ActivitySetSystemUiVisibilityParams() : super(kVersions.last.size);
+
+  static ActivitySetSystemUiVisibilityParams deserialize(bindings.Message message) {
+    var decoder = new bindings.Decoder(message);
+    var result = decode(decoder);
+    if (decoder.excessHandles != null) {
+      decoder.excessHandles.forEach((h) => h.close());
+    }
+    return result;
+  }
+
+  static ActivitySetSystemUiVisibilityParams decode(bindings.Decoder decoder0) {
+    if (decoder0 == null) {
+      return null;
+    }
+    ActivitySetSystemUiVisibilityParams result = new ActivitySetSystemUiVisibilityParams();
+
+    var mainDataHeader = decoder0.decodeStructDataHeader();
+    if (mainDataHeader.version <= kVersions.last.version) {
+      // Scan in reverse order to optimize for more recent versions.
+      for (int i = kVersions.length - 1; i >= 0; --i) {
+        if (mainDataHeader.version >= kVersions[i].version) {
+          if (mainDataHeader.size == kVersions[i].size) {
+            // Found a match.
+            break;
+          }
+          throw new bindings.MojoCodecError(
+              'Header size doesn\'t correspond to known version size.');
+        }
+      }
+    } else if (mainDataHeader.size < kVersions.last.size) {
+      throw new bindings.MojoCodecError(
+        'Message newer than the last known version cannot be shorter than '
+        'required by the last known version.');
+    }
+    if (mainDataHeader.version >= 0) {
+      
+        result.visibility = SystemUiVisibility.decode(decoder0, 8);
+        if (result.visibility == null) {
+          throw new bindings.MojoCodecError(
+            'Trying to decode null union for non-nullable SystemUiVisibility.');
+        }
+    }
+    return result;
+  }
+
+  void encode(bindings.Encoder encoder) {
+    var encoder0 = encoder.getStructEncoderAtOffset(kVersions.last);
+    
+    encoder0.encodeEnum(visibility, 8);
+  }
+
+  String toString() {
+    return "ActivitySetSystemUiVisibilityParams("
+           "visibility: $visibility" ")";
+  }
+
+  Map toJson() {
+    Map map = new Map();
+    map["visibility"] = visibility;
+    return map;
+  }
+}
+
+
+class ActivitySetRequestedOrientationParams extends bindings.Struct {
+  static const List<bindings.StructDataHeader> kVersions = const [
+    const bindings.StructDataHeader(16, 0)
+  ];
+  ScreenOrientation orientation = null;
+
+  ActivitySetRequestedOrientationParams() : super(kVersions.last.size);
+
+  static ActivitySetRequestedOrientationParams deserialize(bindings.Message message) {
+    var decoder = new bindings.Decoder(message);
+    var result = decode(decoder);
+    if (decoder.excessHandles != null) {
+      decoder.excessHandles.forEach((h) => h.close());
+    }
+    return result;
+  }
+
+  static ActivitySetRequestedOrientationParams decode(bindings.Decoder decoder0) {
+    if (decoder0 == null) {
+      return null;
+    }
+    ActivitySetRequestedOrientationParams result = new ActivitySetRequestedOrientationParams();
+
+    var mainDataHeader = decoder0.decodeStructDataHeader();
+    if (mainDataHeader.version <= kVersions.last.version) {
+      // Scan in reverse order to optimize for more recent versions.
+      for (int i = kVersions.length - 1; i >= 0; --i) {
+        if (mainDataHeader.version >= kVersions[i].version) {
+          if (mainDataHeader.size == kVersions[i].size) {
+            // Found a match.
+            break;
+          }
+          throw new bindings.MojoCodecError(
+              'Header size doesn\'t correspond to known version size.');
+        }
+      }
+    } else if (mainDataHeader.size < kVersions.last.size) {
+      throw new bindings.MojoCodecError(
+        'Message newer than the last known version cannot be shorter than '
+        'required by the last known version.');
+    }
+    if (mainDataHeader.version >= 0) {
+      
+        result.orientation = ScreenOrientation.decode(decoder0, 8);
+        if (result.orientation == null) {
+          throw new bindings.MojoCodecError(
+            'Trying to decode null union for non-nullable ScreenOrientation.');
+        }
+    }
+    return result;
+  }
+
+  void encode(bindings.Encoder encoder) {
+    var encoder0 = encoder.getStructEncoderAtOffset(kVersions.last);
+    
+    encoder0.encodeEnum(orientation, 8);
+  }
+
+  String toString() {
+    return "ActivitySetRequestedOrientationParams("
+           "orientation: $orientation" ")";
+  }
+
+  Map toJson() {
+    Map map = new Map();
+    map["orientation"] = orientation;
+    return map;
+  }
+}
+
+
+class PathServiceGetAppDataDirParams extends bindings.Struct {
+  static const List<bindings.StructDataHeader> kVersions = const [
+    const bindings.StructDataHeader(8, 0)
+  ];
+
+  PathServiceGetAppDataDirParams() : super(kVersions.last.size);
+
+  static PathServiceGetAppDataDirParams deserialize(bindings.Message message) {
+    var decoder = new bindings.Decoder(message);
+    var result = decode(decoder);
+    if (decoder.excessHandles != null) {
+      decoder.excessHandles.forEach((h) => h.close());
+    }
+    return result;
+  }
+
+  static PathServiceGetAppDataDirParams decode(bindings.Decoder decoder0) {
+    if (decoder0 == null) {
+      return null;
+    }
+    PathServiceGetAppDataDirParams result = new PathServiceGetAppDataDirParams();
+
+    var mainDataHeader = decoder0.decodeStructDataHeader();
+    if (mainDataHeader.version <= kVersions.last.version) {
+      // Scan in reverse order to optimize for more recent versions.
+      for (int i = kVersions.length - 1; i >= 0; --i) {
+        if (mainDataHeader.version >= kVersions[i].version) {
+          if (mainDataHeader.size == kVersions[i].size) {
+            // Found a match.
+            break;
+          }
+          throw new bindings.MojoCodecError(
+              'Header size doesn\'t correspond to known version size.');
+        }
+      }
+    } else if (mainDataHeader.size < kVersions.last.size) {
+      throw new bindings.MojoCodecError(
+        'Message newer than the last known version cannot be shorter than '
+        'required by the last known version.');
+    }
+    return result;
+  }
+
+  void encode(bindings.Encoder encoder) {
+    encoder.getStructEncoderAtOffset(kVersions.last);
+  }
+
+  String toString() {
+    return "PathServiceGetAppDataDirParams("")";
+  }
+
+  Map toJson() {
+    Map map = new Map();
+    return map;
+  }
+}
+
+
+class PathServiceGetAppDataDirResponseParams extends bindings.Struct {
+  static const List<bindings.StructDataHeader> kVersions = const [
+    const bindings.StructDataHeader(16, 0)
+  ];
+  String path = null;
+
+  PathServiceGetAppDataDirResponseParams() : super(kVersions.last.size);
+
+  static PathServiceGetAppDataDirResponseParams deserialize(bindings.Message message) {
+    var decoder = new bindings.Decoder(message);
+    var result = decode(decoder);
+    if (decoder.excessHandles != null) {
+      decoder.excessHandles.forEach((h) => h.close());
+    }
+    return result;
+  }
+
+  static PathServiceGetAppDataDirResponseParams decode(bindings.Decoder decoder0) {
+    if (decoder0 == null) {
+      return null;
+    }
+    PathServiceGetAppDataDirResponseParams result = new PathServiceGetAppDataDirResponseParams();
+
+    var mainDataHeader = decoder0.decodeStructDataHeader();
+    if (mainDataHeader.version <= kVersions.last.version) {
+      // Scan in reverse order to optimize for more recent versions.
+      for (int i = kVersions.length - 1; i >= 0; --i) {
+        if (mainDataHeader.version >= kVersions[i].version) {
+          if (mainDataHeader.size == kVersions[i].size) {
+            // Found a match.
+            break;
+          }
+          throw new bindings.MojoCodecError(
+              'Header size doesn\'t correspond to known version size.');
+        }
+      }
+    } else if (mainDataHeader.size < kVersions.last.size) {
+      throw new bindings.MojoCodecError(
+        'Message newer than the last known version cannot be shorter than '
+        'required by the last known version.');
+    }
+    if (mainDataHeader.version >= 0) {
+      
+      result.path = decoder0.decodeString(8, false);
+    }
+    return result;
+  }
+
+  void encode(bindings.Encoder encoder) {
+    var encoder0 = encoder.getStructEncoderAtOffset(kVersions.last);
+    
+    encoder0.encodeString(path, 8, false);
+  }
+
+  String toString() {
+    return "PathServiceGetAppDataDirResponseParams("
+           "path: $path" ")";
+  }
+
+  Map toJson() {
+    Map map = new Map();
+    map["path"] = path;
+    return map;
+  }
+}
+
+
+class PathServiceGetFilesDirParams extends bindings.Struct {
+  static const List<bindings.StructDataHeader> kVersions = const [
+    const bindings.StructDataHeader(8, 0)
+  ];
+
+  PathServiceGetFilesDirParams() : super(kVersions.last.size);
+
+  static PathServiceGetFilesDirParams deserialize(bindings.Message message) {
+    var decoder = new bindings.Decoder(message);
+    var result = decode(decoder);
+    if (decoder.excessHandles != null) {
+      decoder.excessHandles.forEach((h) => h.close());
+    }
+    return result;
+  }
+
+  static PathServiceGetFilesDirParams decode(bindings.Decoder decoder0) {
+    if (decoder0 == null) {
+      return null;
+    }
+    PathServiceGetFilesDirParams result = new PathServiceGetFilesDirParams();
+
+    var mainDataHeader = decoder0.decodeStructDataHeader();
+    if (mainDataHeader.version <= kVersions.last.version) {
+      // Scan in reverse order to optimize for more recent versions.
+      for (int i = kVersions.length - 1; i >= 0; --i) {
+        if (mainDataHeader.version >= kVersions[i].version) {
+          if (mainDataHeader.size == kVersions[i].size) {
+            // Found a match.
+            break;
+          }
+          throw new bindings.MojoCodecError(
+              'Header size doesn\'t correspond to known version size.');
+        }
+      }
+    } else if (mainDataHeader.size < kVersions.last.size) {
+      throw new bindings.MojoCodecError(
+        'Message newer than the last known version cannot be shorter than '
+        'required by the last known version.');
+    }
+    return result;
+  }
+
+  void encode(bindings.Encoder encoder) {
+    encoder.getStructEncoderAtOffset(kVersions.last);
+  }
+
+  String toString() {
+    return "PathServiceGetFilesDirParams("")";
+  }
+
+  Map toJson() {
+    Map map = new Map();
+    return map;
+  }
+}
+
+
+class PathServiceGetFilesDirResponseParams extends bindings.Struct {
+  static const List<bindings.StructDataHeader> kVersions = const [
+    const bindings.StructDataHeader(16, 0)
+  ];
+  String path = null;
+
+  PathServiceGetFilesDirResponseParams() : super(kVersions.last.size);
+
+  static PathServiceGetFilesDirResponseParams deserialize(bindings.Message message) {
+    var decoder = new bindings.Decoder(message);
+    var result = decode(decoder);
+    if (decoder.excessHandles != null) {
+      decoder.excessHandles.forEach((h) => h.close());
+    }
+    return result;
+  }
+
+  static PathServiceGetFilesDirResponseParams decode(bindings.Decoder decoder0) {
+    if (decoder0 == null) {
+      return null;
+    }
+    PathServiceGetFilesDirResponseParams result = new PathServiceGetFilesDirResponseParams();
+
+    var mainDataHeader = decoder0.decodeStructDataHeader();
+    if (mainDataHeader.version <= kVersions.last.version) {
+      // Scan in reverse order to optimize for more recent versions.
+      for (int i = kVersions.length - 1; i >= 0; --i) {
+        if (mainDataHeader.version >= kVersions[i].version) {
+          if (mainDataHeader.size == kVersions[i].size) {
+            // Found a match.
+            break;
+          }
+          throw new bindings.MojoCodecError(
+              'Header size doesn\'t correspond to known version size.');
+        }
+      }
+    } else if (mainDataHeader.size < kVersions.last.size) {
+      throw new bindings.MojoCodecError(
+        'Message newer than the last known version cannot be shorter than '
+        'required by the last known version.');
+    }
+    if (mainDataHeader.version >= 0) {
+      
+      result.path = decoder0.decodeString(8, false);
+    }
+    return result;
+  }
+
+  void encode(bindings.Encoder encoder) {
+    var encoder0 = encoder.getStructEncoderAtOffset(kVersions.last);
+    
+    encoder0.encodeString(path, 8, false);
+  }
+
+  String toString() {
+    return "PathServiceGetFilesDirResponseParams("
+           "path: $path" ")";
+  }
+
+  Map toJson() {
+    Map map = new Map();
+    map["path"] = path;
+    return map;
+  }
+}
+
+
+class PathServiceGetCacheDirParams extends bindings.Struct {
+  static const List<bindings.StructDataHeader> kVersions = const [
+    const bindings.StructDataHeader(8, 0)
+  ];
+
+  PathServiceGetCacheDirParams() : super(kVersions.last.size);
+
+  static PathServiceGetCacheDirParams deserialize(bindings.Message message) {
+    var decoder = new bindings.Decoder(message);
+    var result = decode(decoder);
+    if (decoder.excessHandles != null) {
+      decoder.excessHandles.forEach((h) => h.close());
+    }
+    return result;
+  }
+
+  static PathServiceGetCacheDirParams decode(bindings.Decoder decoder0) {
+    if (decoder0 == null) {
+      return null;
+    }
+    PathServiceGetCacheDirParams result = new PathServiceGetCacheDirParams();
+
+    var mainDataHeader = decoder0.decodeStructDataHeader();
+    if (mainDataHeader.version <= kVersions.last.version) {
+      // Scan in reverse order to optimize for more recent versions.
+      for (int i = kVersions.length - 1; i >= 0; --i) {
+        if (mainDataHeader.version >= kVersions[i].version) {
+          if (mainDataHeader.size == kVersions[i].size) {
+            // Found a match.
+            break;
+          }
+          throw new bindings.MojoCodecError(
+              'Header size doesn\'t correspond to known version size.');
+        }
+      }
+    } else if (mainDataHeader.size < kVersions.last.size) {
+      throw new bindings.MojoCodecError(
+        'Message newer than the last known version cannot be shorter than '
+        'required by the last known version.');
+    }
+    return result;
+  }
+
+  void encode(bindings.Encoder encoder) {
+    encoder.getStructEncoderAtOffset(kVersions.last);
+  }
+
+  String toString() {
+    return "PathServiceGetCacheDirParams("")";
+  }
+
+  Map toJson() {
+    Map map = new Map();
+    return map;
+  }
+}
+
+
+class PathServiceGetCacheDirResponseParams extends bindings.Struct {
+  static const List<bindings.StructDataHeader> kVersions = const [
+    const bindings.StructDataHeader(16, 0)
+  ];
+  String path = null;
+
+  PathServiceGetCacheDirResponseParams() : super(kVersions.last.size);
+
+  static PathServiceGetCacheDirResponseParams deserialize(bindings.Message message) {
+    var decoder = new bindings.Decoder(message);
+    var result = decode(decoder);
+    if (decoder.excessHandles != null) {
+      decoder.excessHandles.forEach((h) => h.close());
+    }
+    return result;
+  }
+
+  static PathServiceGetCacheDirResponseParams decode(bindings.Decoder decoder0) {
+    if (decoder0 == null) {
+      return null;
+    }
+    PathServiceGetCacheDirResponseParams result = new PathServiceGetCacheDirResponseParams();
+
+    var mainDataHeader = decoder0.decodeStructDataHeader();
+    if (mainDataHeader.version <= kVersions.last.version) {
+      // Scan in reverse order to optimize for more recent versions.
+      for (int i = kVersions.length - 1; i >= 0; --i) {
+        if (mainDataHeader.version >= kVersions[i].version) {
+          if (mainDataHeader.size == kVersions[i].size) {
+            // Found a match.
+            break;
+          }
+          throw new bindings.MojoCodecError(
+              'Header size doesn\'t correspond to known version size.');
+        }
+      }
+    } else if (mainDataHeader.size < kVersions.last.size) {
+      throw new bindings.MojoCodecError(
+        'Message newer than the last known version cannot be shorter than '
+        'required by the last known version.');
+    }
+    if (mainDataHeader.version >= 0) {
+      
+      result.path = decoder0.decodeString(8, false);
+    }
+    return result;
+  }
+
+  void encode(bindings.Encoder encoder) {
+    var encoder0 = encoder.getStructEncoderAtOffset(kVersions.last);
+    
+    encoder0.encodeString(path, 8, false);
+  }
+
+  String toString() {
+    return "PathServiceGetCacheDirResponseParams("
+           "path: $path" ")";
+  }
+
+  Map toJson() {
+    Map map = new Map();
+    map["path"] = path;
+    return map;
+  }
+}
+
+
+class UserFeedbackPerformHapticFeedbackParams extends bindings.Struct {
+  static const List<bindings.StructDataHeader> kVersions = const [
+    const bindings.StructDataHeader(16, 0)
+  ];
+  HapticFeedbackType type = null;
+
+  UserFeedbackPerformHapticFeedbackParams() : super(kVersions.last.size);
+
+  static UserFeedbackPerformHapticFeedbackParams deserialize(bindings.Message message) {
+    var decoder = new bindings.Decoder(message);
+    var result = decode(decoder);
+    if (decoder.excessHandles != null) {
+      decoder.excessHandles.forEach((h) => h.close());
+    }
+    return result;
+  }
+
+  static UserFeedbackPerformHapticFeedbackParams decode(bindings.Decoder decoder0) {
+    if (decoder0 == null) {
+      return null;
+    }
+    UserFeedbackPerformHapticFeedbackParams result = new UserFeedbackPerformHapticFeedbackParams();
+
+    var mainDataHeader = decoder0.decodeStructDataHeader();
+    if (mainDataHeader.version <= kVersions.last.version) {
+      // Scan in reverse order to optimize for more recent versions.
+      for (int i = kVersions.length - 1; i >= 0; --i) {
+        if (mainDataHeader.version >= kVersions[i].version) {
+          if (mainDataHeader.size == kVersions[i].size) {
+            // Found a match.
+            break;
+          }
+          throw new bindings.MojoCodecError(
+              'Header size doesn\'t correspond to known version size.');
+        }
+      }
+    } else if (mainDataHeader.size < kVersions.last.size) {
+      throw new bindings.MojoCodecError(
+        'Message newer than the last known version cannot be shorter than '
+        'required by the last known version.');
+    }
+    if (mainDataHeader.version >= 0) {
+      
+        result.type = HapticFeedbackType.decode(decoder0, 8);
+        if (result.type == null) {
+          throw new bindings.MojoCodecError(
+            'Trying to decode null union for non-nullable HapticFeedbackType.');
+        }
+    }
+    return result;
+  }
+
+  void encode(bindings.Encoder encoder) {
+    var encoder0 = encoder.getStructEncoderAtOffset(kVersions.last);
+    
+    encoder0.encodeEnum(type, 8);
+  }
+
+  String toString() {
+    return "UserFeedbackPerformHapticFeedbackParams("
+           "type: $type" ")";
+  }
+
+  Map toJson() {
+    Map map = new Map();
+    map["type"] = type;
+    return map;
+  }
+}
+
+
+class UserFeedbackPerformAuralFeedbackParams extends bindings.Struct {
+  static const List<bindings.StructDataHeader> kVersions = const [
+    const bindings.StructDataHeader(16, 0)
+  ];
+  AuralFeedbackType type = null;
+
+  UserFeedbackPerformAuralFeedbackParams() : super(kVersions.last.size);
+
+  static UserFeedbackPerformAuralFeedbackParams deserialize(bindings.Message message) {
+    var decoder = new bindings.Decoder(message);
+    var result = decode(decoder);
+    if (decoder.excessHandles != null) {
+      decoder.excessHandles.forEach((h) => h.close());
+    }
+    return result;
+  }
+
+  static UserFeedbackPerformAuralFeedbackParams decode(bindings.Decoder decoder0) {
+    if (decoder0 == null) {
+      return null;
+    }
+    UserFeedbackPerformAuralFeedbackParams result = new UserFeedbackPerformAuralFeedbackParams();
+
+    var mainDataHeader = decoder0.decodeStructDataHeader();
+    if (mainDataHeader.version <= kVersions.last.version) {
+      // Scan in reverse order to optimize for more recent versions.
+      for (int i = kVersions.length - 1; i >= 0; --i) {
+        if (mainDataHeader.version >= kVersions[i].version) {
+          if (mainDataHeader.size == kVersions[i].size) {
+            // Found a match.
+            break;
+          }
+          throw new bindings.MojoCodecError(
+              'Header size doesn\'t correspond to known version size.');
+        }
+      }
+    } else if (mainDataHeader.size < kVersions.last.size) {
+      throw new bindings.MojoCodecError(
+        'Message newer than the last known version cannot be shorter than '
+        'required by the last known version.');
+    }
+    if (mainDataHeader.version >= 0) {
+      
+        result.type = AuralFeedbackType.decode(decoder0, 8);
+        if (result.type == null) {
+          throw new bindings.MojoCodecError(
+            'Trying to decode null union for non-nullable AuralFeedbackType.');
+        }
+    }
+    return result;
+  }
+
+  void encode(bindings.Encoder encoder) {
+    var encoder0 = encoder.getStructEncoderAtOffset(kVersions.last);
+    
+    encoder0.encodeEnum(type, 8);
+  }
+
+  String toString() {
+    return "UserFeedbackPerformAuralFeedbackParams("
+           "type: $type" ")";
+  }
+
+  Map toJson() {
+    Map map = new Map();
+    map["type"] = type;
+    return map;
+  }
+}
+
+const int kActivity_getUserFeedback_name = 0;
+const int kActivity_startActivity_name = 1;
+const int kActivity_finishCurrentActivity_name = 2;
+const int kActivity_setTaskDescription_name = 3;
+const int kActivity_setSystemUiVisibility_name = 4;
+const int kActivity_setRequestedOrientation_name = 5;
+
+const String ActivityName =
+      'activity::Activity';
+
+abstract class Activity {
+  void getUserFeedback(Object userFeedback);
+  void startActivity(Intent intent);
+  void finishCurrentActivity();
+  void setTaskDescription(TaskDescription description);
+  void setSystemUiVisibility(SystemUiVisibility visibility);
+  void setRequestedOrientation(ScreenOrientation orientation);
+
+}
+
+
+class ActivityProxyImpl extends bindings.Proxy {
+  ActivityProxyImpl.fromEndpoint(
+      core.MojoMessagePipeEndpoint endpoint) : super.fromEndpoint(endpoint);
+
+  ActivityProxyImpl.fromHandle(core.MojoHandle handle) :
+      super.fromHandle(handle);
+
+  ActivityProxyImpl.unbound() : super.unbound();
+
+  static ActivityProxyImpl newFromEndpoint(
+      core.MojoMessagePipeEndpoint endpoint) {
+    assert(endpoint.setDescription("For ActivityProxyImpl"));
+    return new ActivityProxyImpl.fromEndpoint(endpoint);
+  }
+
+  String get name => ActivityName;
+
+  void handleResponse(bindings.ServiceMessage message) {
+    switch (message.header.type) {
+      default:
+        proxyError("Unexpected message type: ${message.header.type}");
+        close(immediate: true);
+        break;
+    }
+  }
+
+  String toString() {
+    var superString = super.toString();
+    return "ActivityProxyImpl($superString)";
+  }
+}
+
+
+class _ActivityProxyCalls implements Activity {
+  ActivityProxyImpl _proxyImpl;
+
+  _ActivityProxyCalls(this._proxyImpl);
+    void getUserFeedback(Object userFeedback) {
+      if (!_proxyImpl.isBound) {
+        _proxyImpl.proxyError("The Proxy is closed.");
+        return;
+      }
+      var params = new ActivityGetUserFeedbackParams();
+      params.userFeedback = userFeedback;
+      _proxyImpl.sendMessage(params, kActivity_getUserFeedback_name);
+    }
+  
+    void startActivity(Intent intent) {
+      if (!_proxyImpl.isBound) {
+        _proxyImpl.proxyError("The Proxy is closed.");
+        return;
+      }
+      var params = new ActivityStartActivityParams();
+      params.intent = intent;
+      _proxyImpl.sendMessage(params, kActivity_startActivity_name);
+    }
+  
+    void finishCurrentActivity() {
+      if (!_proxyImpl.isBound) {
+        _proxyImpl.proxyError("The Proxy is closed.");
+        return;
+      }
+      var params = new ActivityFinishCurrentActivityParams();
+      _proxyImpl.sendMessage(params, kActivity_finishCurrentActivity_name);
+    }
+  
+    void setTaskDescription(TaskDescription description) {
+      if (!_proxyImpl.isBound) {
+        _proxyImpl.proxyError("The Proxy is closed.");
+        return;
+      }
+      var params = new ActivitySetTaskDescriptionParams();
+      params.description = description;
+      _proxyImpl.sendMessage(params, kActivity_setTaskDescription_name);
+    }
+  
+    void setSystemUiVisibility(SystemUiVisibility visibility) {
+      if (!_proxyImpl.isBound) {
+        _proxyImpl.proxyError("The Proxy is closed.");
+        return;
+      }
+      var params = new ActivitySetSystemUiVisibilityParams();
+      params.visibility = visibility;
+      _proxyImpl.sendMessage(params, kActivity_setSystemUiVisibility_name);
+    }
+  
+    void setRequestedOrientation(ScreenOrientation orientation) {
+      if (!_proxyImpl.isBound) {
+        _proxyImpl.proxyError("The Proxy is closed.");
+        return;
+      }
+      var params = new ActivitySetRequestedOrientationParams();
+      params.orientation = orientation;
+      _proxyImpl.sendMessage(params, kActivity_setRequestedOrientation_name);
+    }
+  
+}
+
+
+class ActivityProxy implements bindings.ProxyBase {
+  final bindings.Proxy impl;
+  Activity ptr;
+  final String name = ActivityName;
+
+  ActivityProxy(ActivityProxyImpl proxyImpl) :
+      impl = proxyImpl,
+      ptr = new _ActivityProxyCalls(proxyImpl);
+
+  ActivityProxy.fromEndpoint(
+      core.MojoMessagePipeEndpoint endpoint) :
+      impl = new ActivityProxyImpl.fromEndpoint(endpoint) {
+    ptr = new _ActivityProxyCalls(impl);
+  }
+
+  ActivityProxy.fromHandle(core.MojoHandle handle) :
+      impl = new ActivityProxyImpl.fromHandle(handle) {
+    ptr = new _ActivityProxyCalls(impl);
+  }
+
+  ActivityProxy.unbound() :
+      impl = new ActivityProxyImpl.unbound() {
+    ptr = new _ActivityProxyCalls(impl);
+  }
+
+  factory ActivityProxy.connectToService(
+      bindings.ServiceConnector s, String url) {
+    ActivityProxy p = new ActivityProxy.unbound();
+    s.connectToService(url, p);
+    return p;
+  }
+
+  static ActivityProxy newFromEndpoint(
+      core.MojoMessagePipeEndpoint endpoint) {
+    assert(endpoint.setDescription("For ActivityProxy"));
+    return new ActivityProxy.fromEndpoint(endpoint);
+  }
+
+  Future close({bool immediate: false}) => impl.close(immediate: immediate);
+
+  Future responseOrError(Future f) => impl.responseOrError(f);
+
+  Future get errorFuture => impl.errorFuture;
+
+  int get version => impl.version;
+
+  Future<int> queryVersion() => impl.queryVersion();
+
+  void requireVersion(int requiredVersion) {
+    impl.requireVersion(requiredVersion);
+  }
+
+  String toString() {
+    return "ActivityProxy($impl)";
+  }
+}
+
+
+class ActivityStub extends bindings.Stub {
+  Activity _impl = null;
+
+  ActivityStub.fromEndpoint(
+      core.MojoMessagePipeEndpoint endpoint, [this._impl])
+      : super.fromEndpoint(endpoint);
+
+  ActivityStub.fromHandle(core.MojoHandle handle, [this._impl])
+      : super.fromHandle(handle);
+
+  ActivityStub.unbound() : super.unbound();
+
+  static ActivityStub newFromEndpoint(
+      core.MojoMessagePipeEndpoint endpoint) {
+    assert(endpoint.setDescription("For ActivityStub"));
+    return new ActivityStub.fromEndpoint(endpoint);
+  }
+
+  static const String name = ActivityName;
+
+
+
+  dynamic handleMessage(bindings.ServiceMessage message) {
+    if (bindings.ControlMessageHandler.isControlMessage(message)) {
+      return bindings.ControlMessageHandler.handleMessage(this,
+                                                          0,
+                                                          message);
+    }
+    assert(_impl != null);
+    switch (message.header.type) {
+      case kActivity_getUserFeedback_name:
+        var params = ActivityGetUserFeedbackParams.deserialize(
+            message.payload);
+        _impl.getUserFeedback(params.userFeedback);
+        break;
+      case kActivity_startActivity_name:
+        var params = ActivityStartActivityParams.deserialize(
+            message.payload);
+        _impl.startActivity(params.intent);
+        break;
+      case kActivity_finishCurrentActivity_name:
+        var params = ActivityFinishCurrentActivityParams.deserialize(
+            message.payload);
+        _impl.finishCurrentActivity();
+        break;
+      case kActivity_setTaskDescription_name:
+        var params = ActivitySetTaskDescriptionParams.deserialize(
+            message.payload);
+        _impl.setTaskDescription(params.description);
+        break;
+      case kActivity_setSystemUiVisibility_name:
+        var params = ActivitySetSystemUiVisibilityParams.deserialize(
+            message.payload);
+        _impl.setSystemUiVisibility(params.visibility);
+        break;
+      case kActivity_setRequestedOrientation_name:
+        var params = ActivitySetRequestedOrientationParams.deserialize(
+            message.payload);
+        _impl.setRequestedOrientation(params.orientation);
+        break;
+      default:
+        throw new bindings.MojoCodecError("Unexpected message name");
+        break;
+    }
+    return null;
+  }
+
+  Activity get impl => _impl;
+  set impl(Activity d) {
+    assert(_impl == null);
+    _impl = d;
+  }
+
+  String toString() {
+    var superString = super.toString();
+    return "ActivityStub($superString)";
+  }
+
+  int get version => 0;
+}
+
+const int kPathService_getAppDataDir_name = 0;
+const int kPathService_getFilesDir_name = 1;
+const int kPathService_getCacheDir_name = 2;
+
+const String PathServiceName =
+      'activity::PathService';
+
+abstract class PathService {
+  dynamic getAppDataDir([Function responseFactory = null]);
+  dynamic getFilesDir([Function responseFactory = null]);
+  dynamic getCacheDir([Function responseFactory = null]);
+
+}
+
+
+class PathServiceProxyImpl extends bindings.Proxy {
+  PathServiceProxyImpl.fromEndpoint(
+      core.MojoMessagePipeEndpoint endpoint) : super.fromEndpoint(endpoint);
+
+  PathServiceProxyImpl.fromHandle(core.MojoHandle handle) :
+      super.fromHandle(handle);
+
+  PathServiceProxyImpl.unbound() : super.unbound();
+
+  static PathServiceProxyImpl newFromEndpoint(
+      core.MojoMessagePipeEndpoint endpoint) {
+    assert(endpoint.setDescription("For PathServiceProxyImpl"));
+    return new PathServiceProxyImpl.fromEndpoint(endpoint);
+  }
+
+  String get name => PathServiceName;
+
+  void handleResponse(bindings.ServiceMessage message) {
+    switch (message.header.type) {
+      case kPathService_getAppDataDir_name:
+        var r = PathServiceGetAppDataDirResponseParams.deserialize(
+            message.payload);
+        if (!message.header.hasRequestId) {
+          proxyError("Expected a message with a valid request Id.");
+          return;
+        }
+        Completer c = completerMap[message.header.requestId];
+        if (c == null) {
+          proxyError(
+              "Message had unknown request Id: ${message.header.requestId}");
+          return;
+        }
+        completerMap.remove(message.header.requestId);
+        if (c.isCompleted) {
+          proxyError("Response completer already completed");
+          return;
+        }
+        c.complete(r);
+        break;
+      case kPathService_getFilesDir_name:
+        var r = PathServiceGetFilesDirResponseParams.deserialize(
+            message.payload);
+        if (!message.header.hasRequestId) {
+          proxyError("Expected a message with a valid request Id.");
+          return;
+        }
+        Completer c = completerMap[message.header.requestId];
+        if (c == null) {
+          proxyError(
+              "Message had unknown request Id: ${message.header.requestId}");
+          return;
+        }
+        completerMap.remove(message.header.requestId);
+        if (c.isCompleted) {
+          proxyError("Response completer already completed");
+          return;
+        }
+        c.complete(r);
+        break;
+      case kPathService_getCacheDir_name:
+        var r = PathServiceGetCacheDirResponseParams.deserialize(
+            message.payload);
+        if (!message.header.hasRequestId) {
+          proxyError("Expected a message with a valid request Id.");
+          return;
+        }
+        Completer c = completerMap[message.header.requestId];
+        if (c == null) {
+          proxyError(
+              "Message had unknown request Id: ${message.header.requestId}");
+          return;
+        }
+        completerMap.remove(message.header.requestId);
+        if (c.isCompleted) {
+          proxyError("Response completer already completed");
+          return;
+        }
+        c.complete(r);
+        break;
+      default:
+        proxyError("Unexpected message type: ${message.header.type}");
+        close(immediate: true);
+        break;
+    }
+  }
+
+  String toString() {
+    var superString = super.toString();
+    return "PathServiceProxyImpl($superString)";
+  }
+}
+
+
+class _PathServiceProxyCalls implements PathService {
+  PathServiceProxyImpl _proxyImpl;
+
+  _PathServiceProxyCalls(this._proxyImpl);
+    dynamic getAppDataDir([Function responseFactory = null]) {
+      var params = new PathServiceGetAppDataDirParams();
+      return _proxyImpl.sendMessageWithRequestId(
+          params,
+          kPathService_getAppDataDir_name,
+          -1,
+          bindings.MessageHeader.kMessageExpectsResponse);
+    }
+    dynamic getFilesDir([Function responseFactory = null]) {
+      var params = new PathServiceGetFilesDirParams();
+      return _proxyImpl.sendMessageWithRequestId(
+          params,
+          kPathService_getFilesDir_name,
+          -1,
+          bindings.MessageHeader.kMessageExpectsResponse);
+    }
+    dynamic getCacheDir([Function responseFactory = null]) {
+      var params = new PathServiceGetCacheDirParams();
+      return _proxyImpl.sendMessageWithRequestId(
+          params,
+          kPathService_getCacheDir_name,
+          -1,
+          bindings.MessageHeader.kMessageExpectsResponse);
+    }
+}
+
+
+class PathServiceProxy implements bindings.ProxyBase {
+  final bindings.Proxy impl;
+  PathService ptr;
+  final String name = PathServiceName;
+
+  PathServiceProxy(PathServiceProxyImpl proxyImpl) :
+      impl = proxyImpl,
+      ptr = new _PathServiceProxyCalls(proxyImpl);
+
+  PathServiceProxy.fromEndpoint(
+      core.MojoMessagePipeEndpoint endpoint) :
+      impl = new PathServiceProxyImpl.fromEndpoint(endpoint) {
+    ptr = new _PathServiceProxyCalls(impl);
+  }
+
+  PathServiceProxy.fromHandle(core.MojoHandle handle) :
+      impl = new PathServiceProxyImpl.fromHandle(handle) {
+    ptr = new _PathServiceProxyCalls(impl);
+  }
+
+  PathServiceProxy.unbound() :
+      impl = new PathServiceProxyImpl.unbound() {
+    ptr = new _PathServiceProxyCalls(impl);
+  }
+
+  factory PathServiceProxy.connectToService(
+      bindings.ServiceConnector s, String url) {
+    PathServiceProxy p = new PathServiceProxy.unbound();
+    s.connectToService(url, p);
+    return p;
+  }
+
+  static PathServiceProxy newFromEndpoint(
+      core.MojoMessagePipeEndpoint endpoint) {
+    assert(endpoint.setDescription("For PathServiceProxy"));
+    return new PathServiceProxy.fromEndpoint(endpoint);
+  }
+
+  Future close({bool immediate: false}) => impl.close(immediate: immediate);
+
+  Future responseOrError(Future f) => impl.responseOrError(f);
+
+  Future get errorFuture => impl.errorFuture;
+
+  int get version => impl.version;
+
+  Future<int> queryVersion() => impl.queryVersion();
+
+  void requireVersion(int requiredVersion) {
+    impl.requireVersion(requiredVersion);
+  }
+
+  String toString() {
+    return "PathServiceProxy($impl)";
+  }
+}
+
+
+class PathServiceStub extends bindings.Stub {
+  PathService _impl = null;
+
+  PathServiceStub.fromEndpoint(
+      core.MojoMessagePipeEndpoint endpoint, [this._impl])
+      : super.fromEndpoint(endpoint);
+
+  PathServiceStub.fromHandle(core.MojoHandle handle, [this._impl])
+      : super.fromHandle(handle);
+
+  PathServiceStub.unbound() : super.unbound();
+
+  static PathServiceStub newFromEndpoint(
+      core.MojoMessagePipeEndpoint endpoint) {
+    assert(endpoint.setDescription("For PathServiceStub"));
+    return new PathServiceStub.fromEndpoint(endpoint);
+  }
+
+  static const String name = PathServiceName;
+
+
+  PathServiceGetAppDataDirResponseParams _PathServiceGetAppDataDirResponseParamsFactory(String path) {
+    var mojo_factory_result = new PathServiceGetAppDataDirResponseParams();
+    mojo_factory_result.path = path;
+    return mojo_factory_result;
+  }
+  PathServiceGetFilesDirResponseParams _PathServiceGetFilesDirResponseParamsFactory(String path) {
+    var mojo_factory_result = new PathServiceGetFilesDirResponseParams();
+    mojo_factory_result.path = path;
+    return mojo_factory_result;
+  }
+  PathServiceGetCacheDirResponseParams _PathServiceGetCacheDirResponseParamsFactory(String path) {
+    var mojo_factory_result = new PathServiceGetCacheDirResponseParams();
+    mojo_factory_result.path = path;
+    return mojo_factory_result;
+  }
+
+  dynamic handleMessage(bindings.ServiceMessage message) {
+    if (bindings.ControlMessageHandler.isControlMessage(message)) {
+      return bindings.ControlMessageHandler.handleMessage(this,
+                                                          0,
+                                                          message);
+    }
+    assert(_impl != null);
+    switch (message.header.type) {
+      case kPathService_getAppDataDir_name:
+        var params = PathServiceGetAppDataDirParams.deserialize(
+            message.payload);
+        var response = _impl.getAppDataDir(_PathServiceGetAppDataDirResponseParamsFactory);
+        if (response is Future) {
+          return response.then((response) {
+            if (response != null) {
+              return buildResponseWithId(
+                  response,
+                  kPathService_getAppDataDir_name,
+                  message.header.requestId,
+                  bindings.MessageHeader.kMessageIsResponse);
+            }
+          });
+        } else if (response != null) {
+          return buildResponseWithId(
+              response,
+              kPathService_getAppDataDir_name,
+              message.header.requestId,
+              bindings.MessageHeader.kMessageIsResponse);
+        }
+        break;
+      case kPathService_getFilesDir_name:
+        var params = PathServiceGetFilesDirParams.deserialize(
+            message.payload);
+        var response = _impl.getFilesDir(_PathServiceGetFilesDirResponseParamsFactory);
+        if (response is Future) {
+          return response.then((response) {
+            if (response != null) {
+              return buildResponseWithId(
+                  response,
+                  kPathService_getFilesDir_name,
+                  message.header.requestId,
+                  bindings.MessageHeader.kMessageIsResponse);
+            }
+          });
+        } else if (response != null) {
+          return buildResponseWithId(
+              response,
+              kPathService_getFilesDir_name,
+              message.header.requestId,
+              bindings.MessageHeader.kMessageIsResponse);
+        }
+        break;
+      case kPathService_getCacheDir_name:
+        var params = PathServiceGetCacheDirParams.deserialize(
+            message.payload);
+        var response = _impl.getCacheDir(_PathServiceGetCacheDirResponseParamsFactory);
+        if (response is Future) {
+          return response.then((response) {
+            if (response != null) {
+              return buildResponseWithId(
+                  response,
+                  kPathService_getCacheDir_name,
+                  message.header.requestId,
+                  bindings.MessageHeader.kMessageIsResponse);
+            }
+          });
+        } else if (response != null) {
+          return buildResponseWithId(
+              response,
+              kPathService_getCacheDir_name,
+              message.header.requestId,
+              bindings.MessageHeader.kMessageIsResponse);
+        }
+        break;
+      default:
+        throw new bindings.MojoCodecError("Unexpected message name");
+        break;
+    }
+    return null;
+  }
+
+  PathService get impl => _impl;
+  set impl(PathService d) {
+    assert(_impl == null);
+    _impl = d;
+  }
+
+  String toString() {
+    var superString = super.toString();
+    return "PathServiceStub($superString)";
+  }
+
+  int get version => 0;
+}
+
+const int kUserFeedback_performHapticFeedback_name = 0;
+const int kUserFeedback_performAuralFeedback_name = 1;
+
+const String UserFeedbackName =
+      'activity::UserFeedback';
+
+abstract class UserFeedback {
+  void performHapticFeedback(HapticFeedbackType type);
+  void performAuralFeedback(AuralFeedbackType type);
+
+}
+
+
+class UserFeedbackProxyImpl extends bindings.Proxy {
+  UserFeedbackProxyImpl.fromEndpoint(
+      core.MojoMessagePipeEndpoint endpoint) : super.fromEndpoint(endpoint);
+
+  UserFeedbackProxyImpl.fromHandle(core.MojoHandle handle) :
+      super.fromHandle(handle);
+
+  UserFeedbackProxyImpl.unbound() : super.unbound();
+
+  static UserFeedbackProxyImpl newFromEndpoint(
+      core.MojoMessagePipeEndpoint endpoint) {
+    assert(endpoint.setDescription("For UserFeedbackProxyImpl"));
+    return new UserFeedbackProxyImpl.fromEndpoint(endpoint);
+  }
+
+  String get name => UserFeedbackName;
+
+  void handleResponse(bindings.ServiceMessage message) {
+    switch (message.header.type) {
+      default:
+        proxyError("Unexpected message type: ${message.header.type}");
+        close(immediate: true);
+        break;
+    }
+  }
+
+  String toString() {
+    var superString = super.toString();
+    return "UserFeedbackProxyImpl($superString)";
+  }
+}
+
+
+class _UserFeedbackProxyCalls implements UserFeedback {
+  UserFeedbackProxyImpl _proxyImpl;
+
+  _UserFeedbackProxyCalls(this._proxyImpl);
+    void performHapticFeedback(HapticFeedbackType type) {
+      if (!_proxyImpl.isBound) {
+        _proxyImpl.proxyError("The Proxy is closed.");
+        return;
+      }
+      var params = new UserFeedbackPerformHapticFeedbackParams();
+      params.type = type;
+      _proxyImpl.sendMessage(params, kUserFeedback_performHapticFeedback_name);
+    }
+  
+    void performAuralFeedback(AuralFeedbackType type) {
+      if (!_proxyImpl.isBound) {
+        _proxyImpl.proxyError("The Proxy is closed.");
+        return;
+      }
+      var params = new UserFeedbackPerformAuralFeedbackParams();
+      params.type = type;
+      _proxyImpl.sendMessage(params, kUserFeedback_performAuralFeedback_name);
+    }
+  
+}
+
+
+class UserFeedbackProxy implements bindings.ProxyBase {
+  final bindings.Proxy impl;
+  UserFeedback ptr;
+  final String name = UserFeedbackName;
+
+  UserFeedbackProxy(UserFeedbackProxyImpl proxyImpl) :
+      impl = proxyImpl,
+      ptr = new _UserFeedbackProxyCalls(proxyImpl);
+
+  UserFeedbackProxy.fromEndpoint(
+      core.MojoMessagePipeEndpoint endpoint) :
+      impl = new UserFeedbackProxyImpl.fromEndpoint(endpoint) {
+    ptr = new _UserFeedbackProxyCalls(impl);
+  }
+
+  UserFeedbackProxy.fromHandle(core.MojoHandle handle) :
+      impl = new UserFeedbackProxyImpl.fromHandle(handle) {
+    ptr = new _UserFeedbackProxyCalls(impl);
+  }
+
+  UserFeedbackProxy.unbound() :
+      impl = new UserFeedbackProxyImpl.unbound() {
+    ptr = new _UserFeedbackProxyCalls(impl);
+  }
+
+  factory UserFeedbackProxy.connectToService(
+      bindings.ServiceConnector s, String url) {
+    UserFeedbackProxy p = new UserFeedbackProxy.unbound();
+    s.connectToService(url, p);
+    return p;
+  }
+
+  static UserFeedbackProxy newFromEndpoint(
+      core.MojoMessagePipeEndpoint endpoint) {
+    assert(endpoint.setDescription("For UserFeedbackProxy"));
+    return new UserFeedbackProxy.fromEndpoint(endpoint);
+  }
+
+  Future close({bool immediate: false}) => impl.close(immediate: immediate);
+
+  Future responseOrError(Future f) => impl.responseOrError(f);
+
+  Future get errorFuture => impl.errorFuture;
+
+  int get version => impl.version;
+
+  Future<int> queryVersion() => impl.queryVersion();
+
+  void requireVersion(int requiredVersion) {
+    impl.requireVersion(requiredVersion);
+  }
+
+  String toString() {
+    return "UserFeedbackProxy($impl)";
+  }
+}
+
+
+class UserFeedbackStub extends bindings.Stub {
+  UserFeedback _impl = null;
+
+  UserFeedbackStub.fromEndpoint(
+      core.MojoMessagePipeEndpoint endpoint, [this._impl])
+      : super.fromEndpoint(endpoint);
+
+  UserFeedbackStub.fromHandle(core.MojoHandle handle, [this._impl])
+      : super.fromHandle(handle);
+
+  UserFeedbackStub.unbound() : super.unbound();
+
+  static UserFeedbackStub newFromEndpoint(
+      core.MojoMessagePipeEndpoint endpoint) {
+    assert(endpoint.setDescription("For UserFeedbackStub"));
+    return new UserFeedbackStub.fromEndpoint(endpoint);
+  }
+
+  static const String name = UserFeedbackName;
+
+
+
+  dynamic handleMessage(bindings.ServiceMessage message) {
+    if (bindings.ControlMessageHandler.isControlMessage(message)) {
+      return bindings.ControlMessageHandler.handleMessage(this,
+                                                          0,
+                                                          message);
+    }
+    assert(_impl != null);
+    switch (message.header.type) {
+      case kUserFeedback_performHapticFeedback_name:
+        var params = UserFeedbackPerformHapticFeedbackParams.deserialize(
+            message.payload);
+        _impl.performHapticFeedback(params.type);
+        break;
+      case kUserFeedback_performAuralFeedback_name:
+        var params = UserFeedbackPerformAuralFeedbackParams.deserialize(
+            message.payload);
+        _impl.performAuralFeedback(params.type);
+        break;
+      default:
+        throw new bindings.MojoCodecError("Unexpected message name");
+        break;
+    }
+    return null;
+  }
+
+  UserFeedback get impl => _impl;
+  set impl(UserFeedback d) {
+    assert(_impl == null);
+    _impl = d;
+  }
+
+  String toString() {
+    var superString = super.toString();
+    return "UserFeedbackStub($superString)";
+  }
+
+  int get version => 0;
+}
+
+
diff --git a/mojo/services/android/interfaces/BUILD.gn b/mojo/services/android/interfaces/BUILD.gn
new file mode 100644
index 0000000..ea84063
--- /dev/null
+++ b/mojo/services/android/interfaces/BUILD.gn
@@ -0,0 +1,12 @@
+# 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.
+
+import("//build/module_args/mojo.gni")
+import("$mojo_sdk_root/mojo/public/tools/bindings/mojom.gni")
+
+mojom("interfaces") {
+  sources = [
+    "activity.mojom",
+  ]
+}
diff --git a/mojo/services/android/interfaces/activity.mojom b/mojo/services/android/interfaces/activity.mojom
new file mode 100644
index 0000000..370cfe0
--- /dev/null
+++ b/mojo/services/android/interfaces/activity.mojom
@@ -0,0 +1,93 @@
+// 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.
+
+// This file has been imported from
+// https://github.com/flutter/engine/blob/master/sky/services/activity/activity.mojom
+[DartPackage="mojo_services"]
+module activity;
+
+struct StringExtra {
+  string name;
+  string value;
+};
+
+struct ComponentName {
+  string package_name;
+  string class_name;
+};
+
+struct Intent {
+  string action;
+  string url;
+  uint32 flags;
+  ComponentName? component;
+  array<StringExtra>? string_extras;
+  string? type;
+};
+
+struct TaskDescription {
+  string? label;
+  uint32 primaryColor;
+};
+
+enum SystemUIVisibility {
+  STANDARD,
+  FULLSCREEN,
+  IMMERSIVE,
+};
+
+// See http://developer.android.com/intl/es/reference/android/R.attr.html#screenOrientation
+enum ScreenOrientation {
+  UNSPECIFIED,
+  LANDSCAPE,
+  PORTRAIT,
+  NOSENSOR,
+};
+
+// TODO(abarth): This interface seems very specific to Android. Do we want to
+//               have a higher-level abstraction here? Do we want a collection
+//               of services that only work on specific platforms? We need to
+//               figure out how to rationalize this interface across platforms.
+[ServiceName="activity::Activity"]
+interface Activity {
+  GetUserFeedback(UserFeedback& user_feedback);
+
+  StartActivity(Intent intent);
+  FinishCurrentActivity();
+  SetTaskDescription(TaskDescription description);
+  SetSystemUIVisibility(SystemUIVisibility visibility);
+  SetRequestedOrientation(ScreenOrientation orientation);
+};
+
+[ServiceName="activity::PathService"]
+interface PathService {
+  // Where the application files are.
+  GetAppDataDir() => (string path);
+
+  // Where to store long-term files.
+  GetFilesDir() => (string path);
+
+  // Where to store short-term files.
+  GetCacheDir() => (string path);
+};
+
+enum HapticFeedbackType {
+  LONG_PRESS,
+  VIRTUAL_KEY,
+  KEYBOARD_TAP,
+  CLOCK_TICK,
+};
+
+enum AuralFeedbackType {
+  CLICK,
+  NAVIGATION_LEFT,
+  NAVIGATION_UP,
+  NAVIGATION_RIGHT,
+  NAVIGATION_DOWN,
+};
+
+interface UserFeedback {
+  PerformHapticFeedback(HapticFeedbackType type);
+  PerformAuralFeedback(AuralFeedbackType type);
+};
diff --git a/mojo/services/mojo_services.gni b/mojo/services/mojo_services.gni
index 3b6d8f9..2ec90e7 100644
--- a/mojo/services/mojo_services.gni
+++ b/mojo/services/mojo_services.gni
@@ -8,6 +8,7 @@
 # //mojo/services/X/public/interfaces to this list.
 
 mojo_services = [
+  "//mojo/services/android/interfaces",
   "//mojo/services/asset_bundle/interfaces",
   "//mojo/services/authenticating_url_loader_interceptor/interfaces",
   "//mojo/services/authentication/interfaces",
diff --git a/services/android/BUILD.gn b/services/android/BUILD.gn
new file mode 100644
index 0000000..453db8a
--- /dev/null
+++ b/services/android/BUILD.gn
@@ -0,0 +1,17 @@
+# 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.
+
+import("//build/config/android/config.gni")
+import("//build/config/android/rules.gni")
+
+# Application regrouping all android specific services.
+android_library("android") {
+  java_files = [ "src/org/chromium/mojo/android/ActivityImpl.java" ]
+
+  deps = [
+    "//mojo/public/java:bindings",
+    "//mojo/public/java:system",
+    "//mojo/services/android/interfaces:interfaces_java",
+  ]
+}
diff --git a/services/android/src/org/chromium/mojo/android/ActivityImpl.java b/services/android/src/org/chromium/mojo/android/ActivityImpl.java
new file mode 100644
index 0000000..961c7dd
--- /dev/null
+++ b/services/android/src/org/chromium/mojo/android/ActivityImpl.java
@@ -0,0 +1,283 @@
+// 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.
+
+package org.chromium.mojo.android;
+
+import android.app.Application.ActivityLifecycleCallbacks;
+import android.content.ActivityNotFoundException;
+import android.content.pm.ActivityInfo;
+import android.net.Uri;
+import android.os.Build;
+import android.os.Bundle;
+import android.util.Log;
+import android.view.HapticFeedbackConstants;
+import android.view.SoundEffectConstants;
+import android.view.View;
+
+import org.chromium.mojo.bindings.InterfaceRequest;
+import org.chromium.mojo.system.MojoException;
+import org.chromium.mojom.activity.Activity;
+import org.chromium.mojom.activity.AuralFeedbackType;
+import org.chromium.mojom.activity.ComponentName;
+import org.chromium.mojom.activity.HapticFeedbackType;
+import org.chromium.mojom.activity.Intent;
+import org.chromium.mojom.activity.ScreenOrientation;
+import org.chromium.mojom.activity.StringExtra;
+import org.chromium.mojom.activity.SystemUiVisibility;
+import org.chromium.mojom.activity.TaskDescription;
+import org.chromium.mojom.activity.UserFeedback;
+
+/**
+ * Android implementation of Activity.
+ *
+ * This is a port of
+ * https://github.com/flutter/engine/blob/master/sky/services/activity/src/org/domokit/activity/ActivityImpl.java
+ */
+public class ActivityImpl implements Activity {
+    private static final String TAG = "AndroidImpl";
+
+    private final android.app.Activity mActivity;
+    private int mVisibility = SystemUiVisibility.STANDARD;
+
+    private static class UserFeedBackImpl implements UserFeedback {
+        private final View mView;
+
+        public UserFeedBackImpl(View view) {
+            mView = view;
+        }
+
+        @Override
+        public void close() {}
+
+        @Override
+        public void onConnectionError(MojoException e) {}
+
+        /**
+         * @see UserFeedback#performHapticFeedback(int)
+         */
+        @Override
+        public void performHapticFeedback(int type) {
+            int androidType = 0;
+            switch (type) {
+                case HapticFeedbackType.LONG_PRESS:
+                    androidType = HapticFeedbackConstants.LONG_PRESS;
+                    break;
+                case HapticFeedbackType.VIRTUAL_KEY:
+                    androidType = HapticFeedbackConstants.VIRTUAL_KEY;
+                    break;
+                case HapticFeedbackType.KEYBOARD_TAP:
+                    androidType = HapticFeedbackConstants.KEYBOARD_TAP;
+                    break;
+                case HapticFeedbackType.CLOCK_TICK:
+                    androidType = HapticFeedbackConstants.CLOCK_TICK;
+                    break;
+                default:
+                    Log.e(TAG, "Unknown HapticFeedbackType " + type);
+                    return;
+            }
+            mView.performHapticFeedback(
+                    androidType, HapticFeedbackConstants.FLAG_IGNORE_VIEW_SETTING);
+        }
+
+        /**
+         * @see UserFeedback#performAuralFeedback(int)
+         */
+        @Override
+        public void performAuralFeedback(int type) {
+            int androidType = 0;
+            switch (type) {
+                case AuralFeedbackType.CLICK:
+                    androidType = SoundEffectConstants.CLICK;
+                    break;
+                case AuralFeedbackType.NAVIGATION_LEFT:
+                    androidType = SoundEffectConstants.NAVIGATION_LEFT;
+                    break;
+                case AuralFeedbackType.NAVIGATION_UP:
+                    androidType = SoundEffectConstants.NAVIGATION_UP;
+                    break;
+                case AuralFeedbackType.NAVIGATION_RIGHT:
+                    androidType = SoundEffectConstants.NAVIGATION_RIGHT;
+                    break;
+                case AuralFeedbackType.NAVIGATION_DOWN:
+                    androidType = SoundEffectConstants.NAVIGATION_DOWN;
+                    break;
+                default:
+                    Log.e(TAG, "Unknown AuralFeedbackType " + type);
+                    return;
+            }
+            mView.playSoundEffect(androidType);
+        }
+    }
+
+    /**
+     * Constructor.
+     */
+    public ActivityImpl(android.app.Activity activity) {
+        mActivity = activity;
+        activity.getApplication().registerActivityLifecycleCallbacks(
+                new ActivityLifecycleCallbacks() {
+
+                    @Override
+                    public void onActivityStopped(android.app.Activity activity) {}
+
+                    @Override
+                    public void onActivityStarted(android.app.Activity activity) {}
+
+                    @Override
+                    public void onActivitySaveInstanceState(
+                            android.app.Activity activity, Bundle bundle) {}
+
+                    @Override
+                    public void onActivityResumed(android.app.Activity activity) {
+                        if (activity == mActivity) {
+                            updateSystemUiVisibility();
+                        }
+                    }
+
+                    @Override
+                    public void onActivityPaused(android.app.Activity activity) {}
+
+                    @Override
+                    public void onActivityDestroyed(android.app.Activity activity) {}
+
+                    @Override
+                    public void onActivityCreated(android.app.Activity activity, Bundle bundle) {}
+                });
+    }
+
+    @Override
+    public void close() {}
+
+    @Override
+    public void onConnectionError(MojoException e) {}
+
+    /**
+     * @see Activity#getUserFeedback(InterfaceRequest)
+     */
+    @Override
+    public void getUserFeedback(final InterfaceRequest<UserFeedback> userFeedback) {
+        mActivity.runOnUiThread(new Runnable() {
+            @Override
+            public void run() {
+                UserFeedback.MANAGER.bind(
+                        new UserFeedBackImpl(mActivity.getWindow().getDecorView()), userFeedback);
+            }
+        });
+    }
+
+    /**
+     * @see Activity#startActivity(Intent)
+     */
+    @Override
+    public void startActivity(Intent intent) {
+        final android.content.Intent androidIntent =
+                new android.content.Intent(intent.action, Uri.parse(intent.url));
+
+        if (intent.component != null) {
+            ComponentName component = intent.component;
+            android.content.ComponentName androidComponent =
+                    new android.content.ComponentName(component.packageName, component.className);
+            androidIntent.setComponent(androidComponent);
+        }
+
+        if (intent.stringExtras != null) {
+            for (StringExtra extra : intent.stringExtras) {
+                androidIntent.putExtra(extra.name, extra.value);
+            }
+        }
+
+        if (intent.flags != 0) {
+            androidIntent.setFlags(intent.flags);
+        }
+
+        if (intent.type != null) {
+            androidIntent.setType(intent.type);
+        }
+
+        try {
+            mActivity.startActivity(androidIntent);
+        } catch (ActivityNotFoundException e) {
+            Log.e(TAG, "Unable to startActivity", e);
+        }
+    }
+
+    /**
+     * @see Activity#finishCurrentActivity()
+     */
+    @Override
+    public void finishCurrentActivity() {
+        Log.e(TAG, "finishCurrentActivity() is not implemented.");
+    }
+
+    /**
+     * @see Activity#setTaskDescription(TaskDescription)
+     */
+    @Override
+    public void setTaskDescription(TaskDescription description) {
+        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) {
+            return;
+        }
+        mActivity.setTaskDescription(new android.app.ActivityManager.TaskDescription(
+                description.label, null, description.primaryColor));
+    }
+
+    /**
+     * @see Activity#setSystemUiVisibility(int)
+     */
+    @Override
+    public void setSystemUiVisibility(int visibility) {
+        mVisibility = visibility;
+        updateSystemUiVisibility();
+    }
+
+    /**
+     * @see Activity#setRequestedOrientation(int)
+     */
+    @Override
+    public void setRequestedOrientation(int orientation) {
+        int androidOrientation = ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
+
+        switch (orientation) {
+            case ScreenOrientation.UNSPECIFIED:
+                androidOrientation = ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
+                break;
+            case ScreenOrientation.LANDSCAPE:
+                androidOrientation = ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE;
+                break;
+            case ScreenOrientation.PORTRAIT:
+                androidOrientation = ActivityInfo.SCREEN_ORIENTATION_PORTRAIT;
+                break;
+            case ScreenOrientation.NOSENSOR:
+                androidOrientation = ActivityInfo.SCREEN_ORIENTATION_NOSENSOR;
+                break;
+            default:
+                Log.w(TAG,
+                        "Unable to set the requested orientation. Unknown value: " + orientation);
+                break;
+        }
+
+        mActivity.setRequestedOrientation(androidOrientation);
+    }
+
+    private void updateSystemUiVisibility() {
+        int flags = View.SYSTEM_UI_FLAG_LAYOUT_STABLE | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN;
+
+        if (mVisibility >= SystemUiVisibility.FULLSCREEN) {
+            flags |= View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
+                    | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION | View.SYSTEM_UI_FLAG_FULLSCREEN;
+        }
+
+        if (mVisibility >= SystemUiVisibility.IMMERSIVE) {
+            flags |= View.SYSTEM_UI_FLAG_IMMERSIVE | View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY;
+        }
+
+        final int finalFlags = flags;
+        mActivity.runOnUiThread(new Runnable() {
+            @Override
+            public void run() {
+                mActivity.getWindow().getDecorView().setSystemUiVisibility(finalFlags);
+            }
+        });
+    }
+}
diff --git a/shell/BUILD.gn b/shell/BUILD.gn
index 5a3a360..54d013f 100644
--- a/shell/BUILD.gn
+++ b/shell/BUILD.gn
@@ -336,6 +336,7 @@
 
   android_library("java") {
     java_files = [
+      "android/apk/src/org/chromium/mojo/shell/AndroidFactory.java",
       "android/apk/src/org/chromium/mojo/shell/AndroidHandler.java",
       "android/apk/src/org/chromium/mojo/shell/BaseActivity.java",
       "android/apk/src/org/chromium/mojo/shell/FileHelper.java",
@@ -368,10 +369,12 @@
       "//mojo/public/java:application",
       "//mojo/public/java:bindings",
       "//mojo/public/java:system",
+      "//mojo/services/android/interfaces:interfaces_java",
       "//mojo/services/input/interfaces:interfaces_java",
       "//mojo/services/keyboard/interfaces:interfaces_java",
       "//mojo/services/nfc/interfaces:interfaces_java",
       "//mojo/services/vsync/interfaces:interfaces_java",
+      "//services/android",
       "//services/authentication",
       "//services/input",
       "//services/intent_receiver:bindings_java",
diff --git a/shell/android/apk/src/org/chromium/mojo/shell/AndroidFactory.java b/shell/android/apk/src/org/chromium/mojo/shell/AndroidFactory.java
new file mode 100644
index 0000000..f3a34c0
--- /dev/null
+++ b/shell/android/apk/src/org/chromium/mojo/shell/AndroidFactory.java
@@ -0,0 +1,29 @@
+// 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.
+
+package org.chromium.mojo.shell;
+
+import org.chromium.mojo.android.ActivityImpl;
+import org.chromium.mojo.application.ServiceFactoryBinder;
+import org.chromium.mojo.bindings.InterfaceRequest;
+import org.chromium.mojom.activity.Activity;
+
+/**
+ * A ServiceFactoryBinder for the android service.
+ */
+final class AndroidFactory implements ServiceFactoryBinder<Activity> {
+    @Override
+    public void bind(final InterfaceRequest<Activity> request) {
+        if (ViewportActivity.getCurrent() == null) {
+            request.close();
+            return;
+        }
+        Activity.MANAGER.bind(new ActivityImpl(ViewportActivity.getCurrent()), request);
+    }
+
+    @Override
+    public String getInterfaceName() {
+        return Activity.MANAGER.getName();
+    }
+}
diff --git a/shell/android/apk/src/org/chromium/mojo/shell/JavaApplicationRegistry.java b/shell/android/apk/src/org/chromium/mojo/shell/JavaApplicationRegistry.java
index 49b5ff3..5a7ef8e 100644
--- a/shell/android/apk/src/org/chromium/mojo/shell/JavaApplicationRegistry.java
+++ b/shell/android/apk/src/org/chromium/mojo/shell/JavaApplicationRegistry.java
@@ -85,24 +85,26 @@
     private static JavaApplicationRegistry create() {
         JavaApplicationRegistry registry = new JavaApplicationRegistry();
         // Register services.
+        registry.registerApplicationDelegate("mojo:android",
+                new ServiceProviderFactoryApplicationDelegate(new AndroidFactory()));
         registry.registerApplicationDelegate("mojo:authentication",
                 new AuthenticationApplicationDelegate(ApplicationStatus.getApplicationContext(),
                                                      CoreImpl.getInstance()));
-        registry.registerApplicationDelegate(
-                "mojo:input", new ServiceProviderFactoryApplicationDelegate(new InputFactory()));
         registry.registerApplicationDelegate("mojo:keyboard",
                 new ServiceProviderFactoryApplicationDelegate(new KeyboardFactory()));
         registry.registerApplicationDelegate(
+                "mojo:input", new ServiceProviderFactoryApplicationDelegate(new InputFactory()));
+        registry.registerApplicationDelegate(
                 "mojo:intent_receiver", new ServiceProviderFactoryApplicationDelegate(
                                                 IntentReceiverRegistry.getInstance()));
         registry.registerApplicationDelegate("mojo:location_service",
                 new LocationApplicationDelegate(ApplicationStatus.getApplicationContext(),
                                                      CoreImpl.getInstance()));
 
-        registry.registerApplicationDelegate("mojo:nfc", new NfcApplicationDelegate());
-        registry.registerApplicationDelegate("mojo:sharing", new SharingApplicationDelegate());
         registry.registerApplicationDelegate(
                 "mojo:native_viewport_support", new NativeViewportSupportApplicationDelegate());
+        registry.registerApplicationDelegate("mojo:nfc", new NfcApplicationDelegate());
+        registry.registerApplicationDelegate("mojo:sharing", new SharingApplicationDelegate());
         registry.registerApplicationDelegate(
                 "mojo:vsync", new ServiceProviderFactoryApplicationDelegate(
                                       new VsyncFactory(registry.mHandlerThread.getLooper())));
diff --git a/shell/android/apk/src/org/chromium/mojo/shell/ViewportActivity.java b/shell/android/apk/src/org/chromium/mojo/shell/ViewportActivity.java
index 29b69a7..b087cd0 100644
--- a/shell/android/apk/src/org/chromium/mojo/shell/ViewportActivity.java
+++ b/shell/android/apk/src/org/chromium/mojo/shell/ViewportActivity.java
@@ -19,6 +19,12 @@
  * Activity for displaying on the screen from the NativeViewportService.
  */
 public class ViewportActivity extends Activity {
+    private static Activity sCurrentActivity = null;
+
+    public static Activity getCurrent() {
+        return sCurrentActivity;
+    }
+
     /**
      * @see Activity#onKeyDown(int, KeyEvent)
      */
@@ -57,4 +63,22 @@
         super.onNewIntent(intent);
         new RuntimeException("This activity instance should only ever receive one intent.");
     }
+
+    /**
+     * @see Activity#onPause()
+     */
+    @Override
+    protected void onPause() {
+        if (sCurrentActivity == this) sCurrentActivity = null;
+        super.onPause();
+    }
+
+    /**
+     * @see Activity#onResume()
+     */
+    @Override
+    protected void onResume() {
+        super.onResume();
+        sCurrentActivity = this;
+    }
 }
