usb-creator-hackers team mailing list archive
-
usb-creator-hackers team
-
Mailing list archive
-
Message #00119
[Merge] lp:~xnox/usb-creator/nexus7 into lp:usb-creator
Dmitrijs Ledkovs has proposed merging lp:~xnox/usb-creator/nexus7 into lp:usb-creator.
Requested reviews:
James Hunt (jamesodhunt)
The Ubuntu Nexus7 Team (ubuntu-nexus7)
usb-creator hackers (usb-creator-hackers)
For more details, see:
https://code.launchpad.net/~xnox/usb-creator/nexus7/+merge/144753
--
https://code.launchpad.net/~xnox/usb-creator/nexus7/+merge/144753
Your team usb-creator hackers is requested to review the proposed merge of lp:~xnox/usb-creator/nexus7 into lp:usb-creator.
=== modified file 'bin/usb-creator-gtk'
--- bin/usb-creator-gtk 2012-05-04 09:29:27 +0000
+++ bin/usb-creator-gtk 2013-01-24 17:05:29 +0000
@@ -1,4 +1,4 @@
-#!/usr/bin/python
+#!/usr/bin/python3
# Copyright (C) 2009 Canonical Ltd.
@@ -27,6 +27,7 @@
os.environ['USBCREATOR_LOCAL'] = '1'
from usbcreator.frontends.gtk import GtkFrontend
from usbcreator.backends.udisks import UDisksBackend
+from usbcreator.backends.fastboot import FastbootBackend
from usbcreator.misc import sane_path, setup_gettext, setup_logging, text_type
sane_path()
@@ -56,13 +57,23 @@
help=_('allow writing to system-internal devices'))
parser.add_option('--show-all', dest='show_all', action='store_true',
help=_('Show all devices'))
+parser.add_option('--fastboot', dest='fastboot', action='store_true',
+ help=_('Use fastboot backend to flash Android devices.'))
(options, args) = parser.parse_args()
try:
- backend = UDisksBackend(allow_system_internal=options.allow_system_internal,
- show_all=options.show_all)
- frontend = GtkFrontend(backend, options.img, options.persistent,
- allow_system_internal=options.allow_system_internal)
+ if options.fastboot:
+ options.persistent = False
+ backend = FastbootBackend()
+ else:
+ backend = UDisksBackend(
+ allow_system_internal=options.allow_system_internal,
+ show_all=options.show_all)
+ frontend = GtkFrontend(
+ backend, options.img, options.persistent,
+ allow_system_internal=options.allow_system_internal,
+ fastboot_mode=options.fastboot,
+ )
except DBusException as e:
# FIXME evand 2009-07-09: Wouldn't service activation pick this up
# automatically?
=== modified file 'debian/changelog'
--- debian/changelog 2013-01-17 18:01:26 +0000
+++ debian/changelog 2013-01-24 17:05:29 +0000
@@ -1,3 +1,9 @@
+usb-creator (0.2.45) UNRELEASED; urgency=low
+
+ * Support flashing devices using fastboot (e.g. Nexus7).
+
+ -- Dmitrijs Ledkovs <dmitrij.ledkov@xxxxxxxxxx> Wed, 16 Jan 2013 13:54:16 +0000
+
usb-creator (0.2.44) raring; urgency=low
* Revert sync remount flag. It's too slow.
=== modified file 'debian/rules'
--- debian/rules 2012-11-09 00:42:18 +0000
+++ debian/rules 2013-01-24 17:05:29 +0000
@@ -35,6 +35,9 @@
find . -path "$(vendor_dir)/*.svg" -exec cp {} $(dest) \;
dh_install
+override_dh_installinit:
+ dh_installinit --upstart-only
+
override_dh_installmenu:
ifneq (,$(wildcard $(vendor_dir)/*.xpm))
mkdir -p $(xpm_gtk) $(xpm_kde)
=== modified file 'debian/usb-creator-common.install'
--- debian/usb-creator-common.install 2010-05-14 16:50:14 +0000
+++ debian/usb-creator-common.install 2013-01-24 17:05:29 +0000
@@ -5,6 +5,7 @@
usr/lib/python*/*/usbcreator/frontends/base/*
usr/lib/python*/*/usbcreator/*.py
usr/share/usb-creator/usb-creator-helper
+usr/share/usb-creator/ubuntu-nexus7-USAGE-NOTICE-en.txt
usr/share/polkit-1/actions/*
usr/share/dbus-1/system-services/*
etc/dbus-1/system.d/*
=== added file 'debian/usb-creator-gtk.upstart'
--- debian/usb-creator-gtk.upstart 1970-01-01 00:00:00 +0000
+++ debian/usb-creator-gtk.upstart 2013-01-24 17:05:29 +0000
@@ -0,0 +1,24 @@
+# usb-creator-gtk
+
+# This really should be enchanced user session job
+# and not a system one!
+# Then the hacks to get DISPLAY & user can go away.
+# Also the udev test are ugly =/
+
+author "Dmitrijs Ledkovs <xnox@xxxxxxxxxx>"
+
+start on (usb-device-added)
+pre-start script
+ [ x"$ID_VENDOR_ID" != x"18d1" ] && { stop; exit 0; }
+ [ x"$ID_MODEL_ID" != x"4e40" ] && { [ x"$ID_MODEL_ID" != x"d001" ] && { stop; exit 0; } }
+end script
+
+script
+test -f /usr/share/acpi-support/power-funcs || exit 0
+. /usr/share/acpi-support/power-funcs
+
+getXconsole
+if [ x"$XAUTHORITY" != x"" ]; then
+ sudo -u $user DISPLAY="$DISPLAY" usb-creator-gtk --fastboot
+fi
+end script
=== added file 'gui/ubuntu-nexus7-USAGE-NOTICE-en.txt'
--- gui/ubuntu-nexus7-USAGE-NOTICE-en.txt 1970-01-01 00:00:00 +0000
+++ gui/ubuntu-nexus7-USAGE-NOTICE-en.txt 2013-01-24 17:05:29 +0000
@@ -0,0 +1,21 @@
+"Ubuntu for Google Nexus 7" is released for free non-commercial use on
+the Google Nexus 7 only. It is provided without warranty, even the
+implied warranty of merchantability, satisfaction or fitness for a
+particular use. See the licence included with each program for details.
+ Some licences may grant additional rights; this notice shall not limit
+your rights under each program's licence. Licences for each program are
+available in the usr/share/doc directory. Source code for Ubuntu can be
+downloaded from archive.ubuntu.com. Ubuntu, the Ubuntu logo and
+Canonical are registered trademarks of Canonical Ltd. All other
+trademarks are the property of their respective owners.
+
+"Ubuntu for Google Nexus 7" is released for limited use due to the
+inclusion of the following hardware drivers:
+
+[Wireless] - [Broadcom Corporation]
+[Bluetooth] - [Broadcom Corporation]
+[Graphics] - [NVIDIA Corporation]
+[Video Codecs] - [NVIDIA Corporation]
+
+The original components and licenses can be found at:
+https://developers.google.com/android/nexus/drivers#grouper
=== modified file 'gui/usbcreator-gtk.ui'
--- gui/usbcreator-gtk.ui 2012-02-20 20:05:55 +0000
+++ gui/usbcreator-gtk.ui 2013-01-24 17:05:29 +0000
@@ -1,13 +1,56 @@
<?xml version="1.0" encoding="UTF-8"?>
<interface>
- <requires lib="gtk+" version="2.24"/>
- <!-- interface-naming-policy toplevel-contextual -->
+ <!-- interface-requires gtk+ 3.0 -->
<object class="GtkAdjustment" id="adjustment1">
<property name="upper">100</property>
<property name="step_increment">1</property>
<property name="page_increment">10</property>
<property name="page_size">10</property>
</object>
+ <object class="GtkDialog" id="eula_dialog">
+ <property name="can_focus">False</property>
+ <property name="border_width">5</property>
+ <property name="title" translatable="yes">Legal Notice</property>
+ <property name="type_hint">dialog</property>
+ <child internal-child="vbox">
+ <object class="GtkBox" id="dialog-vbox6">
+ <property name="can_focus">False</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">2</property>
+ <child internal-child="action_area">
+ <object class="GtkButtonBox" id="dialog-action_area6">
+ <property name="can_focus">False</property>
+ <property name="layout_style">end</property>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="pack_type">end</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkTextView" id="eula_text">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="vexpand">True</property>
+ <property name="editable">False</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ </object>
<object class="GtkDialog" id="failed_dialog">
<property name="can_focus">True</property>
<property name="title" translatable="yes">Installation Failed</property>
@@ -18,11 +61,11 @@
<property name="type_hint">dialog</property>
<property name="gravity">center</property>
<child internal-child="vbox">
- <object class="GtkVBox" id="dialog-vbox5">
+ <object class="GtkBox" id="dialog-vbox5">
<property name="visible">True</property>
<property name="can_focus">False</property>
<child internal-child="action_area">
- <object class="GtkHButtonBox" id="dialog-action_area5">
+ <object class="GtkButtonBox" id="dialog-action_area5">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="layout_style">end</property>
@@ -33,7 +76,6 @@
<property name="can_focus">True</property>
<property name="can_default">True</property>
<property name="receives_default">False</property>
- <property name="use_action_appearance">False</property>
<property name="use_stock">True</property>
</object>
<packing>
@@ -123,11 +165,11 @@
<property name="type_hint">dialog</property>
<property name="gravity">center</property>
<child internal-child="vbox">
- <object class="GtkVBox" id="dialog-vbox3">
+ <object class="GtkBox" id="dialog-vbox3">
<property name="visible">True</property>
<property name="can_focus">False</property>
<child internal-child="action_area">
- <object class="GtkHButtonBox" id="dialog-action_area3">
+ <object class="GtkButtonBox" id="dialog-action_area3">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="layout_style">end</property>
@@ -136,7 +178,6 @@
<property name="label" translatable="yes">Test Disk</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
- <property name="use_action_appearance">False</property>
</object>
<packing>
<property name="expand">False</property>
@@ -151,7 +192,6 @@
<property name="can_focus">True</property>
<property name="can_default">True</property>
<property name="receives_default">False</property>
- <property name="use_action_appearance">False</property>
<property name="use_stock">True</property>
</object>
<packing>
@@ -305,7 +345,6 @@
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">False</property>
- <property name="use_action_appearance">False</property>
<property name="use_stock">True</property>
</object>
<packing>
@@ -335,11 +374,11 @@
<property name="type_hint">dialog</property>
<property name="gravity">center</property>
<child internal-child="vbox">
- <object class="GtkVBox" id="dialog-vbox10">
+ <object class="GtkBox" id="dialog-vbox10">
<property name="visible">True</property>
<property name="can_focus">False</property>
<child internal-child="action_area">
- <object class="GtkHButtonBox" id="dialog-action_area10">
+ <object class="GtkButtonBox" id="dialog-action_area10">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="layout_style">end</property>
@@ -350,7 +389,6 @@
<property name="can_focus">True</property>
<property name="can_default">True</property>
<property name="receives_default">False</property>
- <property name="use_action_appearance">False</property>
<property name="use_stock">True</property>
</object>
<packing>
@@ -366,7 +404,6 @@
<property name="can_focus">True</property>
<property name="can_default">True</property>
<property name="receives_default">False</property>
- <property name="use_action_appearance">False</property>
<property name="use_stock">True</property>
<signal name="clicked" handler="quit" swapped="no"/>
</object>
@@ -509,18 +546,20 @@
</child>
<child>
<object class="GtkScrolledWindow" id="scrolledwindow1">
+ <property name="height_request">70</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="hscrollbar_policy">never</property>
- <property name="vscrollbar_policy">automatic</property>
<property name="shadow_type">in</property>
- <property name="height_request">70</property>
<child>
<object class="GtkTreeView" id="source_treeview">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="headers_clickable">False</property>
<property name="rubber_banding">True</property>
+ <child internal-child="selection">
+ <object class="GtkTreeSelection" id="treeview-selection1"/>
+ </child>
</object>
</child>
</object>
@@ -551,7 +590,6 @@
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
- <property name="use_action_appearance">False</property>
<signal name="clicked" handler="add_file_source_dialog" swapped="no"/>
</object>
<packing>
@@ -607,17 +645,19 @@
</child>
<child>
<object class="GtkScrolledWindow" id="scrolledwindow2">
+ <property name="height_request">70</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="hscrollbar_policy">never</property>
- <property name="vscrollbar_policy">automatic</property>
<property name="shadow_type">in</property>
- <property name="height_request">70</property>
<child>
<object class="GtkTreeView" id="dest_treeview">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="headers_clickable">False</property>
+ <child internal-child="selection">
+ <object class="GtkTreeSelection" id="treeview-selection2"/>
+ </child>
</object>
</child>
</object>
@@ -659,7 +699,6 @@
<property name="label">gtk-open</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
- <property name="use_action_appearance">False</property>
<property name="use_stock">True</property>
<signal name="clicked" handler="open_dest_folder" swapped="no"/>
</object>
@@ -674,7 +713,6 @@
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
- <property name="use_action_appearance">False</property>
<signal name="clicked" handler="format_dest_clicked" swapped="no"/>
<child>
<object class="GtkHBox" id="hbox3">
@@ -767,7 +805,7 @@
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">False</property>
- <property name="use_action_appearance">False</property>
+ <property name="xalign">0.5</property>
<property name="active">True</property>
<property name="draw_indicator">True</property>
</object>
@@ -837,7 +875,7 @@
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">False</property>
- <property name="use_action_appearance">False</property>
+ <property name="xalign">0.5</property>
<property name="active">True</property>
<property name="draw_indicator">True</property>
<property name="group">persist_enabled</property>
@@ -877,7 +915,6 @@
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<property name="border_width">4</property>
- <property name="use_action_appearance">False</property>
<property name="use_stock">True</property>
</object>
<packing>
@@ -894,7 +931,6 @@
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<property name="border_width">4</property>
- <property name="use_action_appearance">False</property>
<property name="use_stock">True</property>
<signal name="clicked" handler="quit" swapped="no"/>
</object>
@@ -914,7 +950,6 @@
<property name="has_default">True</property>
<property name="receives_default">True</property>
<property name="border_width">4</property>
- <property name="use_action_appearance">False</property>
<signal name="clicked" handler="install" swapped="no"/>
</object>
<packing>
=== modified file 'setup.py'
--- setup.py 2012-01-21 13:31:38 +0000
+++ setup.py 2013-01-24 17:05:29 +0000
@@ -20,11 +20,13 @@
'usbcreator.frontends.base',
'usbcreator.backends',
'usbcreator.backends.base',
+ 'usbcreator.backends.fastboot',
'usbcreator.backends.udisks',
],
scripts=['bin/usb-creator-gtk','bin/usb-creator-kde'],
data_files=[('share/usb-creator', ['gui/usbcreator-gtk.ui']),
('share/usb-creator', ['bin/usb-creator-helper']),
+ ('share/usb-creator', ['gui/ubuntu-nexus7-USAGE-NOTICE-en.txt']),
('share/icons/hicolor/scalable/apps', ['desktop/usb-creator-gtk.svg', 'desktop/usb-creator-kde.svg']),
('share/kde4/apps/usb-creator-kde', ['gui/usbcreator-kde.ui']),
('/etc/dbus-1/system.d', ['dbus/com.ubuntu.USBCreator.conf']),
=== modified file 'usbcreator/backends/base/backend.py'
--- usbcreator/backends/base/backend.py 2012-11-09 00:42:18 +0000
+++ usbcreator/backends/base/backend.py 2013-01-24 17:05:29 +0000
@@ -75,6 +75,19 @@
def get_current_source(self):
return self.current_source
+ # Common helpers
+
+ def _device_removed(self, device):
+ logging.debug('Device has been removed from the system: %s' % device)
+ if device in self.sources:
+ if misc.callable(self.source_removed_cb):
+ self.source_removed_cb(device)
+ self.sources.pop(device)
+ elif device in self.targets:
+ if misc.callable(self.target_removed_cb):
+ self.target_removed_cb(device)
+ self.targets.pop(device)
+
# Signals.
def source_added_cb(self, drive):
@@ -170,11 +183,13 @@
return changed
def install(self, source, target, persist, device=None,
- allow_system_internal=False):
+ allow_system_internal=False,
+ fastboot_mode=False):
logging.debug('Starting install thread.')
self.install_thread = usbcreator.install.install(
source, target, persist, device=device,
- allow_system_internal=allow_system_internal)
+ allow_system_internal=allow_system_internal,
+ fastboot_mode=fastboot_mode)
# Connect signals.
self.install_thread.success = self.success_cb
self.install_thread.failure = self.failure_cb
=== added directory 'usbcreator/backends/fastboot'
=== added file 'usbcreator/backends/fastboot/__init__.py'
--- usbcreator/backends/fastboot/__init__.py 1970-01-01 00:00:00 +0000
+++ usbcreator/backends/fastboot/__init__.py 2013-01-24 17:05:29 +0000
@@ -0,0 +1,1 @@
+from usbcreator.backends.fastboot.backend import FastbootBackend
=== added file 'usbcreator/backends/fastboot/backend.py'
--- usbcreator/backends/fastboot/backend.py 1970-01-01 00:00:00 +0000
+++ usbcreator/backends/fastboot/backend.py 2013-01-24 17:05:29 +0000
@@ -0,0 +1,68 @@
+import logging
+
+from gi.repository import GUdev
+from gi.repository import GLib
+
+from usbcreator.backends.base import Backend
+from usbcreator import misc
+
+KNOWN_IDS = {
+ 'ID_VENDOR_ID': ('18d1',),
+ 'ID_MODEL_ID': ('4e40', 'd001',),
+}
+
+class FastbootBackend(Backend):
+ def __init__(self):
+ Backend.__init__(self)
+ logging.debug('FastbootBackend')
+ self.client = GUdev.Client(subsystems=['usb'])
+
+ def on_uevent(self, action, device):
+ logging.debug('action: %s' % action)
+ logging.debug('device: %s' % device.get_sysfs_path())
+
+ for key,ids in KNOWN_IDS.items():
+ result = device.get_property(key)
+ if result not in ids:
+ logging.debug('Unknown %s: %s' % (key, result))
+ return
+
+ [logging.debug('%s=%s' % (k, device.get_property(k))) for k in device.get_property_keys()]
+
+ key = device.get_property('ID_SERIAL_SHORT')
+
+ if action == 'add':
+ self.targets[key] = {
+ 'vendor' : device.get_property('ID_VENDOR_FROM_DATABASE'),
+ 'model' : device.get_property('ID_MODEL'),
+ 'label' : '',
+ 'device' : device.get_property('ID_SERIAL_SHORT'),
+ 'status' : misc.CAN_USE,
+ }
+ if misc.callable(self.target_added_cb):
+ self.target_added_cb(key)
+ elif action == 'remove':
+ self._device_removed(key)
+
+ def detect_devices(self):
+ def _on_uevent(client, action, device):
+ self.on_uevent(action, device)
+
+ self.client.connect('uevent', _on_uevent)
+ # Just in case, go over already attached devices
+ for device in self.client.query_by_subsystem('usb'):
+ self.on_uevent('add', device)
+
+ def update_free(self):
+ # No progress yet.
+ return True
+
+ def _is_casper_cd(self, filename):
+ # no cds for us
+ return None
+
+ def unmount(self):
+ return
+
+ def shutdown(self):
+ return
=== modified file 'usbcreator/backends/udisks/backend.py'
--- usbcreator/backends/udisks/backend.py 2012-07-06 12:49:06 +0000
+++ usbcreator/backends/udisks/backend.py 2013-01-24 17:05:29 +0000
@@ -229,17 +229,6 @@
else:
logging.debug('not adding device: 0 byte disk.')
- def _device_removed(self, device):
- logging.debug('Device has been removed from the system: %s' % device)
- if device in self.sources:
- if misc.callable(self.source_removed_cb):
- self.source_removed_cb(device)
- self.sources.pop(device)
- elif device in self.targets:
- if misc.callable(self.target_removed_cb):
- self.target_removed_cb(device)
- self.targets.pop(device)
-
# Device manipulation functions.
def _is_casper_cd(self, filename):
cmd = ['isoinfo', '-J', '-i', filename, '-x', '/.disk/info']
=== modified file 'usbcreator/frontends/gtk/frontend.py'
--- usbcreator/frontends/gtk/frontend.py 2013-01-10 14:58:41 +0000
+++ usbcreator/frontends/gtk/frontend.py 2013-01-24 17:05:29 +0000
@@ -30,8 +30,10 @@
if 'USBCREATOR_LOCAL' in os.environ:
ui_path = os.path.join(os.getcwd(), 'gui/usbcreator-gtk.ui')
+ eula_path = os.path.join(os.getcwd(), 'gui/ubuntu-nexus7-USAGE-NOTICE-en.txt')
else:
ui_path = '/usr/share/usb-creator/usbcreator-gtk.ui'
+ eula_path = '/usr/share/usb-creator/ubuntu-nexus7-USAGE-NOTICE-en.txt'
GObject.threads_init()
Gdk.threads_init()
@@ -60,10 +62,12 @@
DBusGMainLoop(set_as_default=True)
def __init__(self, backend, img=None, persistent=True,
- allow_system_internal=False):
+ allow_system_internal=False,
+ fastboot_mode=False):
self.allow_system_internal = allow_system_internal
-
+ self.fastboot_mode = fastboot_mode
+
self.all_widgets = set()
self.builder = Gtk.Builder()
@@ -98,11 +102,6 @@
self.finished_exit.connect('clicked', lambda x: self.finished_dialog.hide())
self.failed_exit.connect('clicked', lambda x: self.failed_exit.hide())
self.progress_cancel_button.connect('clicked', lambda x: self.warning_dialog.show())
- # we currently do not have help
- self.button_help.hide()
- #self.button_help.connect('clicked', lambda x: Gtk.show_uri(self.button_help.get_screen(),
- # 'ghelp:usb-creator',
- # Gtk.get_current_event_time()))
def format_value(scale, value):
return misc.format_mb_size(value)
@@ -129,6 +128,30 @@
# Pulse state.
self.pulsing = False
+ # Hide erase in fastboot mode
+ if self.fastboot_mode:
+ self.format_dest.hide()
+ self.intro_label.set_text(_('To run Ubuntu from a portable device, it needs to be set up first.'))
+ self.label2.set_text(_('Source disc image (.img):'))
+ self.label3.set_text(_('Target device:'))
+ self.window.set_title(_('Ubuntu Core Installer'))
+ self.button_install.set_label(_('Install Ubuntu Core'))
+ self.button_help.set_label(_('Legal'))
+ self.button_help.connect('clicked', self.show_eula)
+ self.eula_dialog.add_buttons(
+ Gtk.STOCK_CANCEL, Gtk.ResponseType.CANCEL,
+ Gtk.STOCK_OK, Gtk.ResponseType.OK
+ )
+ with open(eula_path, 'r') as f:
+ text = ''.join(f.readlines())
+ self.eula_text.get_buffer().set_text(text)
+ else:
+ # we currently do not have help
+ self.button_help.hide()
+ #self.button_help.connect('clicked', lambda x: Gtk.show_uri(self.button_help.get_screen(),
+ # 'ghelp:usb-creator',
+ # Gtk.get_current_event_time()))
+
self.setup_sources_treeview()
self.setup_targets_treeview()
self.persist_vbox.set_sensitive(False)
@@ -345,6 +368,8 @@
cell_name.set_property('ellipsize', Pango.EllipsizeMode.END)
cell_pixbuf = Gtk.CellRendererPixbuf()
column_name = Gtk.TreeViewColumn(_('CD-Drive/Image'))
+ if self.fastboot_mode:
+ column_name = Gtk.TreeViewColumn(_('Image'))
column_name.set_sizing(Gtk.TreeViewColumnSizing.AUTOSIZE)
column_name.set_resizable(True)
column_name.set_expand(True)
@@ -355,15 +380,16 @@
column_name.set_cell_data_func(cell_name, column_data_func, 0)
column_name.set_cell_data_func(cell_pixbuf, pixbuf_data_func, None)
- cell_version = Gtk.CellRendererText()
- cell_version.set_property('ellipsize', Pango.EllipsizeMode.END)
- column_name = Gtk.TreeViewColumn(_('OS Version'), cell_version)
- column_name.set_cell_data_func(cell_version, column_data_func, 1)
- column_name.set_sizing(Gtk.TreeViewColumnSizing.AUTOSIZE)
- column_name.set_resizable(True)
- column_name.set_expand(True)
- column_name.set_min_width(75)
- self.source_treeview.append_column(column_name)
+ if not self.fastboot_mode:
+ cell_version = Gtk.CellRendererText()
+ cell_version.set_property('ellipsize', Pango.EllipsizeMode.END)
+ column_name = Gtk.TreeViewColumn(_('OS Version'), cell_version)
+ column_name.set_cell_data_func(cell_version, column_data_func, 1)
+ column_name.set_sizing(Gtk.TreeViewColumnSizing.AUTOSIZE)
+ column_name.set_resizable(True)
+ column_name.set_expand(True)
+ column_name.set_min_width(75)
+ self.source_treeview.append_column(column_name)
cell_size = Gtk.CellRendererText()
cell_size.set_property('ellipsize', Pango.EllipsizeMode.END)
@@ -416,16 +442,20 @@
m.row_changed(m.get_path(iterator), iterator)
break
iterator = m.iter_next(iterator)
+
+ target = self.backend.targets[udi]
+
# Update persistence maximum value.
- self.persist_vbox.set_sensitive(False)
- self.persist_enabled_vbox.set_sensitive(False)
- target = self.backend.targets[udi]
- persist_mb = target['persist'] / 1024 / 1024
- if persist_mb > misc.MIN_PERSISTENCE:
- self.persist_vbox.set_sensitive(True)
- self.persist_enabled_vbox.set_sensitive(True)
- self.persist_value.set_range(misc.MIN_PERSISTENCE, persist_mb)
- self.persist_value.set_value(misc.MIN_PERSISTENCE)
+ if not self.fastboot_mode:
+ self.persist_vbox.set_sensitive(False)
+ self.persist_enabled_vbox.set_sensitive(False)
+ persist_mb = target['persist'] / 1024 / 1024
+ if persist_mb > misc.MIN_PERSISTENCE:
+ self.persist_vbox.set_sensitive(True)
+ self.persist_enabled_vbox.set_sensitive(True)
+ self.persist_value.set_range(misc.MIN_PERSISTENCE, persist_mb)
+ self.persist_value.set_value(misc.MIN_PERSISTENCE)
+
# Update install button state.
status = target['status']
source = self.backend.get_current_source()
@@ -467,6 +497,9 @@
if udi:
self.update_target(udi)
+ if self.fastboot_mode:
+ return
+
dev = self.backend.targets[udi]
p = dev['parent']
if p and p in self.backend.targets:
@@ -546,45 +579,51 @@
column_name.set_cell_data_func(cell_name, column_data_func, 0)
column_name.set_cell_data_func(cell_pixbuf, pixbuf_data_func, None)
- cell_name = Gtk.CellRendererText()
- cell_name.set_property('ellipsize', Pango.EllipsizeMode.END)
- column_name = Gtk.TreeViewColumn(_('Label'), cell_name)
- column_name.set_cell_data_func(cell_name, column_data_func, 1)
- column_name.set_sizing(Gtk.TreeViewColumnSizing.AUTOSIZE)
- column_name.set_resizable(True)
- column_name.set_expand(True)
- column_name.set_min_width(75)
- self.dest_treeview.append_column(column_name)
-
- cell_capacity = Gtk.CellRendererText()
- cell_capacity.set_property('ellipsize', Pango.EllipsizeMode.END)
- column_name = Gtk.TreeViewColumn(_('Capacity'), cell_capacity)
- column_name.set_cell_data_func(cell_capacity, column_data_func, 2)
- column_name.set_sizing(Gtk.TreeViewColumnSizing.AUTOSIZE)
- column_name.set_resizable(True)
- column_name.set_expand(False)
- column_name.set_min_width(75)
- self.dest_treeview.append_column(column_name)
-
- cell_free = Gtk.CellRendererText()
- cell_free.set_property('ellipsize', Pango.EllipsizeMode.END)
- column_name = Gtk.TreeViewColumn(_('Free Space'), cell_free)
- column_name.set_cell_data_func(cell_free, column_data_func, 3)
- column_name.set_sizing(Gtk.TreeViewColumnSizing.AUTOSIZE)
- column_name.set_resizable(True)
- column_name.set_expand(False)
- column_name.set_min_width(75)
- self.dest_treeview.append_column(column_name)
+ if not self.fastboot_mode:
+ cell_name = Gtk.CellRendererText()
+ cell_name.set_property('ellipsize', Pango.EllipsizeMode.END)
+ column_name = Gtk.TreeViewColumn(_('Label'), cell_name)
+ column_name.set_cell_data_func(cell_name, column_data_func, 1)
+ column_name.set_sizing(Gtk.TreeViewColumnSizing.AUTOSIZE)
+ column_name.set_resizable(True)
+ column_name.set_expand(True)
+ column_name.set_min_width(75)
+ self.dest_treeview.append_column(column_name)
+
+ cell_capacity = Gtk.CellRendererText()
+ cell_capacity.set_property('ellipsize', Pango.EllipsizeMode.END)
+ column_name = Gtk.TreeViewColumn(_('Capacity'), cell_capacity)
+ column_name.set_cell_data_func(cell_capacity, column_data_func, 2)
+ column_name.set_sizing(Gtk.TreeViewColumnSizing.AUTOSIZE)
+ column_name.set_resizable(True)
+ column_name.set_expand(False)
+ column_name.set_min_width(75)
+ self.dest_treeview.append_column(column_name)
+
+ cell_free = Gtk.CellRendererText()
+ cell_free.set_property('ellipsize', Pango.EllipsizeMode.END)
+ column_name = Gtk.TreeViewColumn(_('Free Space'), cell_free)
+ column_name.set_cell_data_func(cell_free, column_data_func, 3)
+ column_name.set_sizing(Gtk.TreeViewColumnSizing.AUTOSIZE)
+ column_name.set_resizable(True)
+ column_name.set_expand(False)
+ column_name.set_min_width(75)
+ self.dest_treeview.append_column(column_name)
def add_file_source_dialog(self, *args):
filename = ''
chooser = Gtk.FileChooserDialog(title=None,action=Gtk.FileChooserAction.OPEN,
buttons=(Gtk.STOCK_CANCEL,Gtk.ResponseType.CANCEL,Gtk.STOCK_OPEN,Gtk.ResponseType.OK))
- for p, n in (('*.iso', _('CD Images')), ('*.img', _('Disk Images'))):
+ def _add_filter(p, n):
filter = Gtk.FileFilter()
filter.add_pattern(p)
filter.set_name(n)
chooser.add_filter(filter)
+
+ if not self.fastboot_mode:
+ _add_filter('*.iso', _('CD Images'))
+ _add_filter('*.img', _('Disk Images'))
+
folder = os.path.expanduser('~')
chooser.set_current_folder(folder)
response = chooser.run()
@@ -599,6 +638,9 @@
source = self.get_source()
target = self.get_target()
persist = self.get_persistence()
+ if self.fastboot_mode and not misc.check_eula():
+ if self.show_eula() == Gtk.ResponseType.CANCEL:
+ return
# TODO evand 2009-07-31: Make these the default values in the
# GtkBuilder file.
starting_up = _('Starting up...')
@@ -610,8 +652,10 @@
self.unity.show_progress()
self.delete_timeout(self.update_loop)
try:
- self.backend.install(source, target, persist,
- allow_system_internal=self.allow_system_internal)
+ self.backend.install(
+ source, target, persist,
+ allow_system_internal=self.allow_system_internal,
+ fastboot_mode=self.fastboot_mode)
except:
self._fail()
@@ -663,6 +707,12 @@
retry_dialog.destroy()
return response == Gtk.ResponseType.YES
+ def show_eula(self, unused=None):
+ response = self.eula_dialog.run()
+ if response == Gtk.ResponseType.OK:
+ misc.check_eula(True)
+ self.eula_dialog.hide()
+ return response
def quit(self, *args):
self.backend.cancel_install()
@@ -706,6 +756,10 @@
except dbus.DBusException:
logging.exception('Error checking for kvm:')
+ if self.fastboot_mode:
+ self.finished_dialog_label.set_text(
+ _('Installation is complete. Your device is rebooting into Ubuntu Core.'))
+ self.kvm_test.hide()
self.finished_dialog.run()
self.backend.shutdown()
Gtk.main_quit()
=== modified file 'usbcreator/install.py'
--- usbcreator/install.py 2012-05-04 10:35:51 +0000
+++ usbcreator/install.py 2013-01-24 17:05:29 +0000
@@ -26,6 +26,7 @@
from threading import Thread, Event
import logging
from hashlib import md5
+import time
if sys.platform != 'win32':
from usbcreator.misc import MAX_DBUS_TIMEOUT
@@ -65,13 +66,15 @@
class install(Thread):
def __init__(self, source, target, persist, device=None,
- allow_system_internal=False):
+ allow_system_internal=False,
+ fastboot_mode=False):
Thread.__init__(self)
self.source = source
self.target = target
self.persist = persist
self.device = device
self.allow_system_internal = allow_system_internal
+ self.fastboot_mode = fastboot_mode
self._stopevent = Event()
self.progress_thread = None
logging.debug('install thread source: %s' % source)
@@ -137,7 +140,13 @@
if ext not in ['.iso', '.img']:
self._failure(_('The extension "%s" is not supported.') %
ext)
- if ext == '.iso':
+ if self.fastboot_mode:
+ self.bootimg = os.path.splitext(self.source)[0] + '.bootimg'
+ if not os.path.isfile(self.bootimg):
+ self._failure(_('Missing matching "%s" for source image %s.') %
+ (self.bootimg, self.source))
+ self.fastboot_install()
+ elif ext == '.iso':
if sys.platform == 'win32':
self.cdimage_install()
else:
@@ -394,6 +403,31 @@
except dbus.DBusException:
self._failure(failure_msg)
+ def _fastboot_command(self, cmd):
+ fastboot_cmd = ['fastboot', '-s', self.target]
+ fastboot_cmd.extend(cmd)
+ popen(fastboot_cmd)
+
+ def fastboot_install(self):
+ self.progress(0, 3*60+9, True)
+ self.progress_message(_('Erasing boot partition...'))
+ self._fastboot_command(['erase', 'boot'])
+ self.progress(5, 3*60+7, True)
+ self.progress_message(_('Erasing user partition...'))
+ self._fastboot_command(['erase', 'userdata'])
+ self.progress(10, 3*60+5, True)
+ self.progress_message(_('Flashing boot partition...'))
+ self._fastboot_command(['flash', 'boot', self.bootimg])
+ self.progress(15, 3*60+3, True)
+ self.progress_message(_('Flashing user partition...'))
+ self.progress_pulse()
+ self._fastboot_command(['flash', 'userdata', self.source])
+ self.progress_pulse_stop()
+ self.progress(95, 1, True)
+ self.progress_message(_('Rebooting device...'))
+ self._fastboot_command(['reboot'])
+ self.progress(100, 0, True)
+
def cdimage_install(self):
# Build.
=== modified file 'usbcreator/misc.py'
--- usbcreator/misc.py 2012-11-09 01:23:47 +0000
+++ usbcreator/misc.py 2013-01-24 17:05:29 +0000
@@ -35,6 +35,8 @@
MAX_LOG_SIZE = 1024 * 1024 * 1
MAX_LOG_BACKUP = 0
+EULA_STAMP = '.ubuntu-nexus7-installer.notice-accepted'
+
if sys.platform != 'win32':
# TODO xnox 20121109 should not hard-code timeouts, instead should
# do async dbus calls with a qt or glib main loop running.
@@ -78,6 +80,13 @@
log.addHandler(handler)
log.setLevel(logging.DEBUG)
+def check_eula(save=False):
+ eula_stamp = os.path.expanduser('~/' + EULA_STAMP)
+ if save:
+ with open(eula_stamp, 'w') as f:
+ pass
+ return os.path.isfile(eula_stamp)
+
def format_size(size):
"""Format a partition size."""
# Taken from ubiquity's ubiquity/misc.py