blob: 53d70da769e7ec98fb7da35bf11b54181aa9ee1a [file] [log] [blame]
// Copyright 2017 The Fuchsia 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 'dart:async';
import 'dart:convert';
import '';
import 'package:fuchsia.fidl.modular/modular.dart';
import 'package:lib.decomposition.dart/decomposition.dart';
import 'package:fidl/fidl.dart';
import 'package:lib.logging/logging.dart';
import 'package:lib.proposal.dart/proposal.dart';
/// The Concert Agents subscribes to the hotel topic and makes proposals for
/// upcoming concerts (concert list module).
const String _kHotelTopic = 'link/hotel';
/// Global scoping to prevent garbage collection
final ContextReaderProxy _contextReader = new ContextReaderProxy();
ContextListenerImpl _contextListenerImpl;
final ProposalPublisherProxy _proposalPublisher = new ProposalPublisherProxy();
final ApplicationContext _context = new ApplicationContext.fromStartupInfo();
/// Concert ContextListener listens to hotel reservations and makes a concert
/// list proposal
class ContextListenerImpl extends ContextListener {
final ContextListenerBinding _binding = new ContextListenerBinding();
/// Gets the [InterfaceHandle]
/// The returned handle should only be used once.
InterfaceHandle<ContextListener> getHandle() => _binding.wrap(this);
Future<Null> onContextUpdate(ContextUpdate result) async {
for (final ContextUpdateEntry entry in result.values) {
if (entry.key != _kHotelTopic || entry.value.isEmpty) {
// TODO(thatguy): There can be more than one value. At some point, use the
// entity type in the ContextQuery instead of using topics as if they are
// types, and handle multiple instances.
dynamic data = json.decode(entry.value[0].content);
if (data != null && data['name'] is String) {
await _createProposal(data['name']);
/// Creates a concert list proposal
Future<Null> _createProposal(String hotelName) async {
String headline = 'Upcoming concerts near $hotelName this week';
final Uri arg = new Uri(
host: '',
pathSegments: <String>['metro_areas', '26330-us-sf-bay-area'],
Proposal proposal = await createProposal(
id: 'Concerts Near Hotel',
headline: headline,
subheadline: 'powered by Songkick',
color: 0xFF467187,
actions: <Action>[
new Action.withCreateStory(new CreateStory(
moduleId: 'concert_event_list',
json.encode(<String, dynamic>{'view': decomposeUri(arg)})))
log.fine('proposing concert suggestion');
Future<Null> main(List<dynamic> args) async {
connectToService(_context.environmentServices, _contextReader.ctrl);
connectToService(_context.environmentServices, _proposalPublisher.ctrl);
ContextQuery query =
const ContextQuery(selector: const <ContextQueryEntry>[const
key: _kHotelTopic, value: const ContextSelector(
type: ContextValueType.entity,
meta: const ContextMetadata(
entity: const EntityMetadata(topic: _kHotelTopic)))
_contextListenerImpl = new ContextListenerImpl();
_contextReader.subscribe(query, _contextListenerImpl.getHandle());