blob: f5f4c2e788ed8de862767cf00d4a6a43d47327f4 [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:io';
import 'package:fidl_fuchsia_modular/fidl_async.dart'
show
AddMod,
IntelligenceServicesProxy,
ProposalPublisherProxy,
QueryHandler,
QueryHandlerBinding,
QueryResponse,
SetFocusState,
StoryCommand,
SurfaceArrangement,
SurfaceRelation,
UserInput;
import 'package:fuchsia_modular/module.dart';
import 'package:fuchsia_modular/proposal.dart';
import 'package:fuchsia_services/services.dart';
/// Proposes suggestions for packages found on the system.
class PackageProposer extends QueryHandler {
final _proposalPublisherProxy = ProposalPublisherProxy();
final _queryHandlerBinding = QueryHandlerBinding();
/// Holds the currently focused story id. Set by [AppModel].
String focusedStoryId;
/// Starts the proposal process.
void start() {
final intelligenceServicesProxy = IntelligenceServicesProxy();
StartupContext.fromStartupInfo()
.incoming
.connectToService(intelligenceServicesProxy);
intelligenceServicesProxy
..getProposalPublisher(_proposalPublisherProxy.ctrl.request())
..registerQueryHandler(_queryHandlerBinding.wrap(this));
intelligenceServicesProxy.ctrl.close();
}
/// Stops the proposal process.
void stop() {
_proposalPublisherProxy.ctrl.close();
_queryHandlerBinding.close();
}
@override
Future<QueryResponse> onQuery(UserInput query) async {
List<Proposal> proposals = <Proposal>[];
if ((query.text?.length ?? 0) >= 2) {
if (query.text.startsWith('fuchsia-pkg://')) {
proposals.add(await _createPackageProposal(query.text, query.text));
} else {
final directory = Directory('/pkgfs/packages/');
if (await directory.exists()) {
proposals = await Future.wait(directory
.listSync(followLinks: false)
.map((FileSystemEntity fileSystemEntity) =>
Uri.parse(fileSystemEntity.path).pathSegments.last)
.where((String package) => package.contains(query.text))
.map((package) {
return focusedStoryId == null
? [_createPackageProposal(package, query.text)]
: [
_createPackageProposal(package, query.text),
_createPackageProposal(package, query.text, focusedStoryId)
];
}).expand((proposal) => proposal));
}
}
}
return QueryResponse(proposals: proposals);
}
Future<Proposal> _createPackageProposal(String package, String query,
[String focusedStory]) async {
final fullPackageName = package.startsWith('fuchsia-pkg://')
? package
: 'fuchsia-pkg://fuchsia.com/$package#meta/$package.cmx';
final addMod = AddMod(
intent: Intent(action: '', handler: fullPackageName),
surfaceParentModName: focusedStory == null ? [] : ['root'],
modName: [focusedStory == null ? 'root' : fullPackageName],
surfaceRelation: SurfaceRelation(
arrangement: SurfaceArrangement.copresent,
),
);
return Proposal(
id: focusedStory == null ? 'open_$package' : 'add_$package',
storyName: focusedStory,
headline: focusedStory == null ? 'open $package' : 'add $package',
confidence:
package == query ? 0.9 : package.startsWith(query) ? 0.7 : 0.5,
details: package,
)
..addStoryCommand(StoryCommand.withAddMod(addMod))
..addStoryCommand(
StoryCommand.withSetFocusState(SetFocusState(focused: true)));
}
}