Skip to content

Commit

Permalink
feat: Transfer factory_reset_tools to monorepo
Browse files Browse the repository at this point in the history
  • Loading branch information
spydon committed Mar 26, 2024
1 parent 73bd8b8 commit efcda4f
Show file tree
Hide file tree
Showing 23 changed files with 1,989 additions and 1 deletion.
2 changes: 1 addition & 1 deletion .gitignore
Expand Up @@ -3,7 +3,7 @@ coverage/
*.iml
.vscode/
pubspec.lock
pubspec_overrides.yaml
**/pubspec_overrides.yaml
/*.snap
**/build/
**/.dart_tool/
Expand Down
53 changes: 53 additions & 0 deletions packages/factory_reset_tools/.gitignore
@@ -0,0 +1,53 @@
# Miscellaneous
*.class
*.log
*.pyc
*.swp
.DS_Store
.atom/
.buildlog/
.history
.svn/

# IntelliJ related
*.iml
*.ipr
*.iws
.idea/

# The .vscode folder contains launch configuration and tasks you configure in
# VS Code which you may wish to be included in version control, so this line
# is commented out by default.
.vscode/

# Flutter/Dart/Pub related
**/doc/api/
**/ios/Flutter/.last_build_id
.dart_tool/
.flutter-plugins
.flutter-plugins-dependencies
*.lock
.packages
.pub-cache/
.pub/
/build/
/android/
/ios/

# Linux related
generated_plugins.cmake
generated_plugin_registrant.*

# Web related
lib/generated_plugin_registrant.dart

# Symbolication related
app.*.symbols

# Obfuscation related
app.*.map.json

# Android Studio will place build artifacts here
/android/app/debug
/android/app/profile
/android/app/release
45 changes: 45 additions & 0 deletions packages/factory_reset_tools/.metadata
@@ -0,0 +1,45 @@
# This file tracks properties of this Flutter project.
# Used by Flutter tool to assess capabilities and perform upgrades etc.
#
# This file should be version controlled and should not be manually edited.

version:
revision: "abb292a07e20d696c4568099f918f6c5f330e6b0"
channel: "stable"

project_type: app

# Tracks metadata for the flutter migrate command
migration:
platforms:
- platform: root
create_revision: abb292a07e20d696c4568099f918f6c5f330e6b0
base_revision: abb292a07e20d696c4568099f918f6c5f330e6b0
- platform: android
create_revision: abb292a07e20d696c4568099f918f6c5f330e6b0
base_revision: abb292a07e20d696c4568099f918f6c5f330e6b0
- platform: ios
create_revision: abb292a07e20d696c4568099f918f6c5f330e6b0
base_revision: abb292a07e20d696c4568099f918f6c5f330e6b0
- platform: linux
create_revision: abb292a07e20d696c4568099f918f6c5f330e6b0
base_revision: abb292a07e20d696c4568099f918f6c5f330e6b0
- platform: macos
create_revision: abb292a07e20d696c4568099f918f6c5f330e6b0
base_revision: abb292a07e20d696c4568099f918f6c5f330e6b0
- platform: web
create_revision: abb292a07e20d696c4568099f918f6c5f330e6b0
base_revision: abb292a07e20d696c4568099f918f6c5f330e6b0
- platform: windows
create_revision: abb292a07e20d696c4568099f918f6c5f330e6b0
base_revision: abb292a07e20d696c4568099f918f6c5f330e6b0

# User provided section

# List of Local paths (relative to this file) that should be
# ignored by the migrate tool.
#
# Files that are not part of the templates will be ignored by default.
unmanaged_files:
- 'lib/main.dart'
- 'ios/Runner.xcodeproj/project.pbxproj'
5 changes: 5 additions & 0 deletions packages/factory_reset_tools/README.md
@@ -0,0 +1,5 @@
# Factory Reset Tools

TODO: To have a proper README

License: GPLv3, see LICENSE fo license text
5 changes: 5 additions & 0 deletions packages/factory_reset_tools/analysis_options.yaml
@@ -0,0 +1,5 @@
include: package:ubuntu_lints/analysis_options.yaml

linter:
rules:
- require_trailing_commas
@@ -0,0 +1,8 @@
<node name="/com/canonical/oem/FactoryResetTools">
<interface name="com.canonical.oem.FactoryResetTools">
<property name="Version" type="s" access="read"/>
<method name="Reboot">
<arg name="rebootOption" type="s" direction="in"/>
</method>
</interface>
</node>
119 changes: 119 additions & 0 deletions packages/factory_reset_tools/lib/cmdline.dart
@@ -0,0 +1,119 @@
import 'dart:io';
import 'package:args/command_runner.dart';
import 'package:factory_reset_tools/dbus_daemon.dart';
import 'package:factory_reset_tools/reboot.dart';
import 'package:factory_reset_tools/reset_media.dart';

/// Command line entrypoint of factory-reset-tools
class CreateResetMediaCommand extends Command<void> {
CreateResetMediaCommand() {
argParser.addOption(
'rp-uuid',
help: 'Use another reset partition filesystem UUID',
valueHelp: '1234-ABCD',
);
}
@override
final name = 'create-reset-media';
@override
final description = 'Create a reset media from reset partition';
@override
String get invocation {
final parents = [name];
for (var command = parent; command != null; command = command.parent) {
parents.add(command.name);
}
parents.add(runner!.executableName);

final invocation = parents.reversed.join(' ');
return '$invocation [arguments] disk-path';
}

@override
Future<void> run() async {
final argResults = this.argResults!;
final fsuuid = argResults['rp-uuid'] as String?;
if (argResults.rest.isEmpty) {
printUsage();
throw Exception('missing disk path');
}
await for (final progress
in createResetMedia(argResults.rest[0], fsuuid: fsuuid)) {
stdout.write(
"${((progress.percent ?? 0.0) * 100).toStringAsFixed(2)}% ${progress.status.name} ${progress.errMsg ?? ""}"
.padRight(75),
);
stdout.write('\r');
}
stdout.writeln();
exit(0);
}
}

class RebootCommand extends Command<void> {
RebootCommand();
@override
final name = 'reboot';

@override
final description =
'Reboot into reset partition, or any other preconfigured options.\n'
'If no option is given, a list of available options will be listed.';

@override
String get invocation {
final parents = [name];
for (var command = parent; command != null; command = command.parent) {
parents.add(command.name);
}
parents.add(runner!.executableName);

final invocation = parents.reversed.join(' ');
return '$invocation [reboot-option]';
}

@override
Future<void> run() async {
final argResults = this.argResults!;
if (argResults.rest.isEmpty) {
final options = getResetOptions();
stdout.writeln('List of available options:\n');
for (final option in options) {
stdout.writeln('${option.key}: ${option.title}');
if (option.description != null) {
stdout.writeln(' ${option.description}');
}
stdout.writeln();
}
return;
}
await startCommandViaDbus(argResults.rest[0]);
exit(0);
}
}

class DBusCommand extends Command<void> {
DBusCommand();
@override
final name = 'dbus';
@override
final description = 'Starts a DBus daemon';
@override
final hidden = true;

@override
Future<void> run() async {
await runDBusDaemon();
}
}

void main(List<String> args) async {
final runner = CommandRunner(
'factory-reset-tools-cli',
'Command line utility for factory reset.',
)
..addCommand(CreateResetMediaCommand())
..addCommand(RebootCommand())
..addCommand(DBusCommand());
await runner.run(args);
}
22 changes: 22 additions & 0 deletions packages/factory_reset_tools/lib/dbus_daemon.dart
@@ -0,0 +1,22 @@
import 'package:dbus/dbus.dart';
import 'package:factory_reset_tools/dbus_local_object.dart';
import 'package:factory_reset_tools/reboot.dart';

class FactoryResetToolsObject extends ComCanonicalOemFactoryResetTools {
@override
Future<DBusMethodResponse> getVersion() async {
return DBusGetPropertyResponse(const DBusString('1.0'));
}

@override
Future<DBusMethodResponse> doReboot(String rebootOption) async {
await startCommand(rebootOption);
return DBusMethodSuccessResponse();
}
}

Future<void> runDBusDaemon() async {
final client = DBusClient.system();
await client.requestName('com.canonical.oem.FactoryResetTools');
await client.registerObject(FactoryResetToolsObject());
}
110 changes: 110 additions & 0 deletions packages/factory_reset_tools/lib/dbus_local_object.dart
@@ -0,0 +1,110 @@
// This file was generated using the following command and may be overwritten.
// dart-dbus generate-object ../data/factory-reset-tools-object.xml

import 'package:dbus/dbus.dart';

class ComCanonicalOemFactoryResetTools extends DBusObject {
/// Creates a new object to expose on [path].
ComCanonicalOemFactoryResetTools({
DBusObjectPath path = const DBusObjectPath.unchecked(
'/com/canonical/oem/FactoryResetTools',
),
}) : super(path);

/// Gets value of property com.canonical.oem.FactoryResetTools.Version
Future<DBusMethodResponse> getVersion() async {
return DBusMethodErrorResponse.failed(
'Get com.canonical.oem.FactoryResetTools.Version not implemented',
);
}

/// Implementation of com.canonical.oem.FactoryResetTools.Reboot()
Future<DBusMethodResponse> doReboot(String rebootOption) async {
return DBusMethodErrorResponse.failed(
'com.canonical.oem.FactoryResetTools.Reboot() not implemented',
);
}

@override
List<DBusIntrospectInterface> introspect() {
return [
DBusIntrospectInterface(
'com.canonical.oem.FactoryResetTools',
methods: [
DBusIntrospectMethod(
'Reboot',
args: [
DBusIntrospectArgument(
DBusSignature('s'),
DBusArgumentDirection.in_,
name: 'rebootOption',
),
],
),
],
properties: [
DBusIntrospectProperty(
'Version',
DBusSignature('s'),
access: DBusPropertyAccess.read,
),
],
),
];
}

@override
Future<DBusMethodResponse> handleMethodCall(DBusMethodCall methodCall) async {
if (methodCall.interface == 'com.canonical.oem.FactoryResetTools') {
if (methodCall.name == 'Reboot') {
if (methodCall.signature != DBusSignature('s')) {
return DBusMethodErrorResponse.invalidArgs();
}
return doReboot(methodCall.values[0].asString());
} else {
return DBusMethodErrorResponse.unknownMethod();
}
} else {
return DBusMethodErrorResponse.unknownInterface();
}
}

@override
Future<DBusMethodResponse> getProperty(String interface, String name) async {
if (interface == 'com.canonical.oem.FactoryResetTools') {
if (name == 'Version') {
return getVersion();
} else {
return DBusMethodErrorResponse.unknownProperty();
}
} else {
return DBusMethodErrorResponse.unknownProperty();
}
}

@override
Future<DBusMethodResponse> setProperty(
String interface,
String name,
DBusValue value,
) async {
if (interface == 'com.canonical.oem.FactoryResetTools') {
if (name == 'Version') {
return DBusMethodErrorResponse.propertyReadOnly();
} else {
return DBusMethodErrorResponse.unknownProperty();
}
} else {
return DBusMethodErrorResponse.unknownProperty();
}
}

@override
Future<DBusMethodResponse> getAllProperties(String interface) async {
final properties = <String, DBusValue>{};
if (interface == 'com.canonical.oem.FactoryResetTools') {
properties['Version'] = (await getVersion()).returnValues[0];
}
return DBusMethodSuccessResponse([DBusDict.stringVariant(properties)]);
}
}

0 comments on commit efcda4f

Please sign in to comment.