[dart-sdk] Add connectToService, wrapping fdio_ns_connect.
Use fdio_ns_connect to connect to services in a namespace. For pure
persistant fidl services the old path of creating a file descriptor and
then opening a channel to that file descriptor doesn't work.
We should provide a way to directly connect to a service without first
treating it as a file.
Test:
* workstation.frank, reboot button on main menu works.
* astro, device_settings "erase user data" reboot works.
Change-Id: I725ba9350547309bebb5530aa44236f841d88f99
diff --git a/bin/device_settings/BUILD.gn b/bin/device_settings/BUILD.gn
index 00b6d93..0787e8c 100644
--- a/bin/device_settings/BUILD.gn
+++ b/bin/device_settings/BUILD.gn
@@ -29,5 +29,6 @@
"//topaz/public/dart/fuchsia_logger",
"//topaz/public/dart/fuchsia_services",
"//topaz/public/dart/widgets:lib.widgets",
+ "//zircon/public/fidl/fuchsia-device-manager",
]
}
diff --git a/bin/device_settings/lib/src/model.dart b/bin/device_settings/lib/src/model.dart
index d18a41d..5f65f0d 100644
--- a/bin/device_settings/lib/src/model.dart
+++ b/bin/device_settings/lib/src/model.dart
@@ -4,7 +4,9 @@
import 'dart:async';
+import 'package:fidl/fidl.dart';
import 'package:fidl_fuchsia_amber/fidl_async.dart' as amber;
+import 'package:fidl_fuchsia_device_manager/fidl_async.dart' as devmgr;
import 'package:flutter/foundation.dart';
import 'package:fuchsia_logger/logger.dart';
import 'package:fuchsia_services/services.dart';
@@ -123,10 +125,30 @@
final flagSet = await DeviceInfo.setFactoryResetFlag(shouldReset: true);
log.severe('Factory Reset flag set successfully: $flagSet');
- int status = System.reboot();
- if (status != 0 ) {
- log.severe('Unable to reboot system: $status');
+ final ChannelPair channels = ChannelPair();
+ if (channels.status != 0) {
+ log.severe('Unable to create channels: $channels.status');
+ return;
}
+
+ int status = System.connectToService(
+ '/svc/${devmgr.Administrator.$serviceName}',
+ channels.second.passHandle());
+ if (status != 0 ) {
+ channels.first.close();
+ log.severe('Unable to connect to device administrator service: $status');
+ return;
+ }
+
+ final devmgr.AdministratorProxy admin = devmgr.AdministratorProxy();
+ admin.ctrl.bind(InterfaceHandle<devmgr.Administrator>(channels.first));
+
+ status = await admin.suspend(devmgr.suspendFlagReboot);
+ if (status != 0) {
+ log.severe('Reboot call failed with status: $status');
+ }
+
+ admin.ctrl.close();
} else {
_showResetConfirmation = true;
notifyListeners();
diff --git a/bin/userpicker_base_shell/BUILD.gn b/bin/userpicker_base_shell/BUILD.gn
index 71ab93a..8da86f2 100644
--- a/bin/userpicker_base_shell/BUILD.gn
+++ b/bin/userpicker_base_shell/BUILD.gn
@@ -45,5 +45,6 @@
"//topaz/public/dart/fuchsia_scenic_flutter",
"//topaz/public/dart/widgets:lib.widgets",
"//topaz/public/lib/device/dart",
+ "//zircon/public/fidl/fuchsia-device-manager",
]
}
diff --git a/bin/userpicker_base_shell/lib/user_picker_base_shell_model.dart b/bin/userpicker_base_shell/lib/user_picker_base_shell_model.dart
index 4507601..3fe0d69 100644
--- a/bin/userpicker_base_shell/lib/user_picker_base_shell_model.dart
+++ b/bin/userpicker_base_shell/lib/user_picker_base_shell_model.dart
@@ -4,6 +4,9 @@
import 'dart:async';
+import 'package:fidl/fidl.dart';
+import 'package:fidl_fuchsia_cobalt/fidl_async.dart' as cobalt;
+import 'package:fidl_fuchsia_device_manager/fidl_async.dart' as devmgr;
import 'package:fidl_fuchsia_modular_auth/fidl_async.dart';
import 'package:fidl_fuchsia_sys/fidl_async.dart';
import 'package:fidl_fuchsia_ui_policy/fidl_async.dart';
@@ -49,7 +52,8 @@
this.onBaseShellStopped,
this.onWifiTapped,
this.onLogin,
- });
+ cobalt.Logger logger,
+ }) : super(logger);
@override
void onStop() {
@@ -74,11 +78,31 @@
}
/// Call when reset is tapped.
- void resetTapped() {
- int status = System.reboot();
- if (status != 0) {
- log.severe('Unable to reboot system: $status');
- }
+ void resetTapped() async {
+ final ChannelPair channels = ChannelPair();
+ if (channels.status != 0) {
+ log.severe('Unable to create channels: $channels.status');
+ return;
+ }
+
+ int status = System.connectToService(
+ '/svc/${devmgr.Administrator.$serviceName}',
+ channels.second.passHandle());
+ if (status != 0 ) {
+ channels.first.close();
+ log.severe('Unable to connect to device administrator service: $status');
+ return;
+ }
+
+ final devmgr.AdministratorProxy admin = devmgr.AdministratorProxy();
+ admin.ctrl.bind(InterfaceHandle<devmgr.Administrator>(channels.first));
+
+ status = await admin.suspend(devmgr.suspendFlagReboot);
+ if (status != 0) {
+ log.severe('Reboot call failed with status: $status');
+ }
+
+ admin.ctrl.close();
}
/// Create a new user and login with that user
diff --git a/bin/userpicker_base_shell/meta/userpicker_base_shell.cmx b/bin/userpicker_base_shell/meta/userpicker_base_shell.cmx
index 5b1e7b8..18b7ca4 100644
--- a/bin/userpicker_base_shell/meta/userpicker_base_shell.cmx
+++ b/bin/userpicker_base_shell/meta/userpicker_base_shell.cmx
@@ -8,14 +8,15 @@
],
"services": [
"fuchsia.cobalt.LoggerFactory",
+ "fuchsia.device.manager.Administrator",
"fuchsia.fonts.Provider",
"fuchsia.logger.LogSink",
"fuchsia.modular.Clipboard",
"fuchsia.modular.ContextWriter",
"fuchsia.net.Connectivity",
"fuchsia.netstack.Netstack",
- "fuchsia.sys.Launcher",
"fuchsia.sys.Environment",
+ "fuchsia.sys.Launcher",
"fuchsia.ui.input.ImeService",
"fuchsia.ui.policy.Presenter",
"fuchsia.ui.scenic.Scenic"
diff --git a/public/dart-pkg/zircon/BUILD.gn b/public/dart-pkg/zircon/BUILD.gn
index ce67b3b..af6f6ce 100644
--- a/public/dart-pkg/zircon/BUILD.gn
+++ b/public/dart-pkg/zircon/BUILD.gn
@@ -36,6 +36,7 @@
"//zircon/public/fidl/fuchsia-device-manager",
"//zircon/public/lib/async-default",
"//zircon/public/lib/ddk",
+ "//zircon/public/lib/fs",
"//zircon/public/lib/zx",
]
diff --git a/public/dart-pkg/zircon/lib/src/system.dart b/public/dart-pkg/zircon/lib/src/system.dart
index 739da7d..4d8ad5e 100644
--- a/public/dart-pkg/zircon/lib/src/system.dart
+++ b/public/dart-pkg/zircon/lib/src/system.dart
@@ -125,8 +125,8 @@
native 'System_ChannelCreate';
static HandleResult channelFromFile(String path)
native 'System_ChannelFromFile';
- static int reboot()
- native 'System_Reboot';
+ static int connectToService(String path, Handle channel)
+ native 'System_ConnectToService';
static int channelWrite(Handle channel, ByteData data, List<Handle> handles)
native 'System_ChannelWrite';
static ReadResult channelQueryAndRead(Handle channel)
@@ -158,4 +158,7 @@
// Time operations.
static int clockGet(int clockId) native 'System_ClockGet';
+
+ // TODO(edcoyne): Remove this, it is required to safely do an API transition across repos.
+ static int reboot() { return -2; /*ZX_ERR_NOT_SUPPORTED*/ }
}
diff --git a/public/dart-pkg/zircon/sdk_ext/system.cc b/public/dart-pkg/zircon/sdk_ext/system.cc
index bf81ce5..854295a 100644
--- a/public/dart-pkg/zircon/sdk_ext/system.cc
+++ b/public/dart-pkg/zircon/sdk_ext/system.cc
@@ -8,6 +8,7 @@
#include <ddk/device.h>
#include <fcntl.h>
+#include <fs/vfs.h>
#include <fuchsia/device/manager/cpp/fidl.h>
#include <lib/fdio/directory.h>
#include <lib/fdio/io.h>
@@ -128,7 +129,7 @@
return object;
}
-fxl::UniqueFD FdFromPath(std::string path) {
+fdio_ns_t* GetNamespace() {
// Grab the fdio_ns_t* out of the isolate.
Dart_Handle zircon_lib = Dart_LookupLibrary(ToDart("dart:zircon"));
FXL_DCHECK(!tonic::LogIfError(zircon_lib));
@@ -142,9 +143,12 @@
Dart_Handle result = Dart_IntegerToUint64(namespace_field, &fdio_ns_ptr);
FXL_DCHECK(!tonic::LogIfError(result));
+ return reinterpret_cast<fdio_ns_t*>(fdio_ns_ptr);
+}
+
+fxl::UniqueFD FdFromPath(std::string path) {
// Get a VMO for the file.
- fdio_ns_t* ns = reinterpret_cast<fdio_ns_t*>(fdio_ns_ptr);
- fxl::UniqueFD dirfd(fdio_ns_opendir(ns));
+ fxl::UniqueFD dirfd(fdio_ns_opendir(GetNamespace()));
if (!dirfd.is_valid())
return fxl::UniqueFD();
@@ -170,29 +174,11 @@
}
}
-zx_status_t System::Reboot() {
- zx::channel local, remote;
- auto status = zx::channel::create(0, &local, &remote);
- if (status != ZX_OK) {
- return status;
- }
+zx_status_t System::ConnectToService(std::string path, fxl::RefPtr<Handle> channel) {
+ return fdio_ns_connect(GetNamespace(), path.c_str(),
+ ZX_FS_RIGHT_READABLE | ZX_FS_RIGHT_WRITABLE,
+ channel->ReleaseHandle());
- const std::string service = std::string{"/svc/"} +
- fuchsia::device::manager::Administrator::Name_;
- status = fdio_service_connect(service.c_str(), remote.get());
- if (status != ZX_OK) {
- printf("failed to connect to service %s: %d\n", service.c_str(), status);
- return status;
- }
-
- zx_status_t call_status;
- fuchsia::device::manager::Administrator_SyncProxy administrator(std::move(local));
- status = administrator.Suspend(DEVICE_SUSPEND_FLAG_REBOOT, &call_status);
- if (status != ZX_OK || call_status != ZX_OK) {
- printf("Call to %s failed: ret: %d remote: %d\n", service.c_str(), status, call_status);
- }
-
- return status != ZX_OK ? status : call_status;
}
Dart_Handle System::ChannelFromFile(std::string path) {
@@ -469,7 +455,7 @@
V(System, ChannelWrite) \
V(System, ChannelQueryAndRead) \
V(System, EventpairCreate) \
- V(System, Reboot) \
+ V(System, ConnectToService) \
V(System, SocketCreate) \
V(System, SocketWrite) \
V(System, SocketRead) \
diff --git a/public/dart-pkg/zircon/sdk_ext/system.h b/public/dart-pkg/zircon/sdk_ext/system.h
index 8c96d7c..ffd39d1 100644
--- a/public/dart-pkg/zircon/sdk_ext/system.h
+++ b/public/dart-pkg/zircon/sdk_ext/system.h
@@ -56,7 +56,7 @@
static void RegisterNatives(tonic::DartLibraryNatives* natives);
- static zx_status_t Reboot();
+ static zx_status_t ConnectToService(std::string path, fxl::RefPtr<Handle> channel);
private:
static void VmoMapFinalizer(void* isolate_callback_data,
diff --git a/public/dart/zircon/lib/src/fakes/system.dart b/public/dart/zircon/lib/src/fakes/system.dart
index dfcb77b..a68e267 100644
--- a/public/dart/zircon/lib/src/fakes/system.dart
+++ b/public/dart/zircon/lib/src/fakes/system.dart
@@ -188,6 +188,12 @@
}
// System operations.
+ static int connectToService(String path, Handle channel) {
+ throw UnimplementedError(
+ 'System.connectToService() is not implemented on this platform.');
+ }
+
+ //TODO(edcoyne): remove after cross-repo transition.
static int reboot() {
throw UnimplementedError(
'System.reboot() is not implemented on this platform.');
diff --git a/runtime/flutter_runner/meta/flutter_aot_product_runner.cmx b/runtime/flutter_runner/meta/flutter_aot_product_runner.cmx
index 6e6a4c9..9795472 100644
--- a/runtime/flutter_runner/meta/flutter_aot_product_runner.cmx
+++ b/runtime/flutter_runner/meta/flutter_aot_product_runner.cmx
@@ -9,7 +9,6 @@
],
"services": [
"fuchsia.crash.Analyzer",
- "fuchsia.device.manager.Administrator",
"fuchsia.fonts.Provider",
"fuchsia.net.SocketProvider",
"fuchsia.sysmem.Allocator",
diff --git a/runtime/flutter_runner/meta/flutter_aot_runner.cmx b/runtime/flutter_runner/meta/flutter_aot_runner.cmx
index 6e6a4c9..9795472 100644
--- a/runtime/flutter_runner/meta/flutter_aot_runner.cmx
+++ b/runtime/flutter_runner/meta/flutter_aot_runner.cmx
@@ -9,7 +9,6 @@
],
"services": [
"fuchsia.crash.Analyzer",
- "fuchsia.device.manager.Administrator",
"fuchsia.fonts.Provider",
"fuchsia.net.SocketProvider",
"fuchsia.sysmem.Allocator",
diff --git a/runtime/flutter_runner/meta/flutter_jit_product_runner.cmx b/runtime/flutter_runner/meta/flutter_jit_product_runner.cmx
index 008e385..9795472 100644
--- a/runtime/flutter_runner/meta/flutter_jit_product_runner.cmx
+++ b/runtime/flutter_runner/meta/flutter_jit_product_runner.cmx
@@ -8,7 +8,6 @@
"vulkan"
],
"services": [
- "fuchsia.device.manager.Administrator",
"fuchsia.crash.Analyzer",
"fuchsia.fonts.Provider",
"fuchsia.net.SocketProvider",
diff --git a/runtime/flutter_runner/meta/flutter_jit_runner.cmx b/runtime/flutter_runner/meta/flutter_jit_runner.cmx
index 6e6a4c9..9795472 100644
--- a/runtime/flutter_runner/meta/flutter_jit_runner.cmx
+++ b/runtime/flutter_runner/meta/flutter_jit_runner.cmx
@@ -9,7 +9,6 @@
],
"services": [
"fuchsia.crash.Analyzer",
- "fuchsia.device.manager.Administrator",
"fuchsia.fonts.Provider",
"fuchsia.net.SocketProvider",
"fuchsia.sysmem.Allocator",