blob: 0250f2fc17aea456f3fc30f29ad6eae357ef65a2 [file] [log] [blame]
// Copyright 2019 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 'package:fidl_fuchsia_sys_index/fidl_async.dart';
import 'package:fidl_fuchsia_sys/fidl_async.dart';
import 'package:flutter/foundation.dart';
import 'package:fuchsia_logger/logger.dart';
import 'package:fuchsia_services/services.dart';
import 'package:meta/meta.dart';
import 'suggestion.dart';
const _kComponentIndexUrl =
'fuchsia-pkg://fuchsia.com/component_index#meta/component_index.cmx';
/// Class to encapsulate the functionality of the Suggestions Engine.
class SuggestionService {
final ComponentIndexProxy _componentIndex;
final LauncherProxy _launcher;
final ValueChanged<Suggestion> _onSuggestion;
/// Constructor.
const SuggestionService({
@required ComponentIndex componentIndex,
@required Launcher launcher,
ValueChanged<Suggestion> onSuggestion,
}) : _componentIndex = componentIndex,
_launcher = launcher,
_onSuggestion = onSuggestion;
/// Construct from [StartupContext].
factory SuggestionService.fromStartupContext({
StartupContext startupContext,
ValueChanged<Suggestion> onSuggestion,
}) {
final launcher = LauncherProxy();
startupContext.incoming.connectToService(launcher);
final Incoming incoming = Incoming();
final ComponentControllerProxy componentIndexController =
ComponentControllerProxy();
launcher.createComponent(
LaunchInfo(
url: _kComponentIndexUrl,
directoryRequest: incoming.request().passChannel(),
),
componentIndexController.ctrl.request(),
);
final componentIndex = ComponentIndexProxy();
incoming
..connectToService(componentIndex)
..close();
return SuggestionService(
componentIndex: componentIndex,
launcher: launcher,
onSuggestion: onSuggestion,
);
}
/// Release FIDL services.
void dispose() {
_componentIndex.ctrl.close();
_launcher.ctrl.close();
}
/// Returns an [Iterable<Suggestion>] for given [query].
Future<Iterable<Suggestion>> getSuggestions(String query,
[int maxSuggestions = 20]) async {
final newSuggestions = <Suggestion>[];
// Allow only non empty queries.
if (query.isEmpty) {
return newSuggestions;
}
try {
final results = await _componentIndex.fuzzySearch(query);
newSuggestions.addAll(results.map((url) {
final re = RegExp(r'fuchsia-pkg://fuchsia.com/(.+)#meta/.+');
final name = re.firstMatch(url)?.group(1);
return Suggestion(
id: '$url:${DateTime.now().millisecondsSinceEpoch}',
url: url,
title: name,
);
}));
} on Exception catch (e) {
log.info('Component Index error: $e');
}
return newSuggestions.take(maxSuggestions);
}
/// Invokes the [suggestion].
Future<void> invokeSuggestion(Suggestion suggestion) async {
_onSuggestion?.call(suggestion);
}
}