Compare commits

..

187 Commits

Author SHA1 Message Date
1e2da51172 Merge branch 'ics' of github.com:CyanogenMod/android_bootable_recovery into ics 2012-06-07 11:58:13 +01:00
Evan McClain
8ba9a6335b Fix build on gcc 4.6.
Several programs were not linked against libcrecovery which has the __system
function.

Change-Id: I12b33a9157ab74825129896d0f2177fa83638464
Signed-off-by: Evan McClain <aeroevan@gmail.com>
2012-05-18 01:28:26 -04:00
eaut
9a7615326e use TARGET_RECOVERY_FSTAB location if defined
If TARGET_RECOVERY_FSTAB is defined use this location to find
recovery.fstab

Change-Id: Ic4cd26f5be064586359f39ff82d7f9b09ce57f53
2012-05-06 11:14:41 +02:00
Koushik Dutta
08bedb21d8 remove copyright, switch to AOSP license
Change-Id: I53485386d68726f5c0596ac842e6a480d4463b74
2012-04-10 13:23:50 -07:00
Koushik Dutta
7ba8a30150 Merge pull request #21 from IEF/ics
Fix BCB clearing for eMMC devices.
2012-04-09 09:34:19 -07:00
IEF
21b8a12300 Always call set_bootloader_message(), not just for MTD-devices. set_bootloader_message has a built-in check for MTD/eMMC via fstab. 2012-03-07 16:50:26 +01:00
Robert Burns
d87b8df56d Remove random offset message during installation
Change-Id: I2281a571e37ba9fac2b99806ce9c63e591b4d39f
2012-02-13 16:18:53 -05:00
Koushik Dutta
1c50ff29e6 Fix ui menu bug for long menus.
Change-Id: If009dee6b7597daeec62dd65baa7ad35e1adec5d

Conflicts:

	ui.c
2012-01-31 20:28:36 -08:00
Koushik Dutta
a465962667 use source built e2fsprogs! thanks cvpcs!
Change-Id: Id3067d4da53643ae1af0b9f15445262afda7b197
2012-01-30 22:51:36 -08:00
Koushik Dutta
e2a66586a3 fix up key value parsing
Change-Id: I05e821cd1215c44be780694644e568676fd67565
2012-01-29 14:03:04 -08:00
Koushik Dutta
10034aabc9 Merge "Always run adbd as root in recovery." into ics 2012-01-28 09:26:53 +03:00
Koushik Dutta
638103922f more derpage
Change-Id: I878386195a408d2a98137816515f5eaaa52ccf79
2012-01-27 02:58:40 -08:00
Koushik Dutta
67e73e1559 fix build
Change-Id: Iac099f5a275b9633ed30d9e4a84acb99a57c4434
2012-01-27 02:46:19 -08:00
Koushik Dutta
3cdfd138fa Various fixes to fix rendering of text. There will always be 3 lines of log shown. The menu can have long items in it now, rather than being truncated. The log text will be bottom aligned.
Change-Id: I09289e053c8ab673814318da55302efaab0404de

derp

Change-Id: I3fc31f5ea311c73c0ec999aa77d3fa0d01238001
2012-01-26 22:56:33 -08:00
Koushik Dutta
ccc1fdb386 derp
Change-Id: I5ffece3af80c0c328c61975d46f4de4cb22f2282
2012-01-26 16:49:58 -08:00
Koushik Dutta
18e3f62ad2 Fix up the mess around fonts and defines.
Change-Id: I3df3dae482ac6f8e9ddcbe2946dba43428bf46b1
2012-01-26 16:49:33 -08:00
Koushik Dutta
b20a4812ba reversed the logic
Change-Id: I62c104ee0c9218f929c10eda31f4bf5828b0de22
2012-01-26 15:29:08 -08:00
Danesh Mondegarian
5617056cb8 Recovery : Show menu if in non user initiated mode and error occurred
When using rom manager and applying a zip, if one encounters an error in recovery,
they're left on a screen with no visible controls (Forcing to hard reset phone).

Change-Id: Ia9b2f396fc95c7972a5a5580e1a50adf4af26060
2012-01-26 15:20:57 -08:00
Pawit Pornkitprasan
aa3c3d429b Respect volume length when formatting ext4 when restoring
This is needed for device encryption to work properly (there must
be space for a 16 KB footer at the end of the partition, which is
usually specified by the length option).

And yes, the old signature of make_ext4fs was wrong, but worked
anyway because the related header was not included and the compiler
let it pass an as implicit delcaration.

Change-Id: Ied7ec70bebc120cc2917771f59eeaeb7ea76bf8d
2012-01-26 15:16:53 -08:00
Koushik Dutta
cd3705e4ab remove power off. not useful in the main menu.
Change-Id: I8923d1e878994c3516798118961b4cdaa82ddc88
2012-01-26 15:09:08 -08:00
CEnnis91
4f78176329 Misc tweaks / bug fixes
- readd "power off" to the main menu
- fix bug where stdout overflows into menu text
- remove +++++Go Back+++++ from main menu as there is nothing to go back to (detects menu depth)

Change-Id: Icb84ac86e55712412d07add0ab76955d7902f07c
2012-01-26 15:08:15 -08:00
CEnnis91
de338e56b3 Big Font Mod and Roboto Fonts (XHDPI, HDPI, and MDPI)
- lets xhdpi devices (Galaxy Nexus, Xoom, etc) have a bigger font size (15x24)
- port Google's Roboto font into recovery for both XHDPI, HDPI, and MDPI font size, make them optional (LDPI is too small!)

(credits to gweedo767 for big font)

Change-Id: I621dbc7c8ac30a8f16039ce64720512e3e63881a
2012-01-26 14:57:07 -08:00
Koushik Dutta
5a44ceb692 remove hacky board define around usb storage mounting on /data/media devices.
Change-Id: I2d382762271a2cfc6d83454160ed127b7457c88c
2012-01-26 14:56:56 -08:00
Koushik Dutta
4c8e2482a6 Who approves this stuff... use get_volume_for_path('/sdcard') and check for null...
Revert "Hide "mount USB storage" option from mount menu when the board has a virtual sdcard"

This reverts commit e510810c71b5d4eb4d779c0db2d131d2b1b556af.
2012-01-26 14:47:34 -08:00
Mike Kasick
059db9bfb6 Always run adbd as root in recovery.
At present, invoking "adb shell" while in recovery results in:

- exec '/system/bin/sh' failed: No such file or directory (2) -

"adb shell" should invoke /sbin/sh, but cannot as /sbin and /sbin/recovery
lack other-user execute permission.  Invoking "adb root" to restart adbd as
root _does_ work, however this behavior may not be intuitive to users who
encounter the above error.

The solution implemented here is to always run adbd as root in recovery, so
it has permission to run /sbin/sh.  Furthemore, user shells in recovery are
not particularly useful and "su" doesn't exist, thus "adb root" is likely
to be invoked anyways.

Change-Id: Iaaa25090e85d970e9a076fef068f5fae8202ab0b
2012-01-26 16:05:56 -05:00
CEnnis91
e510810c71 Hide "mount USB storage" option from mount menu when the board has a virtual sdcard
Change-Id: I4e59768e9f34f0fb33d88ad382feaa2515d70bc4
2012-01-15 02:37:34 -05:00
4e50004a0e fix yes/no issue where the index is 0 and not 7 2012-01-13 14:16:03 +00:00
d43f5a01bf merge, and fix extendedcommands.c for yes/no 2012-01-11 11:10:07 +00:00
Koushik Dutta
9487d2965f add comments around /data/media
Change-Id: I35ad822ed602e2b1018f1e1a0d67499867b60a40
2011-12-18 13:49:52 -08:00
Koushik Dutta
d4c04cb00b Merge branch 'ics' of git://github.com/CyanogenMod/android_bootable_recovery into ics 2011-12-18 13:40:30 -08:00
Koushik Dutta
e9039792c9 5.5.04
Change-Id: Idb2f70a8a02d2f9418356f011c9392f8d9b1d1d2
2011-12-18 11:53:08 -08:00
Prashant Somashekar
f0c389ddcd nandroid/root/extendedcommands: attenuate for /data not being auto in fstab
Change-Id: I0e7bec03bb29f1ae72f23321f89cf704e54ff4d9
2011-12-18 02:52:30 -05:00
Prashant Somashekar
357a2f5109 extendedcommands/nandroid: remove internal options if no sdcard and is_data_media
-force /data as backup_path if volume for /sdcard is null and the same is true

Change-Id: I927b723cde5b519d81402c6d841f2424627253e8

Conflicts:

	nandroid.c
2011-12-18 02:52:21 -05:00
Steve Kondik
db524c28b4 Merge "Fix wipe from android settings for devices with /datadata" into ics 2011-11-30 08:14:02 +03:00
Koushik Dutta
a64c697333 Fix up the autoinclusion rules for the recoveryimage target. 2011-11-27 14:07:29 -08:00
Pawit Pornkitprasan
1659814576 Fix wipe from android settings for devices with /datadata
Change-Id: I2d80d580bc2ccdc756f411dbe514270d5c245816
2011-11-26 22:44:29 +07:00
Koushik Dutta
a9017dabc5 remove redundant fix 2011-11-23 14:07:06 -08:00
Koushik Dutta
ddc1241a36 fix missing prebuilts in recovery. mmc bootloader message support. fix segfault happening due to C structs not being zeroed out. 2011-11-23 14:06:26 -08:00
Ricardo Cerqueira
edae7a5b0f Merge "recovery: fix non-MTD mounting (uninitialized variables)" into ics 2011-11-22 21:45:36 +03:00
Chris41g
d2eecca360 Update extendedcommands.c one "No". 2011-11-21 14:37:29 -08:00
Koushik Dutta
d280f6e0d8 rewrite mtd_restore_raw_partition to use the new aosp code 2011-11-21 11:22:04 -08:00
Pawit Pornkitprasan
ff316eb739 recovery: fix non-MTD mounting (uninitialized variables)
Mounting failed due to invalid (garbage) fs_options
2011-11-19 13:31:21 +07:00
Koushik Dutta
21ad8d04dd remove dedupe 2011-11-16 18:28:20 -08:00
Koushik Dutta
0e7d88613a Support custom graphics.c. Set the recovery timeout to 1 hour. 2011-11-16 16:47:53 -08:00
Koushik Dutta
0df56f4db4 wip 2011-11-16 16:00:35 -08:00
Dima Zavin
441031dadc minui: add ability to synchronize current key state
If a key is down prior to the time of initialization, we would not get the
down event for the key, and thus think that the key is not pressed.

Add an interface that allows one to provide a callback to execute
on all keys that are currently down.

Change-Id: I2a4096c0cb4c7c7a9a80d207835f168a0b418413
Signed-off-by: Dima Zavin <dima@android.com>
2011-10-12 15:53:32 -07:00
Doug Zongker
f6abd409bb fix problem where the screen is sometimes all black in recovery
Change-Id: Ifa0b59e43eaf0bea9435aa4d96c5b0fc4f10fbfe
2011-09-27 13:09:48 -07:00
Doug Zongker
fdfb636336 update recovery with new 3D images
Change-Id: I6d52fd1db27fdf1b61f41f598a2209b70385b106
2011-09-20 14:16:46 -07:00
Dima Zavin
88e0899617 minui: events: only open input devices with EV_KEY and/or EV_REL
Change-Id: I8283d7aaa0f66d488f462cd108350cc49657a745
Signed-off-by: Dima Zavin <dima@android.com>
2011-09-02 14:55:20 -07:00
Dima Zavin
365836736c minui: events: add ability to poll on non-input fds
Change-Id: Iad52a6f2adcae0068d252d6163586f9d7b93121d
Signed-off-by: Dima Zavin <dima@android.com>
2011-09-02 14:55:20 -07:00
Dima Zavin
bc29063bf4 minui: events: refactor event acquisition
Events are now delivered through a callback mechanism during
a call to ev_dispatch(). This will allow us to extend the events
code to handle other devices/fds, not just input. One such example
is the ability to process uevents.

During initialization, we provide an input callback to ev_init
that gets called when a new event is encountered during dispatch.

ev_get has been removed and replaced with ev_get_input() helper
function that can be called from inside the callback to attempt
to get an input event.

The existing client of ev_get in recovery has been split up such
that the input thread just calls ev_wait(); ev_dispatch(); and
the input_callback handles individual events by using the
ev_get_input() helper.

Change-Id: I24d8e71bd1533876b4ab1ae751ba200fea43c049
Signed-off-by: Dima Zavin <dima@android.com>
2011-09-02 14:55:20 -07:00
Dima Zavin
4daf48a10b minui: graphics: add interface for framebuffer blank/unblank
Change-Id: I5c3ee61cbf6fadae50f10b9f2e73caceaa5048a7
Signed-off-by: Dima Zavin <dima@android.com>
2011-08-30 11:59:20 -07:00
Dima Zavin
3c7f00ede6 minui: graphics: add ability to query font size
Change-Id: I5e8f477b7b205794f2975f12e6b6010c177f6052
Signed-off-by: Dima Zavin <dima@android.com>
2011-08-30 11:58:24 -07:00
Doug Zongker
c2ddaea83a change recovery images to match blue holo theme
Change-Id: I912d3ab32973c5c5e7b6b1749698f8a71d884fa3
2011-08-19 16:56:31 -07:00
Michael Ward
6242a8bc9b Support multiple recovery updater extensions.
Change-Id: I787c086223b674050c0a12fc575add9badb471af
2011-07-14 15:12:20 -07:00
Doug Zongker
8918673cf7 Merge "Check pointer for null before dereferencing" 2011-07-13 15:42:09 -07:00
Adam Bliss
b2ceb696d0 Check pointer for null before dereferencing
Change-Id: Ie7563bf8fb2d627454010de7388d0992e2accf91
2011-07-13 15:24:38 -07:00
Benoit Goby
8d92ae052e Merge "Update usb_connected() to support new gadget driver" 2011-07-12 15:39:11 -07:00
Benoit Goby
7e6067e36c Update usb_connected() to support new gadget driver
Change-Id: Iabe8be5bbfa7d2bf1d13280c8734ff75b62a152f
2011-07-12 12:38:46 -07:00
Jeff Brown
b0462e6ae2 Remove the simulator target from all makefiles.
Bug: 5010576

Change-Id: Ib465fdb42c8621899bea15c04a427d7ab1641a8c
2011-07-11 22:11:45 -07:00
Michael Ward
933487868f Add missing commands to recovery init.rc
Wrote some missing items in recovery, most notably the serial number so that it shows up correctly on adb.

Change-Id: If430c0b78191c8d77f781aa605b5081571451775
2011-07-07 13:29:43 -07:00
Mike Lockwood
718a2f7872 init.rc: Simplify logic for starting adbd in recovery
Always start adbd if ro.debuggable=1 rather than basing it on user preference
in persistent system properties.

Use new D001 product ID, which I just allocated for "android recovery mode"

Change-Id: I6f1eac5257eaad2e538c0a8dd549ad89219efa3e
Signed-off-by: Mike Lockwood <lockwood@android.com>
2011-06-29 10:22:04 -04:00
Michael Ward
9d2629c1c4 Allow applying an OTA package manually from cache.
Change-Id: I8f78377555c658a992ca95cadf11b67ddc93fed8
2011-06-24 11:53:58 -07:00
Michael Ward
3dbe66b71d Get the correct line_length.
Set the BPP and other fields and write it back, so the line_length comes back correctly.

Change-Id: I85e4e8223c79b9394ae1fb609b3026de62027ab8
2011-06-24 11:06:01 -07:00
Doug Zongker
fb04b87002 fix adb root in recovery
recovery's init.rc was missing lines that made adb root work.

Change-Id: I300e6997e3b5cb9c7b542b2012eed61deb2550f1
2011-06-23 15:30:34 -07:00
Michael Ward
9d1bcdf7b8 Graphics can handle stride != xres, and BGRA support.
Change-Id: Ifee94ac08028e62a40241a089ac7c36346fea3a3
2011-06-22 15:04:00 -07:00
Mike Lockwood
7e58b65efb Fix starting adb in recovery mode
Change-Id: I8444f44d3194ff16ce54121633d5b255231393f5
Signed-off-by: Mike Lockwood <lockwood@android.com>
2011-06-19 02:52:01 -04:00
Jean-Baptiste Queru
5a4e03d120 am f84b2524: am 6ebedf00: am 82da01d6: Merge from gingerbread
* commit 'f84b25243d7ebeaca8424171f5ca3b192cc76d80':
2011-06-08 14:47:00 -07:00
Jean-Baptiste Queru
7f72ad7934 am a94d9548: am 1117c69f: am 7172eb7b: Merge "Mute unharmful build warning at the top of the build log:" into gingerbread
* commit 'a94d954862fab26f6159ed7bb836ba6758a569fd':
  Mute unharmful build warning at the top of the build log:
2011-06-08 14:46:59 -07:00
Jean-Baptiste Queru
f84b25243d am 6ebedf00: am 82da01d6: Merge from gingerbread
* commit '6ebedf0053ccefd414e5887db316f84bd8f6c44c':
2011-06-07 13:23:26 -07:00
Jean-Baptiste Queru
a94d954862 am 1117c69f: am 7172eb7b: Merge "Mute unharmful build warning at the top of the build log:" into gingerbread
* commit '1117c69fe40dccfa6090d184094c4a6d407ab8d6':
  Mute unharmful build warning at the top of the build log:
2011-06-07 13:22:51 -07:00
Jean-Baptiste Queru
6ebedf0053 am 82da01d6: Merge from gingerbread
* commit '82da01d6a32c4fbfe57155c119d4669d7faba438':
2011-06-01 14:23:11 -07:00
Jean-Baptiste Queru
82da01d6a3 Merge from gingerbread
Change-Id: I30902cdb19698f88a1ea57cf8c7667ef867d13a8
2011-06-01 14:08:15 -07:00
Jean-Baptiste Queru
1117c69fe4 am 7172eb7b: Merge "Mute unharmful build warning at the top of the build log:" into gingerbread
* commit '7172eb7b623f4b30f5a709d639fcd3fb51cd6220':
  Mute unharmful build warning at the top of the build log:
2011-06-01 08:06:14 -07:00
The Android Open Source Project
28a08efe15 Reconcile with honeycomb-release
Change-Id: I1205ca405fdaf586ebc349fbe83969e9694fab60
2011-05-20 12:45:51 -07:00
The Android Automerger
e44b41a770 am c2a158db: Merge remote branch \'goog/honeycomb-mr2\' into honeycomb-LTE
* commit 'c2a158db9588e6ad290dd0f9171a190609900387':
  delay accessing misc partition until its device exists
2011-05-09 10:53:22 -07:00
The Android Automerger
c2a158db95 Merge remote branch 'goog/honeycomb-mr2' into honeycomb-LTE 2011-05-08 22:31:27 -07:00
Doug Zongker
c636b7300b am 90588820: delay accessing misc partition until its device exists
* commit '90588820b7110acf142d17457f0d10cd7cb57a8a':
  delay accessing misc partition until its device exists
2011-05-04 12:46:12 -07:00
Doug Zongker
90588820b7 delay accessing misc partition until its device exists
When the misc partition is on an emmc device, recovery can get started
and try to access it before the kernel has actually created the
device.  Try statting the device before reading or writing it; delay
up to 10 seconds waiting for the device to exist.

Change-Id: I93256db4b047c76020490e8a3dc76b8ade643291
2011-05-04 11:17:35 -04:00
Doug Zongker
f4bb554ee9 delay accessing misc partition until its device exists
When the misc partition is on an emmc device, recovery can get started
and try to access it before the kernel has actually created the
device.  Try statting the device before reading or writing it; delay
up to 10 seconds waiting for the device to exist.

Change-Id: I988442d5701394d7152bfab3c571e7548c364f61
2011-05-04 11:07:48 -04:00
Doug Zongker
cfd256a332 delay accessing misc partition until its device exists
When the misc partition is on an emmc device, recovery can get started
and try to access it before the kernel has actually created the
device.  Try statting the device before reading or writing it; delay
up to 10 seconds waiting for the device to exist.

Change-Id: Ib9bf6c35fa2c28fc43aa7550aaaffb76c9f6e120
2011-04-22 09:33:14 -07:00
Doug Zongker
179b2d9895 make write_raw_image able to take a blob
write_raw_image() can now take either a blob or a filename as the
source.  The blob format eliminates the need for a temp file.

Change-Id: I0c6effec53d47862040efcec75e64b7c951cdcf7
2011-04-12 16:48:49 -07:00
Doug Zongker
469243e536 save a last_install file with the result of the last package install attempt
When installing a package, create /cache/recovery/last_install, which
contains the filename of the package and a 1 or 0 for success or
failure.

Also, don't mount ext4 and vfat filesystems as read-only (on devices
where /cache is ext4, we need it to be read-write).

Change-Id: I0cf2a1921bbd65e06343aa74e2006577fac77c2c
2011-04-12 09:28:10 -07:00
Doug Zongker
3ed8e18721 am 4762633c: log which key a package verified against in recovery
* commit '4762633cf846d17516878303502b056b52353a5d':
  log which key a package verified against in recovery
2011-03-15 13:47:23 -07:00
Doug Zongker
4762633cf8 log which key a package verified against in recovery
Change-Id: I0d91b715d1eb9e45e2fce54bb93ba0abef92727e
2011-03-15 12:11:08 -07:00
Iliyan Malchev
201aa88cba recovery: mount /sdcard read-only
Change-Id: Ieffafe00cf82620057cacd0629cb60b0e6aad817
Signed-off-by: Iliyan Malchev <malchev@google.com>
2011-03-11 16:47:53 -08:00
Ken Sumrall
90415aca67 am 6e4472ab: Have recovery reboot using the new android_reboot() function.
* commit '6e4472abbd3c7be9cd31d98a03df1e3b6fa92f40':
  Have recovery reboot using the new android_reboot() function.
2011-03-10 19:44:38 -08:00
Ken Sumrall
6e4472abbd Have recovery reboot using the new android_reboot() function.
The new android_reboot() function is a nicer way to reboot the
system.  I can optionally sync() and remount read-only writable
filesystems.  This fixes bug 3350709.

Change-Id: Ic4c8676debd642e57bce3107b99dd810d90b6f82
2011-03-10 19:30:13 -08:00
Doug Zongker
f66088d2ce am 6ce4a326: don\'t reboot for inactivity if USB is connected
* commit '6ce4a326efae4abb108e19899f4d7776abc362da':
  don't reboot for inactivity if USB is connected
2011-03-08 23:53:35 -08:00
Doug Zongker
6ce4a326ef don't reboot for inactivity if USB is connected
(Cherry-pick back from master.)

Bug: 4071007
Change-Id: I28355c593770df678968185171bdd19dabe7f062
2011-03-08 17:51:14 -08:00
Doug Zongker
4cc533dd1c don't reboot for inactivity if USB is connected
Change-Id: Icba35da91167d30c446581afb47d0804e49964bf
2011-03-08 12:25:05 -08:00
Doug Zongker
b70fe3f76a am 68189f29: allow paletted RGB images in recovery
* commit '68189f2994690538b6e3bddc3788cb092cbda088':
  allow paletted RGB images in recovery
2011-03-07 15:47:04 -08:00
Doug Zongker
68189f2994 allow paletted RGB images in recovery
Recovery assumes any paletted images are in RGBA format.  Make it
handle both RGB and RGBA paletted images.

Bug: 3514884
Change-Id: I517cd571aa3f434dacacc33a774236260aec20ef
2011-03-04 17:13:16 -08:00
Eric Fischer
7e69e2cccc Merge branch 'master' of ssh://android-git:29418/platform/bootable/recovery 2011-03-04 00:29:22 -08:00
Doug Zongker
73bb6f749f convert recovery images to palettized PNGs
Cuts the byte size of the recovery images in half, roughly.

Change-Id: I3c45b5e58423b57faca83fc67b4e24e8d643c5b1
2011-03-03 16:52:06 -08:00
Doug Zongker
b7c91766da convert recovery images to palettized PNGs
Cuts the byte size of the recovery images in half, roughly.

Change-Id: I453a499e9937163c545dab3c552201882766e218
2011-03-03 14:43:13 -08:00
Doug Zongker
be6d4d1052 change the default recovery assets to be in holograph style
Also remove the weird backwards compatibility thing for animations
with fewer than 10 frames.  Frames are always named "name01.png",
"name02.png", ..., no matter how many there are.

Change-Id: I7af64fdec1bfcdb0464998b735ec8d6c626ffe9d
2011-03-02 10:38:02 -08:00
Doug Zongker
6809c51f8d make recovery UI images more general; allow for installation animation
Change some of the UI parameters (# of indeterminate progress bar
frames, fps, etc.) from #defined constants to variables that can be
set by the device-specific recovery_ui code (via a new function).

Support overlaying different images on top of the base installation
icon to animate it.  Make the FPS control more accurate.

Change-Id: I9268b389b7ea6b3ed9e0c7eae37baf4272e60edd
2011-03-01 14:04:34 -08:00
Doug Zongker
c007b961d7 am 8d43d940: am 2c273f00: store partition length in recovery.fstab
* commit '8d43d94065e88e00e1460841b43c7de584ee5585':
  store partition length in recovery.fstab
2011-02-24 20:35:19 -08:00
Doug Zongker
ee458bbf9b store partition length in recovery.fstab
Don't hardcode magical partition behavior in roots.c.

Change-Id: I587fc2c066575b51c11efd2e45a50f5b864df484
2011-02-24 18:46:44 -08:00
Doug Zongker
8d43d94065 am 2c273f00: store partition length in recovery.fstab
* commit '2c273f004e0504ae0389ad160ed2a92624873189':
  store partition length in recovery.fstab
2011-02-24 18:38:48 -08:00
Doug Zongker
2c273f004e store partition length in recovery.fstab
Don't hardcode magical partition behavior in roots.c.

Change-Id: I587fc2c066575b51c11efd2e45a50f5b864df484
2011-02-24 18:34:36 -08:00
Doug Zongker
2810ceda34 store partition length in recovery.fstab
Don't hardcode magical partition behavior in roots.c.

Change-Id: I587fc2c066575b51c11efd2e45a50f5b864df484
2011-02-17 15:55:21 -08:00
Ying Wang
4c05d95112 Fix x86 build.
Change-Id: Iada6268b0a72ee832113ea397334cc7950a37051
2011-02-08 19:51:07 -08:00
Doug Zongker
6da1abbc38 am 5df22d03: am 5cae445e: make recovery reboot after 2 minutes of no activity
* commit '5df22d03d2e7c6de213d83a58e0af39c42f839ca':
  make recovery reboot after 2 minutes of no activity
2011-01-25 13:56:07 -08:00
Doug Zongker
5df22d03d2 am 5cae445e: make recovery reboot after 2 minutes of no activity
* commit '5cae445e43c5928daba0a76745b0dd2657274eda':
  make recovery reboot after 2 minutes of no activity
2011-01-25 13:53:52 -08:00
Doug Zongker
5cae445e43 make recovery reboot after 2 minutes of no activity
If recovery sits for 2 minutes in prompt_and_wait(), and you've never
turned the screen on via the magic keypress, go ahead and reboot.  (We
used to assume that the user could pull the battery to get out of this
state, but on devices with nonremovable batteries...)

If you've ever enabled display of the log/menu since recovery started,
we assume you know what you're doing and will stay in recovery until
you choose to reboot.

Bug: 3387873
Bug: 3387274
Change-Id: I041621e5db132df9a925e6808845a7c45e1b427a
2011-01-25 13:50:16 -08:00
Doug Zongker
80abd51dbc am da993fcf: am 8d58c957: Merge "Free allocated struct after freeing field"
* commit 'da993fcf2665102435b05d6b20a4c4e8f8bd3b8f':
  Free allocated struct after freeing field
2011-01-21 16:15:02 -08:00
Doug Zongker
da993fcf26 am 8d58c957: Merge "Free allocated struct after freeing field"
* commit '8d58c957036835db148acc4e506633a016dc6c7e':
  Free allocated struct after freeing field
2011-01-21 16:12:03 -08:00
Doug Zongker
1966aaf4e6 Merge "remove encrypted filesystem code from recovery" 2011-01-21 13:12:30 -08:00
Doug Zongker
8d58c95703 Merge "Free allocated struct after freeing field" 2011-01-20 07:06:02 -08:00
Ken Sumrall
8f132ed870 Reserve the last 16 Kbytes of /data for the crypto footer.
When formatting /data, if it's an ext4 filesystem, reserve the
last 16 Kbytes for the crypto footer.

Change-Id: I7b401d851ee87732e5da5860df0287a1c331c5b7
2011-01-19 17:12:47 -08:00
Christian Lindeberg
862c83bb31 Free allocated struct after freeing field
Free allocated MtdReadContext after freeing buffer field in struct,
not before.

Change-Id: I237920dc36115389cd2d6948e7a962dbec22fe56
2011-01-19 12:22:41 +01:00
Doug Zongker
540d57f25a remove encrypted filesystem code from recovery
This was never used; encrypted filesystems are being done a different
way now.

Change-Id: I519c57b9be44d001f0b81516af7bfc252069892b
2011-01-18 13:36:58 -08:00
Doug Zongker
be3e6f13b8 option to allow recovery to use 24-bit graphics in UI
Add "RECOVERY_24_BIT := true" to the device's BoardConfig.mk to use
24-bit framebuffers in the recovery ui.

Change-Id: Iaede138bf7870becf237f12f1c0e49c9ff82d007
2011-01-13 16:43:44 -08:00
Colin Cross
49396b79b5 Update make_ext4fs arguments in roots.c
Change-Id: I835e55fb80add6a74cd4d99f77b2528829d9a349
2011-01-05 17:19:37 -08:00
Colin Cross
264f549b7d Update arguments to make_ext4fs
Change-Id: Id96e98da76b3091987b01651f980797b1d6b49d8
2010-12-29 14:18:26 -08:00
Doug Zongker
70f7e8dbf0 am c5ebf1fb: am 5d6309e7: fix comparison of ECC stats before and after mtd reads
* commit 'c5ebf1fba2f870a4e9453721112900975c18e083':
  fix comparison of ECC stats before and after mtd reads
2010-11-04 07:20:28 -07:00
Doug Zongker
c5ebf1fba2 am 5d6309e7: fix comparison of ECC stats before and after mtd reads
* commit '5d6309e77f6055a9aec062dd991d071054726ebb':
  fix comparison of ECC stats before and after mtd reads
2010-11-03 15:18:12 -07:00
Doug Zongker
02971af254 am 8521ef59: am 51266d13: clear recovery framebuffers on allocation; display icon right after ui_init
* commit '8521ef5965675da85c7bbbe9c8b86fe68716e855':
  clear recovery framebuffers on allocation; display icon right after ui_init
2010-11-01 10:40:33 -07:00
Doug Zongker
8521ef5965 am 51266d13: clear recovery framebuffers on allocation; display icon right after ui_init
* commit '51266d1397309978eac9b2e96035582454f0321b':
  clear recovery framebuffers on allocation; display icon right after ui_init
2010-11-01 10:38:12 -07:00
Doug Zongker
7c3ee270ce am 2d87023e: am 2c3539e4: save the log from recovery\'s last run in /cache/recovery/last_log
Merge commit '2d87023e77b20aa2196c8ceae833b33040b0dc57'

* commit '2d87023e77b20aa2196c8ceae833b33040b0dc57':
  save the log from recovery's last run in /cache/recovery/last_log
2010-09-30 11:25:31 -07:00
Doug Zongker
2d87023e77 am 2c3539e4: save the log from recovery\'s last run in /cache/recovery/last_log
Merge commit '2c3539e4d8251ad91e0b881253d39583680093e8' into gingerbread-plus-aosp

* commit '2c3539e4d8251ad91e0b881253d39583680093e8':
  save the log from recovery's last run in /cache/recovery/last_log
2010-09-29 13:46:06 -07:00
Doug Zongker
1a32732db2 am 704fa750: am 9b125b04: handle old-style CACHE: packages
Merge commit '704fa75024467fb4e362537f7c341eb056e283b5'

* commit '704fa75024467fb4e362537f7c341eb056e283b5':
  handle old-style CACHE: packages
2010-09-22 13:53:57 -07:00
Doug Zongker
704fa75024 am 9b125b04: handle old-style CACHE: packages
Merge commit '9b125b04c6ba8f07d8aa6494d58917a596443dc5' into gingerbread-plus-aosp

* commit '9b125b04c6ba8f07d8aa6494d58917a596443dc5':
  handle old-style CACHE: packages
2010-09-22 12:06:24 -07:00
Doug Zongker
6b26c882a8 am af78591c: am 2c3c5c15: Merge "mount sdcard only on demand; fix sideload installs" into gingerbread
Merge commit 'af78591c9a2aa8379c2d8528c31ea1eb813f6cae'

* commit 'af78591c9a2aa8379c2d8528c31ea1eb813f6cae':
  mount sdcard only on demand; fix sideload installs
2010-09-21 20:21:52 -07:00
Doug Zongker
af78591c9a am 2c3c5c15: Merge "mount sdcard only on demand; fix sideload installs" into gingerbread
Merge commit '2c3c5c15d15faf1c9fa074851c57d0afa2a40d28' into gingerbread-plus-aosp

* commit '2c3c5c15d15faf1c9fa074851c57d0afa2a40d28':
  mount sdcard only on demand; fix sideload installs
2010-09-21 20:01:51 -07:00
Doug Zongker
3d798835a3 am 8147ba85: (-s ours) am 93ca4fc6: use fs_type "emmc" instead of "block" for consistency (do not merge)
Merge commit '8147ba850b2e74dc950183e67c77a0da2b1a19b7'

* commit '8147ba850b2e74dc950183e67c77a0da2b1a19b7':
  use fs_type "emmc" instead of "block" for consistency (do not merge)
2010-09-21 14:46:43 -07:00
Doug Zongker
8147ba850b am 93ca4fc6: use fs_type "emmc" instead of "block" for consistency (do not merge)
Merge commit '93ca4fc6943a3ebf758c5db98531531b8fe92c98' into gingerbread-plus-aosp

* commit '93ca4fc6943a3ebf758c5db98531531b8fe92c98':
  use fs_type "emmc" instead of "block" for consistency (do not merge)
2010-09-21 14:37:10 -07:00
Doug Zongker
cc8cd3f3ca remove the notion of "root path"; support mixed flash types
Remove the wacky notion of "roots" and "root paths" (those things that
look like "FOO:some/path" instead of just "/foo/some/path").  Let each
device specify its own table of available partitions and how to mount
them (needed for devices that use both MTD/yaffs2 and EMMC/ext4
partitions).

(Cherrypicked from gingerbread w/slight edits.)

Change-Id: I2479ce76b13e73f1d12035c89386c3a82b3edf51
2010-09-21 14:13:45 -07:00
Doug Zongker
0f1ad110f8 am 3dba40da: (-s ours) am d4208f9f: remove the notion of "root path"; support mixed flash types (do not merge)
Merge commit '3dba40da1e533c6f419857e4274d9d9dd55868b6'

* commit '3dba40da1e533c6f419857e4274d9d9dd55868b6':
  remove the notion of "root path"; support mixed flash types (do not merge)
2010-09-21 11:38:21 -07:00
Doug Zongker
3dba40da1e am d4208f9f: remove the notion of "root path"; support mixed flash types (do not merge)
Merge commit 'd4208f9f9d4e9f268ba1888c1fe879ee73eb7e47' into gingerbread-plus-aosp

* commit 'd4208f9f9d4e9f268ba1888c1fe879ee73eb7e47':
  remove the notion of "root path"; support mixed flash types (do not merge)
2010-09-21 11:34:39 -07:00
Doug Zongker
c9ebb58623 resolved conflicts for merge of 40f0d3b4 to master
Change-Id: If14ab094a8bb11106b0ea7fdf8736e5e4c223089
2010-09-17 16:07:14 -07:00
Doug Zongker
40f0d3b4e0 am d7d42089: remove unneeded partition roots
Merge commit 'd7d4208976125d114d0b8e44438e2417d5275098' into gingerbread-plus-aosp

* commit 'd7d4208976125d114d0b8e44438e2417d5275098':
  remove unneeded partition roots
2010-09-17 13:30:15 -07:00
Brian Swetland
97e54ef573 am 1dcd2fd0: (-s ours) am 792b0071: do not merge - update to match ext4utils api
Merge commit '1dcd2fd0c7cc44cae279a5088241bdf15f084cb8'

* commit '1dcd2fd0c7cc44cae279a5088241bdf15f084cb8':
  do not merge - update to match ext4utils api
2010-09-15 19:49:56 -07:00
Brian Swetland
1dcd2fd0c7 am 792b0071: do not merge - update to match ext4utils api
Merge commit '792b00712bb1411d3b0583bcea95b43b3107fb95' into gingerbread-plus-aosp

* commit '792b00712bb1411d3b0583bcea95b43b3107fb95':
  do not merge - update to match ext4utils api
2010-09-15 18:07:22 -07:00
Doug Zongker
dc49ce453e add missing sparseness parameter
Change-Id: Ie6e309b127e80cd6475f1deaa5dbadf9f5cc2746
2010-09-15 18:05:10 -07:00
Doug Zongker
6c3e03b3c5 resolved conflicts for merge of 85bcf776 to master
Change-Id: Iab4f25702a5a62b9172f81fd543a8240a0e603c3
2010-09-15 17:51:50 -07:00
Doug Zongker
a66c32ab1d resolved conflicts for merge of 9f89b0e4 to master
Change-Id: Id458df96fd56830fdb35397e95a80274761ecff5
2010-09-15 17:40:14 -07:00
Doug Zongker
d7693c4c8e resolved conflicts for merge of 76445f3a to master
Change-Id: I658894dcaddbf0de428e3c51dbcdc306d3f47a52
2010-09-15 17:03:51 -07:00
Doug Zongker
6b1ff61f62 am 858f0a76: am 8e5e4dad: close update package before installing; allow remount
Merge commit '858f0a763d0f736eb721f54257b6164886bfcbfc'

* commit '858f0a763d0f736eb721f54257b6164886bfcbfc':
  close update package before installing; allow remount
2010-09-15 16:32:52 -07:00
Doug Zongker
4f69afdb63 am bd4bc088: am d12560aa: add the ability to seek to a raw location while reading MTD partition
Merge commit 'bd4bc088e286b87a5d1469598644125ecc0fd547'

* commit 'bd4bc088e286b87a5d1469598644125ecc0fd547':
  add the ability to seek to a raw location while reading MTD partition
2010-09-15 12:32:22 -07:00
Doug Zongker
85bcf776e1 am 8a8e6cc3: (cherry-pick) EMMC support in applypatch
Merge commit '8a8e6cc33cc0dcfe7e184b59d5ef1f1c29095509' into gingerbread-plus-aosp

* commit '8a8e6cc33cc0dcfe7e184b59d5ef1f1c29095509':
  (cherry-pick) EMMC support in applypatch
2010-09-15 11:17:34 -07:00
Doug Zongker
9f89b0e467 am 56c5105b: support for ext4/EMMC filesystems in updater binary
Merge commit '56c5105bd7096704eaed35329b2c8c84cc282867' into gingerbread-plus-aosp

* commit '56c5105bd7096704eaed35329b2c8c84cc282867':
  support for ext4/EMMC filesystems in updater binary
2010-09-15 11:14:51 -07:00
Doug Zongker
76445f3aef am 8674a726: (cherry-pick) support installing any .zip file on the sdcard
Merge commit '8674a726ff05a4a6c09c6934778c251635f130a8' into gingerbread-plus-aosp

* commit '8674a726ff05a4a6c09c6934778c251635f130a8':
  (cherry-pick) support installing any .zip file on the sdcard
2010-09-15 11:12:34 -07:00
Doug Zongker
858f0a763d am 8e5e4dad: close update package before installing; allow remount
Merge commit '8e5e4dada713609c9b2c45ea9cf4572bb89ef761' into gingerbread-plus-aosp

* commit '8e5e4dada713609c9b2c45ea9cf4572bb89ef761':
  close update package before installing; allow remount
2010-09-14 21:32:14 -07:00
Doug Zongker
bd4bc088e2 am d12560aa: add the ability to seek to a raw location while reading MTD partition
Merge commit 'd12560aa2134d3af21a1220cd4873553f9c51743' into gingerbread-plus-aosp

* commit 'd12560aa2134d3af21a1220cd4873553f9c51743':
  add the ability to seek to a raw location while reading MTD partition
2010-09-14 15:32:07 -07:00
Doug Zongker
6a84721c76 am f94a3575: am 61ba7a83: stop treating all-zero blocks as bad
Merge commit 'f94a3575d76f1fd6df20f82ca28fff688d53cfbc'

* commit 'f94a3575d76f1fd6df20f82ca28fff688d53cfbc':
  stop treating all-zero blocks as bad
2010-09-12 14:28:45 -07:00
Doug Zongker
f94a3575d7 am 61ba7a83: stop treating all-zero blocks as bad
Merge commit '61ba7a83ef46494689801ddaad569d7d174153b1' into gingerbread-plus-aosp

* commit '61ba7a83ef46494689801ddaad569d7d174153b1':
  stop treating all-zero blocks as bad
2010-09-12 14:23:25 -07:00
Doug Zongker
0b519b25c3 am a2c9a1e8: am aaf3f56c: block is bad if ioctl() returns nonzero
Merge commit 'a2c9a1e8a2b99bd8197c83b2f749ec61bc0312f8'

* commit 'a2c9a1e8a2b99bd8197c83b2f749ec61bc0312f8':
  block is bad if ioctl() returns nonzero
2010-09-09 17:01:49 -07:00
Doug Zongker
a2c9a1e8a2 am aaf3f56c: block is bad if ioctl() returns nonzero
Merge commit 'aaf3f56c44c37dca4ef9cc9efde68727ca26105f' into gingerbread-plus-aosp

* commit 'aaf3f56c44c37dca4ef9cc9efde68727ca26105f':
  block is bad if ioctl() returns nonzero
2010-09-09 16:59:05 -07:00
Doug Zongker
b56db27d08 am 28cae98c: am 4bc98062: add --show_text option to recovery
Merge commit '28cae98c834fb4bc47588b34dc3fe19811d5162b'

* commit '28cae98c834fb4bc47588b34dc3fe19811d5162b':
  add --show_text option to recovery
2010-09-03 11:23:21 -07:00
Doug Zongker
28cae98c83 am 4bc98062: add --show_text option to recovery
Merge commit '4bc980626c1cf6f1ea7d36e4b54e0023c896c9de' into gingerbread-plus-aosp

* commit '4bc980626c1cf6f1ea7d36e4b54e0023c896c9de':
  add --show_text option to recovery
2010-09-03 11:20:50 -07:00
Ying Wang
5200114fe8 am 4c7c2f73: (-s ours) am 532c8600: Revert 21f0f97ebabb47adcbfe8d38b02685f2019b4eb3
Merge commit '4c7c2f73af773872faf5a65167d74900865d96ba'

* commit '4c7c2f73af773872faf5a65167d74900865d96ba':
  Revert 21f0f97ebabb47adcbfe8d38b02685f2019b4eb3
2010-09-01 17:03:23 -07:00
Ying Wang
3e115b81a4 am 17b44ee3: (-s ours) am 21f0f97e: Fix for crespo.
Merge commit '17b44ee3d82d7b8efa8dc3bc17d78fee11d72e01'

* commit '17b44ee3d82d7b8efa8dc3bc17d78fee11d72e01':
  Fix for crespo.
2010-09-01 17:01:06 -07:00
Ying Wang
4c7c2f73af am 532c8600: Revert 21f0f97ebabb47adcbfe8d38b02685f2019b4eb3
Merge commit '532c86002bb89db43094b27ec50f001ae173c650' into gingerbread-plus-aosp

* commit '532c86002bb89db43094b27ec50f001ae173c650':
  Revert 21f0f97ebabb47adcbfe8d38b02685f2019b4eb3
2010-09-01 14:56:27 -07:00
Ying Wang
17b44ee3d8 am 21f0f97e: Fix for crespo.
Merge commit '21f0f97ebabb47adcbfe8d38b02685f2019b4eb3' into gingerbread-plus-aosp

* commit '21f0f97ebabb47adcbfe8d38b02685f2019b4eb3':
  Fix for crespo.
2010-09-01 14:53:32 -07:00
Jean-Baptiste Queru
37d58711f6 am 97900287: am 965f9dc4: merge -s ours from froyo-release so that upgrading to gingerbread is a git fast-forward
Merge commit '979002871ddc417dfdfb6a6542b9018626af7883'

* commit '979002871ddc417dfdfb6a6542b9018626af7883':
  fix bug in applying patches
  remove shadowed variable declaration
2010-08-24 11:54:52 -07:00
Jean-Baptiste Queru
979002871d am 965f9dc4: merge -s ours from froyo-release so that upgrading to gingerbread is a git fast-forward
Merge commit '965f9dc45345486e885b59b4776f0ca5e765ec20' into gingerbread-plus-aosp

* commit '965f9dc45345486e885b59b4776f0ca5e765ec20':
  fix bug in applying patches
  remove shadowed variable declaration
2010-08-23 19:10:18 -07:00
Doug Zongker
baf6e35473 am c080bc54: am fbd7ae7a: am 201cd466: remove shadowed variable declaration
Merge commit 'c080bc549aaf272c77fe7903e52c2a2c0d8de1bb'

* commit 'c080bc549aaf272c77fe7903e52c2a2c0d8de1bb':
  remove shadowed variable declaration
2010-08-16 07:44:51 -07:00
Ken Sumrall
8101125ee5 Changes to work with updated make_ext4fs tool that supports creating sparse images.
An extra parameter was added to the make_ext4fs() function, we these tools need
to be updated to match.

Change-Id: Id640a7f2b03153eb333b00337f0f991ff5332349
2010-08-13 19:22:47 -07:00
Doug Zongker
c080bc549a am fbd7ae7a: am 201cd466: remove shadowed variable declaration
Merge commit 'fbd7ae7a1ce0060221241ed02c576983c1f48d34' into gingerbread-plus-aosp

* commit 'fbd7ae7a1ce0060221241ed02c576983c1f48d34':
  remove shadowed variable declaration
2010-08-13 10:02:51 -07:00
Doug Zongker
80dcee145f am c4e32005: am 17986e6b: am 8cd9e4f3: fix bug in applying patches
Merge commit 'c4e3200578ad670bee9f5a88e90e7a77089d5df7'

* commit 'c4e3200578ad670bee9f5a88e90e7a77089d5df7':
  fix bug in applying patches
2010-08-12 17:57:45 -07:00
Doug Zongker
c4e3200578 am 17986e6b: am 8cd9e4f3: fix bug in applying patches
Merge commit '17986e6b8766ef9bdaa49efc7099e3867ca1978a' into gingerbread-plus-aosp

* commit '17986e6b8766ef9bdaa49efc7099e3867ca1978a':
  fix bug in applying patches
2010-08-12 17:55:24 -07:00
Doug Zongker
04611da55b support using an EMMC misc partition to store recovery arguments
Change-Id: I9f912857cfc6afb8ba764f5541af7f01df029a77
2010-08-12 15:35:29 -07:00
Hristo Bojinov
db314d69f0 Working ASLR implementation
Separate files for retouch functionality are in minelf/*

ASLR for shared libraries is controlled by "-a" in ota_from_target_files.
Binary files are self-contained. Retouch logic can recover from crashes.

Signed-off-by: Hristo Bojinov <hristo@google.com>
Change-Id: I76c596abf4febd68c14f9d807ac62e8751e0b1bd
2010-08-02 14:17:33 -07:00
Doug Zongker
f635d2e910 don't go into file select menu when mounting external storage fails
Change-Id: If0efeddc28e1dbb52d9e52abf53323e2cc97c8f0
2010-08-02 11:34:46 -07:00
Doug Zongker
dc9e87c44b generalize "install from sdcard" to "install from external storage"
Allow sideloading of OTA packages from USB drives that appear as
/dev/block/sda1.

Change-Id: I1908576c24547cd0088475d8c8917699cd906868
2010-07-29 17:08:50 -07:00
Ying Wang
b4277c25c6 Mute unwanted error message
This CL removes the following line from the top of build logs:
"diff: out/target/product/*/obj/PACKAGING/updater_extensions_intermediates/register.inc.list: No such file or directory"

Change-Id: I79c15a69a0b1b0da0e45620b45a7a0fea5625250
2010-07-20 17:31:04 -07:00
Doug Zongker
050d0f7fec resolved conflicts for merge of c02c37a1 to master
Change-Id: Iafb9cb4adf27a7086d587d95e94ab1bd050099dc
2010-07-09 09:13:51 -07:00
Doug Zongker
c02c37a1e6 am 23ceeea8: make a copy of sideloaded packages in /tmp before verifying
Merge commit '23ceeea85e6a3555dd3d7140128e310954cadf7f' into gingerbread-plus-aosp

* commit '23ceeea85e6a3555dd3d7140128e310954cadf7f':
  make a copy of sideloaded packages in /tmp before verifying
2010-07-08 17:50:26 -07:00
Doug Zongker
f291d858f8 EMMC support in applypatch
Let applypatch read and write EMMC partitions as well as MTD ones.
This enables incremental updates that include boot image changes, as
well as OTA of new recovery partitions.

Change-Id: I3766b9e77c639769ddf693b675da51d57f6e6b1d
2010-07-07 15:18:27 -07:00
Doug Zongker
3d177d055c support for ext4/EMMC filesystems in updater binary
Make the mount and format functions take extra parameters describing
the filesystem type and add support for mounting and formatting ext4
filesystems on EMMC.

Change recovery to consistently use stdout for status messages instead
of mixing stdout and stderr.
2010-07-01 15:42:28 -07:00
Doug Zongker
b442b45bdd Merge "support userdata and cache partitions using emmc/ext4 instead of mtd/yaffs" 2010-07-01 09:21:12 -07:00
The Android Open Source Project
42cfc2cc05 am 60faafcf: merge from open-source master
Merge commit '60faafcf01ff7f4179cdcaefd24b10ac4ee7f692'

* commit '60faafcf01ff7f4179cdcaefd24b10ac4ee7f692':
2010-06-30 15:54:38 -07:00
The Android Open Source Project
60faafcf01 merge from open-source master
Change-Id: I9d0122dbf1a9c2bd1898c41766c5bf4320f2313a
2010-06-30 15:51:09 -07:00
Doug Zongker
49c73a76a3 support userdata and cache partitions using emmc/ext4 instead of mtd/yaffs
Change-Id: I827af624c9ec7c64decb702de8c0310cf19b4141
2010-06-29 17:36:28 -07:00
Kenny Root
ba634dc9f7 am c78a9698: am ecc76ba5: Set adbd to be disabled by default in recovery
Merge commit 'c78a9698dd55a165c2206c380f87f173bacba2aa'

* commit 'c78a9698dd55a165c2206c380f87f173bacba2aa':
  Set adbd to be disabled by default in recovery
2010-06-28 12:28:45 -07:00
Kenny Root
4fef81a5a9 am ecc76ba5: Set adbd to be disabled by default in recovery
Merge commit 'ecc76ba5516d62a886f9c290906e0ca50702c9ab' into froyo-plus-aosp

* commit 'ecc76ba5516d62a886f9c290906e0ca50702c9ab':
  Set adbd to be disabled by default in recovery
2010-06-28 12:24:46 -07:00
Nick Kralevich
9e6513f145 am 21b97ed5: Add __attribute__((format(printf, a, b))) to printf like functions.
Merge commit '21b97ed5693d039e8b9dea57a160d3307f412682'

* commit '21b97ed5693d039e8b9dea57a160d3307f412682':
  Add __attribute__((format(printf, a, b))) to printf like functions.
2010-06-24 17:16:49 -07:00
Colin Cross
b3d9a15b66 am dd6a0412: recovery: Add ueventd service 2010-05-14 14:35:50 -07:00
Bruce Beare
eb681fd491 am be42930f: am 97ca48e7: generic_x86 support 2010-05-03 16:17:50 -07:00
Doug Zongker
be598881d0 support installing any .zip file on the sdcard
Replaces the "install sdcard:update zip" menu option with one that
displays a menu of zip files (and subdirs) on the sdcard and lets you
pick which one to install.

Change-Id: I85c94c0e9bc8e05ca52031fc29ca2624c2695ced
2010-04-08 14:36:55 -07:00
Oscar Montemayor
6102227b0b am 52219a68: (-s ours) DO NOT MERGE Encrypted File Systems integration. Recovery changes. 2010-04-01 17:42:37 -07:00
Oscar Montemayor
f33e24645b Merge "Encrypted File Systems part 3. Recovery changes." 2010-03-31 10:06:27 -07:00
Oscar Montemayor
be17b1c0d7 am 51282faa: (-s ours) am 2654f5aa: (-s ours) DO NOT MERGE Removing unused recovey options. Please refer to Bug#2502219 for more info. 2010-03-29 16:31:06 -07:00
Oscar Montemayor
31f6ee88ce Encrypted File Systems part 3. Recovery changes.
Change-Id: I932f73a6f937aac061128e1134eab08c30f0471d
2010-03-15 09:45:49 -07:00
68 changed files with 2305 additions and 1689 deletions

View File

@ -1,6 +1,3 @@
ifneq ($(TARGET_SIMULATOR),true)
ifeq ($(TARGET_ARCH),arm)
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
@ -13,15 +10,15 @@ LOCAL_SRC_FILES := \
install.c \
roots.c \
ui.c \
verifier.c \
encryptedfs_provisioning.c \
mounts.c \
extendedcommands.c \
nandroid.c \
../../system/core/toolbox/reboot.c \
firmware.c \
edifyscripting.c \
setprop.c
setprop.c \
default_recovery_ui.c \
verifier.c
ADDITIONAL_RECOVERY_FILES := $(shell echo $$ADDITIONAL_RECOVERY_FILES)
LOCAL_SRC_FILES += $(ADDITIONAL_RECOVERY_FILES)
@ -37,13 +34,22 @@ else
RECOVERY_NAME := CWM-based Recovery
endif
RECOVERY_VERSION := $(RECOVERY_NAME) v5.0.2.7
RECOVERY_VERSION := $(RECOVERY_NAME) v5.5.0.4
LOCAL_CFLAGS += -DRECOVERY_VERSION="$(RECOVERY_VERSION)"
RECOVERY_API_VERSION := 2
LOCAL_CFLAGS += -DRECOVERY_API_VERSION=$(RECOVERY_API_VERSION)
BOARD_RECOVERY_DEFINES := BOARD_HAS_NO_SELECT_BUTTON BOARD_HAS_SMALL_RECOVERY BOARD_LDPI_RECOVERY BOARD_UMS_LUNFILE BOARD_RECOVERY_ALWAYS_WIPES BOARD_RECOVERY_HANDLES_MOUNT
ifneq ($(BOARD_USE_CUSTOM_RECOVERY_FONT),)
BOARD_RECOVERY_CHAR_WIDTH := $(shell echo $(BOARD_USE_CUSTOM_RECOVERY_FONT) | cut -d _ -f 2 | cut -d . -f 1 | cut -d x -f 1)
BOARD_RECOVERY_CHAR_HEIGHT := $(shell echo $(BOARD_USE_CUSTOM_RECOVERY_FONT) | cut -d _ -f 2 | cut -d . -f 1 | cut -d x -f 2)
else
BOARD_RECOVERY_CHAR_WIDTH := 10
BOARD_RECOVERY_CHAR_HEIGHT := 18
endif
LOCAL_CFLAGS += -DBOARD_RECOVERY_CHAR_WIDTH=$(BOARD_RECOVERY_CHAR_WIDTH) -DBOARD_RECOVERY_CHAR_HEIGHT=$(BOARD_RECOVERY_CHAR_HEIGHT)
BOARD_RECOVERY_DEFINES := BOARD_HAS_NO_SELECT_BUTTON BOARD_UMS_LUNFILE BOARD_RECOVERY_ALWAYS_WIPES BOARD_RECOVERY_HANDLES_MOUNT BOARD_TOUCH_RECOVERY
$(foreach board_define,$(BOARD_RECOVERY_DEFINES), \
$(if $($(board_define)), \
@ -51,6 +57,12 @@ $(foreach board_define,$(BOARD_RECOVERY_DEFINES), \
) \
)
LOCAL_STATIC_LIBRARIES :=
LOCAL_CFLAGS += -DUSE_EXT4
LOCAL_C_INCLUDES += system/extras/ext4_utils
LOCAL_STATIC_LIBRARIES += libext4_utils libz
# This binary is in the recovery ramdisk, which is otherwise a copy of root.
# It gets copied there in config/Makefile. LOCAL_MODULE_TAGS suppresses
# a (redundant) copy of the binary in /system/bin for user builds.
@ -58,18 +70,16 @@ $(foreach board_define,$(BOARD_RECOVERY_DEFINES), \
LOCAL_MODULE_TAGS := eng
LOCAL_STATIC_LIBRARIES :=
ifeq ($(BOARD_CUSTOM_RECOVERY_KEYMAPPING),)
LOCAL_SRC_FILES += default_recovery_ui.c
LOCAL_SRC_FILES += default_recovery_keys.c
else
LOCAL_SRC_FILES += $(BOARD_CUSTOM_RECOVERY_KEYMAPPING)
endif
LOCAL_STATIC_LIBRARIES += librebootrecovery
LOCAL_STATIC_LIBRARIES += libext4_utils libz
LOCAL_STATIC_LIBRARIES += libminzip libunz libmincrypt
LOCAL_STATIC_LIBRARIES += libedify libbusybox libclearsilverregex libmkyaffs2image libunyaffs liberase_image libdump_image libflash_image
LOCAL_STATIC_LIBRARIES += libedify libbusybox libmkyaffs2image libunyaffs liberase_image libdump_image libflash_image
LOCAL_STATIC_LIBRARIES += libcrecovery libflashutils libmtdutils libmmcutils libbmlutils
@ -99,12 +109,7 @@ ALL_DEFAULT_INSTALLED_MODULES += $(RECOVERY_SYMLINKS)
# Now let's do recovery symlinks
BUSYBOX_LINKS := $(shell cat external/busybox/busybox-minimal.links)
ifndef BOARD_HAS_SMALL_RECOVERY
exclude := tune2fs
ifeq ($(BOARD_HAS_LARGE_FILESYSTEM),true)
exclude += mke2fs
endif
endif
exclude := tune2fs mke2fs
RECOVERY_BUSYBOX_SYMLINKS := $(addprefix $(TARGET_RECOVERY_ROOT_OUT)/sbin/,$(filter-out $(exclude),$(notdir $(BUSYBOX_LINKS))))
$(RECOVERY_BUSYBOX_SYMLINKS): BUSYBOX_BINARY := busybox
$(RECOVERY_BUSYBOX_SYMLINKS): $(LOCAL_INSTALLED_MODULE)
@ -113,11 +118,11 @@ $(RECOVERY_BUSYBOX_SYMLINKS): $(LOCAL_INSTALLED_MODULE)
@rm -rf $@
$(hide) ln -sf $(BUSYBOX_BINARY) $@
ALL_DEFAULT_INSTALLED_MODULES += $(RECOVERY_BUSYBOX_SYMLINKS)
ALL_DEFAULT_INSTALLED_MODULES += $(RECOVERY_BUSYBOX_SYMLINKS)
include $(CLEAR_VARS)
LOCAL_MODULE := nandroid-md5.sh
LOCAL_MODULE_TAGS := eng
LOCAL_MODULE_TAGS := optional
LOCAL_MODULE_CLASS := RECOVERY_EXECUTABLES
LOCAL_MODULE_PATH := $(TARGET_RECOVERY_ROOT_OUT)/sbin
LOCAL_SRC_FILES := nandroid-md5.sh
@ -125,7 +130,7 @@ include $(BUILD_PREBUILT)
include $(CLEAR_VARS)
LOCAL_MODULE := killrecovery.sh
LOCAL_MODULE_TAGS := eng
LOCAL_MODULE_TAGS := optional
LOCAL_MODULE_CLASS := RECOVERY_EXECUTABLES
LOCAL_MODULE_PATH := $(TARGET_RECOVERY_ROOT_OUT)/sbin
LOCAL_SRC_FILES := killrecovery.sh
@ -145,12 +150,11 @@ LOCAL_STATIC_LIBRARIES := libmincrypt libcutils libstdc++ libc
include $(BUILD_EXECUTABLE)
include $(commands_recovery_local_path)/dedupe/Android.mk
include $(commands_recovery_local_path)/bmlutils/Android.mk
include $(commands_recovery_local_path)/flashutils/Android.mk
include $(commands_recovery_local_path)/libcrecovery/Android.mk
include $(commands_recovery_local_path)/minui/Android.mk
include $(commands_recovery_local_path)/minelf/Android.mk
include $(commands_recovery_local_path)/minzip/Android.mk
include $(commands_recovery_local_path)/mtdutils/Android.mk
include $(commands_recovery_local_path)/mmcutils/Android.mk
@ -160,7 +164,3 @@ include $(commands_recovery_local_path)/updater/Android.mk
include $(commands_recovery_local_path)/applypatch/Android.mk
include $(commands_recovery_local_path)/utilities/Android.mk
commands_recovery_local_path :=
endif # TARGET_ARCH == arm
endif # !TARGET_SIMULATOR

View File

@ -12,9 +12,6 @@
# See the License for the specific language governing permissions and
# limitations under the License.
ifneq ($(TARGET_SIMULATOR),true)
ifeq ($(TARGET_ARCH),arm)
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
@ -31,7 +28,7 @@ include $(CLEAR_VARS)
LOCAL_SRC_FILES := main.c
LOCAL_MODULE := applypatch
LOCAL_C_INCLUDES += bootable/recovery
LOCAL_STATIC_LIBRARIES += libapplypatch libmtdutils libmincrypt libbz
LOCAL_STATIC_LIBRARIES += libapplypatch libmtdutils libmincrypt libbz libminelf
LOCAL_SHARED_LIBRARIES += libz libcutils libstdc++ libc
include $(BUILD_EXECUTABLE)
@ -43,7 +40,7 @@ LOCAL_MODULE := applypatch_static
LOCAL_FORCE_STATIC_EXECUTABLE := true
LOCAL_MODULE_TAGS := eng
LOCAL_C_INCLUDES += bootable/recovery
LOCAL_STATIC_LIBRARIES += libapplypatch libmtdutils libmincrypt libbz
LOCAL_STATIC_LIBRARIES += libapplypatch libmtdutils libmincrypt libbz libminelf
LOCAL_STATIC_LIBRARIES += libz libcutils libstdc++ libc
include $(BUILD_EXECUTABLE)
@ -58,6 +55,3 @@ LOCAL_C_INCLUDES += external/zlib external/bzip2
LOCAL_STATIC_LIBRARIES += libz libbz
include $(BUILD_HOST_EXECUTABLE)
endif # TARGET_ARCH == arm
endif # !TARGET_SIMULATOR

View File

@ -30,16 +30,21 @@
#include "mtdutils/mtdutils.h"
#include "edify/expr.h"
static int SaveFileContents(const char* filename, FileContents file);
int SaveFileContents(const char* filename, FileContents file);
static int LoadPartitionContents(const char* filename, FileContents* file);
int ParseSha1(const char* str, uint8_t* digest);
static ssize_t FileSink(unsigned char* data, ssize_t len, void* token);
static int mtd_partitions_scanned = 0;
// Read a file into memory; store it and its associated metadata in
// *file. Return 0 on success.
int LoadFileContents(const char* filename, FileContents* file) {
// Read a file into memory; optionally (retouch_flag == RETOUCH_DO_MASK) mask
// the retouched entries back to their original value (such that SHA-1 checks
// don't fail due to randomization); store the file contents and associated
// metadata in *file.
//
// Return 0 on success.
int LoadFileContents(const char* filename, FileContents* file,
int retouch_flag) {
file->data = NULL;
// A special 'filename' beginning with "MTD:" or "EMMC:" means to
@ -75,6 +80,20 @@ int LoadFileContents(const char* filename, FileContents* file) {
}
fclose(f);
// apply_patch[_check] functions are blind to randomization. Randomization
// is taken care of in [Undo]RetouchBinariesFn. If there is a mismatch
// within a file, this means the file is assumed "corrupt" for simplicity.
if (retouch_flag) {
int32_t desired_offset = 0;
if (retouch_mask_data(file->data, file->size,
&desired_offset, NULL) != RETOUCH_DATA_MATCHED) {
printf("error trying to mask retouch entries\n");
free(file->data);
file->data = NULL;
return -1;
}
}
SHA(file->data, file->size, file->sha1);
return 0;
}
@ -303,7 +322,7 @@ static int LoadPartitionContents(const char* filename, FileContents* file) {
// Save the contents of the given FileContents object under the given
// filename. Return 0 on success.
static int SaveFileContents(const char* filename, FileContents file) {
int SaveFileContents(const char* filename, FileContents file) {
int fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC);
if (fd < 0) {
printf("failed to open \"%s\" for write: %s\n",
@ -477,7 +496,7 @@ int applypatch_check(const char* filename,
// LoadFileContents is successful. (Useful for reading
// partitions, where the filename encodes the sha1s; no need to
// check them twice.)
if (LoadFileContents(filename, &file) != 0 ||
if (LoadFileContents(filename, &file, RETOUCH_DO_MASK) != 0 ||
(num_patches > 0 &&
FindMatchingPatch(file.sha1, patch_sha1_str, num_patches) < 0)) {
printf("file \"%s\" doesn't have any of expected "
@ -491,7 +510,7 @@ int applypatch_check(const char* filename,
// exists and matches the sha1 we're looking for, the check still
// passes.
if (LoadFileContents(CACHE_TEMP_SOURCE, &file) != 0) {
if (LoadFileContents(CACHE_TEMP_SOURCE, &file, RETOUCH_DO_MASK) != 0) {
printf("failed to load cache file\n");
return 1;
}
@ -617,7 +636,8 @@ int applypatch(const char* source_filename,
int made_copy = 0;
// We try to load the target file into the source_file object.
if (LoadFileContents(target_filename, &source_file) == 0) {
if (LoadFileContents(target_filename, &source_file,
RETOUCH_DO_MASK) == 0) {
if (memcmp(source_file.sha1, target_sha1, SHA_DIGEST_SIZE) == 0) {
// The early-exit case: the patch was already applied, this file
// has the desired hash, nothing for us to do.
@ -633,7 +653,8 @@ int applypatch(const char* source_filename,
// Need to load the source file: either we failed to load the
// target file, or we did but it's different from the source file.
free(source_file.data);
LoadFileContents(source_filename, &source_file);
LoadFileContents(source_filename, &source_file,
RETOUCH_DO_MASK);
}
if (source_file.data != NULL) {
@ -648,7 +669,8 @@ int applypatch(const char* source_filename,
free(source_file.data);
printf("source file is bad; trying copy\n");
if (LoadFileContents(CACHE_TEMP_SOURCE, &copy_file) < 0) {
if (LoadFileContents(CACHE_TEMP_SOURCE, &copy_file,
RETOUCH_DO_MASK) < 0) {
// fail.
printf("failed to read copy file\n");
return 1;

View File

@ -19,6 +19,7 @@
#include <sys/stat.h>
#include "mincrypt/sha.h"
#include "minelf/Retouch.h"
#include "edify/expr.h"
typedef struct _Patch {
@ -59,10 +60,12 @@ int applypatch_check(const char* filename,
int num_patches,
char** const patch_sha1_str);
// Read a file into memory; store it and its associated metadata in
// *file. Return 0 on success.
int LoadFileContents(const char* filename, FileContents* file);
int LoadFileContents(const char* filename, FileContents* file,
int retouch_flag);
int SaveFileContents(const char* filename, FileContents file);
void FreeFileContents(FileContents* file);
int FindMatchingPatch(uint8_t* sha1, char** const patch_sha1_str,
int num_patches);
// bsdiff.c
void ShowBSDiffLicense();

View File

@ -74,7 +74,7 @@ static int ParsePatchArgs(int argc, char** argv,
(*patches)[i] = NULL;
} else {
FileContents fc;
if (LoadFileContents(colon, &fc) != 0) {
if (LoadFileContents(colon, &fc, RETOUCH_DONT_MASK) != 0) {
goto abort;
}
(*patches)[i] = malloc(sizeof(Value));

View File

@ -10,6 +10,9 @@ $(foreach board_define,$(BOARD_RECOVERY_DEFINES), \
) \
)
LOCAL_STATIC_LIBRARIES := libcrecovery
LOCAL_C_INCLUDES := bootable/recovery/libcrecovery
LOCAL_SRC_FILES := bmlutils.c
LOCAL_MODULE := libbmlutils
LOCAL_MODULE_TAGS := eng

View File

@ -20,7 +20,8 @@
#include <signal.h>
#include <sys/wait.h>
extern int __system(const char *command);
#include <common.h>
#define BML_UNLOCK_ALL 0x8A29 ///< unlock all partition RO -> RW
#ifndef BOARD_BML_BOOT

View File

@ -22,6 +22,8 @@
#include <errno.h>
#include <stdio.h>
#include <string.h>
#include <sys/stat.h>
#include <unistd.h>
static int get_bootloader_message_mtd(struct bootloader_message *out, const Volume* v);
static int set_bootloader_message_mtd(const struct bootloader_message *in, const Volume* v);
@ -140,8 +142,26 @@ static int set_bootloader_message_mtd(const struct bootloader_message *in,
// for misc partitions on block devices
// ------------------------------------
static void wait_for_device(const char* fn) {
int tries = 0;
int ret;
struct stat buf;
do {
++tries;
ret = stat(fn, &buf);
if (ret) {
printf("stat %s try %d: %s\n", fn, tries, strerror(errno));
sleep(1);
}
} while (ret && tries < 10);
if (ret) {
printf("failed to stat %s\n", fn);
}
}
static int get_bootloader_message_block(struct bootloader_message *out,
const Volume* v) {
wait_for_device(v->device);
FILE* f = fopen(v->device, "rb");
if (f == NULL) {
LOGE("Can't open %s\n(%s)\n", v->device, strerror(errno));
@ -163,6 +183,7 @@ static int get_bootloader_message_block(struct bootloader_message *out,
static int set_bootloader_message_block(const struct bootloader_message *in,
const Volume* v) {
wait_for_device(v->device);
FILE* f = fopen(v->device, "wb");
if (f == NULL) {
LOGE("Can't open %s\n(%s)\n", v->device, strerror(errno));
@ -328,4 +349,4 @@ int write_update_for_bootloader(
}
return 0;
}
}

View File

@ -26,6 +26,7 @@ void ui_init();
int ui_wait_key(); // waits for a key/button press, returns the code
int ui_key_pressed(int key); // returns >0 if the code is currently pressed
int ui_text_visible(); // returns >0 if text log is currently visible
int ui_text_ever_visible(); // returns >0 if text log was ever visible
void ui_show_text(int visible);
void ui_clear_key_queue();
@ -113,6 +114,13 @@ typedef struct {
const char* device2; // alternative device to try if fs_type
// == "ext4" or "vfat" and mounting
// 'device' fails
long long length; // (ext4 partition only) when
// formatting, size to use for the
// partition. 0 or negative number
// means to format all but the last
// (that much).
const char* fs_type2;
const char* fs_options;
@ -120,4 +128,26 @@ typedef struct {
const char* fs_options2;
} Volume;
typedef struct {
// number of frames in indeterminate progress bar animation
int indeterminate_frames;
// number of frames per second to try to maintain when animating
int update_fps;
// number of frames in installing animation. may be zero for a
// static installation icon.
int installing_frames;
// the install icon is animated by drawing images containing the
// changing part over the base icon. These specify the
// coordinates of the upper-left corner.
int install_overlay_offset_x;
int install_overlay_offset_y;
} UIParameters;
// fopen a file, mounting volumes and making parent dirs as necessary.
FILE* fopen_path(const char *path, const char *mode);
#endif // RECOVERY_COMMON_H

View File

@ -1,24 +0,0 @@
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_SRC_FILES := dedupe.c
LOCAL_FORCE_STATIC_EXECUTABLE := true
LOCAL_MODULE_TAGS := eng
LOCAL_MODULE := dedupe
LOCAL_STATIC_LIBRARIES := libcrypto_static
LOCAL_C_INCLUDES += $(LOCAL_PATH)/../../../external/openssl/include
include $(BUILD_HOST_EXECUTABLE)
include $(CLEAR_VARS)
LOCAL_SRC_FILES := dedupe.c
LOCAL_STATIC_LIBRARIES := libcrypto libcutils libc
LOCAL_MODULE := utility_dedupe
LOCAL_MODULE_TAGS := eng
LOCAL_MODULE_STEM := dedupe
LOCAL_MODULE_CLASS := UTILITY_EXECUTABLES
LOCAL_C_INCLUDES := external/openssl/include
LOCAL_UNSTRIPPED_PATH := $(PRODUCT_OUT)/symbols/utilities
LOCAL_MODULE_PATH := $(PRODUCT_OUT)/utilities
LOCAL_FORCE_STATIC_EXECUTABLE := true
include $(BUILD_EXECUTABLE)

View File

@ -1,330 +0,0 @@
#include <stdio.h>
#include <sys/stat.h>
#include <openssl/md5.h>
#include <openssl/sha.h>
#include <openssl/ripemd.h>
#include <errno.h>
#include <dirent.h>
#include <limits.h>
#include <stdlib.h>
#include <fcntl.h>
#include <limits.h>
typedef struct DEDUPE_STORE_CONTEXT {
char blob_dir[PATH_MAX];
FILE *output_manifest;
};
static void usage(char** argv) {
fprintf(stderr, "usage: %s c input_directory blob_dir output_manifest\n", argv[0]);
fprintf(stderr, "usage: %s x input_manifest blob_dir output_directory\n", argv[0]);
}
static int copy_file(const char *dst, const char *src) {
char buf[4096];
int dstfd, srcfd, bytes_read, bytes_written, total_read = 0;
if (src == NULL)
return 1;
if (dst == NULL)
return 2;
srcfd = open(src, O_RDONLY);
if (srcfd < 0)
return 3;
dstfd = open(dst, O_RDWR | O_CREAT | O_TRUNC, 0600);
if (dstfd < 0) {
close(srcfd);
return 4;
}
while (bytes_read = read(srcfd, buf, 4096)) {
total_read += bytes_read;
if (write(dstfd, buf, bytes_read) != bytes_read)
return 5;
}
close(dstfd);
close(srcfd);
return 0;
}
static void do_sha256sum(FILE *mfile, unsigned char *rptr) {
char rdata[BUFSIZ];
int rsize;
SHA256_CTX c;
SHA256_Init(&c);
while(!feof(mfile)) {
rsize = fread(rdata, sizeof(char), BUFSIZ, mfile);
if(rsize > 0) {
SHA256_Update(&c, rdata, rsize);
}
}
SHA256_Final(rptr, &c);
}
static int do_sha256sum_file(const char* filename, unsigned char *rptr) {
FILE *f = fopen(filename, "rb");
if (f == NULL) {
fprintf(stderr, "Unable to open file: %s\n", filename);
return 1;
}
do_sha256sum(f, rptr);
fclose(f);
return 0;
}
static int store_st(struct DEDUPE_STORE_CONTEXT *context, struct stat st, const char* s);
void print_stat(struct DEDUPE_STORE_CONTEXT *context, char type, struct stat st, const char *f) {
fprintf(context->output_manifest, "%c\t%o\t%d\t%d\t%s\t", type, st.st_mode & (S_IRWXU | S_IRWXG | S_IRWXO | S_ISUID | S_ISGID), st.st_uid, st.st_gid, f);
}
static int store_file(struct DEDUPE_STORE_CONTEXT *context, struct stat st, const char* f) {
printf("%s\n", f);
unsigned char sumdata[SHA256_DIGEST_LENGTH];
int ret;
if (ret = do_sha256sum_file(f, sumdata)) {
fprintf(stderr, "Error calculating sha256sum of %s\n", f);
return ret;
}
char psum[128];
int j;
for (j = 0; j < SHA256_DIGEST_LENGTH; j++)
sprintf(&psum[(j*2)], "%02x", (int)sumdata[j]);
psum[(SHA256_DIGEST_LENGTH * 2)] = '\0';
char out_blob[PATH_MAX];
sprintf(out_blob, "%s/%s", context->blob_dir, psum);
if (ret = copy_file(out_blob, f)) {
fprintf(stderr, "Error copying blob %s\n", f);
return ret;
}
fprintf(context->output_manifest, "%s\t%d\t\n", psum, st.st_size);
return 0;
}
static int store_dir(struct DEDUPE_STORE_CONTEXT *context, struct stat st, const char* d) {
printf("%s\n", d);
DIR *dp = opendir(d);
if (d == NULL) {
fprintf(stderr, "Error opening directory: %s\n", d);
return 1;
}
struct dirent *ep;
char full_path[PATH_MAX];
while (ep = readdir(dp)) {
if (strcmp(ep->d_name, ".") == 0)
continue;
if (strcmp(ep->d_name, "..") == 0)
continue;
struct stat cst;
int ret;
sprintf(full_path, "%s/%s", d, ep->d_name);
if (0 != (ret = lstat(full_path, &cst))) {
fprintf(stderr, "Error opening: %s\n", ep->d_name);
closedir(dp);
return ret;
}
if (ret = store_st(context, cst, full_path))
return ret;
}
closedir(dp);
return 0;
}
static int store_link(struct DEDUPE_STORE_CONTEXT *context, struct stat st, const char* l) {
printf("%s\n", l);
char link[PATH_MAX];
int ret = readlink(l, link, PATH_MAX);
if (ret < 0) {
fprintf(stderr, "Error reading symlink\n");
return errno;
}
link[ret] = '\0';
fprintf(context->output_manifest, "%s\t\n", link);
return 0;
}
static int store_st(struct DEDUPE_STORE_CONTEXT *context, struct stat st, const char* s) {
if (S_ISREG(st.st_mode)) {
print_stat(context, 'f', st, s);
return store_file(context, st, s);
}
else if (S_ISDIR(st.st_mode)) {
print_stat(context, 'd', st, s);
fprintf(context->output_manifest, "\n");
return store_dir(context, st, s);
}
else if (S_ISLNK(st.st_mode)) {
print_stat(context, 'l', st, s);
return store_link(context, st, s);
}
else {
fprintf(stderr, "Skipping special: %s\n", s);
return 0;
}
}
void get_full_path(char *out_path, char *rel_path) {
char tmp[PATH_MAX];
getcwd(tmp, PATH_MAX);
chdir(rel_path);
getcwd(out_path, PATH_MAX);
chdir(tmp);
}
static char* tokenize(char *out, const char* line, const char sep) {
while (*line != sep) {
if (*line == '\0') {
return NULL;
}
*out = *line;
out++;
line++;
}
*out = '\0';
// resume at the next char
return ++line;
}
static int dec_to_oct(int dec) {
int ret = 0;
int mult = 1;
while (dec != 0) {
int rem = dec % 10;
ret += (rem * mult);
dec /= 10;
mult *= 8;
}
return ret;
}
int main(int argc, char** argv) {
if (argc != 5) {
usage(argv);
return 1;
}
if (strcmp(argv[1], "c") == 0) {
struct stat st;
int ret;
if (0 != (ret = lstat(argv[2], &st))) {
fprintf(stderr, "Error opening input_file/input_directory.\n");
return ret;
}
if (!S_ISDIR(st.st_mode)) {
fprintf(stderr, "%s must be a directory.\n", argv[2]);
return 1;
}
char blob_dir[PATH_MAX];
struct DEDUPE_STORE_CONTEXT context;
context.output_manifest = fopen(argv[4], "wb");
if (context.output_manifest == NULL) {
fprintf(stderr, "Unable to open output file %s\n", argv[4]);
return 1;
}
get_full_path(context.blob_dir, argv[3]);
chdir(argv[2]);
return store_dir(&context, st, ".");
}
else if (strcmp(argv[1], "x") == 0) {
FILE *input_manifest = fopen(argv[2], "rb");
if (input_manifest == NULL) {
fprintf(stderr, "Unable to open input manifest %s\n", argv[2]);
return 1;
}
char blob_dir[PATH_MAX];
char *output_dir = argv[4];
get_full_path(blob_dir, argv[3]);
printf("%s\n" , output_dir);
chdir(output_dir);
char line[PATH_MAX];
while (fgets(line, PATH_MAX, input_manifest)) {
//printf("%s", line);
char type[4];
char mode[8];
char uid[32];
char gid[32];
char filename[PATH_MAX];
char *token = line;
token = tokenize(type, token, '\t');
token = tokenize(mode, token, '\t');
token = tokenize(uid, token, '\t');
token = tokenize(gid, token, '\t');
token = tokenize(filename, token, '\t');
int mode_oct = dec_to_oct(atoi(mode));
int uid_int = atoi(uid);
int gid_int = atoi(gid);
int ret;
printf("%s\t%s\t%s\t%s\t%s\t", type, mode, uid, gid, filename);
if (strcmp(type, "f") == 0) {
char sha256[128];
token = tokenize(sha256, token, '\t');
char sizeStr[32];
token = tokenize(sizeStr, token, '\t');
int size = atoi(sizeStr);
printf("%s\t%d\n", sha256, size);
char blob_file[PATH_MAX];
sprintf(blob_file, "%s/%s", blob_dir, sha256);
if (ret = copy_file(filename, blob_file)) {
fprintf(stderr, "Unable to copy file %s\n", filename);
fclose(input_manifest);
return ret;
}
chmod(filename, mode_oct);
chown(filename, uid_int, gid_int);
}
else if (strcmp(type, "l") == 0) {
char link[41];
token = tokenize(link, token, '\t');
printf("%s\n", link);
symlink(link, filename);
// Android has no lchmod, and chmod follows symlinks
//chmod(filename, mode_oct);
lchown(filename, uid_int, gid_int);
}
else if (strcmp(type, "d") == 0) {
printf("\n");
mkdir(filename, mode_oct);
chmod(filename, mode_oct);
chown(filename, uid_int, gid_int);
}
else {
fprintf(stderr, "Unknown type %s\n", type);
fclose(input_manifest);
return 1;
}
}
fclose(input_manifest);
return 0;
}
else {
usage(argv);
return 1;
}
}

68
default_recovery_keys.c Normal file
View File

@ -0,0 +1,68 @@
#include <linux/input.h>
#include "recovery_ui.h"
#include "common.h"
#include "extendedcommands.h"
int device_toggle_display(volatile char* key_pressed, int key_code) {
int alt = key_pressed[KEY_LEFTALT] || key_pressed[KEY_RIGHTALT];
if (alt && key_code == KEY_L)
return 1;
// allow toggling of the display if the correct key is pressed, and the display toggle is allowed or the display is currently off
if (ui_get_showing_back_button()) {
return 0;
//return get_allow_toggle_display() && (key_code == KEY_HOME || key_code == KEY_MENU || key_code == KEY_END);
}
return get_allow_toggle_display() && (key_code == KEY_HOME || key_code == KEY_MENU || key_code == KEY_POWER || key_code == KEY_END);
}
int device_handle_key(int key_code, int visible) {
if (visible) {
switch (key_code) {
case KEY_CAPSLOCK:
case KEY_DOWN:
case KEY_VOLUMEDOWN:
case KEY_MENU:
return HIGHLIGHT_DOWN;
case KEY_LEFTSHIFT:
case KEY_UP:
case KEY_VOLUMEUP:
case KEY_HOME:
return HIGHLIGHT_UP;
case KEY_POWER:
if (ui_get_showing_back_button()) {
return SELECT_ITEM;
}
if (!get_allow_toggle_display() && ui_menu_level > 0) {
return GO_BACK;
}
break;
case KEY_LEFTBRACE:
case KEY_ENTER:
case BTN_MOUSE:
case KEY_CAMERA:
case KEY_F21:
case KEY_SEND:
return SELECT_ITEM;
case KEY_END:
case KEY_BACKSPACE:
case KEY_SEARCH:
if (ui_get_showing_back_button()) {
return SELECT_ITEM;
}
if (!get_allow_toggle_display() && ui_menu_level > 0) {
return GO_BACK;
}
case KEY_BACK:
if (ui_menu_level > 0) {
return GO_BACK;
}
}
}
return NO_ACTION;
}

View File

@ -23,83 +23,25 @@
char* MENU_HEADERS[] = { NULL };
char* MENU_ITEMS[] = { "reboot system now",
"apply update from sdcard",
"install zip from sdcard",
"wipe data/factory reset",
"wipe cache partition",
"install zip from sdcard",
"backup and restore",
"mounts and storage",
"advanced",
"power off",
NULL };
void device_ui_init(UIParameters* ui_parameters) {
}
int device_recovery_start() {
return 0;
}
int device_toggle_display(volatile char* key_pressed, int key_code) {
int alt = key_pressed[KEY_LEFTALT] || key_pressed[KEY_RIGHTALT];
if (alt && key_code == KEY_L)
return 1;
// allow toggling of the display if the correct key is pressed, and the display toggle is allowed or the display is currently off
if (ui_get_showing_back_button()) {
return 0;
//return get_allow_toggle_display() && (key_code == KEY_HOME || key_code == KEY_MENU || key_code == KEY_END);
}
return get_allow_toggle_display() && (key_code == KEY_HOME || key_code == KEY_MENU || key_code == KEY_POWER || key_code == KEY_END);
}
int device_reboot_now(volatile char* key_pressed, int key_code) {
return 0;
}
int device_handle_key(int key_code, int visible) {
if (visible) {
switch (key_code) {
case KEY_CAPSLOCK:
case KEY_DOWN:
case KEY_VOLUMEDOWN:
case KEY_MENU:
return HIGHLIGHT_DOWN;
case KEY_LEFTSHIFT:
case KEY_UP:
case KEY_VOLUMEUP:
case KEY_HOME:
return HIGHLIGHT_UP;
case KEY_POWER:
if (ui_get_showing_back_button()) {
return SELECT_ITEM;
}
if (!get_allow_toggle_display())
return GO_BACK;
break;
case KEY_LEFTBRACE:
case KEY_ENTER:
case BTN_MOUSE:
case KEY_CENTER:
case KEY_CAMERA:
case KEY_F21:
case KEY_SEND:
return SELECT_ITEM;
case KEY_END:
case KEY_BACKSPACE:
case KEY_SEARCH:
if (ui_get_showing_back_button()) {
return SELECT_ITEM;
}
if (!get_allow_toggle_display())
return GO_BACK;
case KEY_BACK:
return GO_BACK;
}
}
return NO_ACTION;
}
int device_perform_action(int which) {
return which;
}

View File

@ -1,6 +1,18 @@
// Copyright ClockworkMod, LLC. Reference and porting purposes only. Usage of the extendedcommand API
// is restricted to those granted explicit permission, or by use of the ROM Manager Recovery API.
// https://github.com/koush/TestRomManager
/*
* Copyright (C) 2008 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <ctype.h>
#include <errno.h>
#include <fcntl.h>

View File

@ -1,283 +0,0 @@
/*
* Copyright (C) 2009 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/mount.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>
#include "encryptedfs_provisioning.h"
#include "cutils/misc.h"
#include "cutils/properties.h"
#include "common.h"
#include "mtdutils/mtdutils.h"
#include "mounts.h"
#include "roots.h"
const char* encrypted_fs_enabled_property = "persist.security.secfs.enabled";
const char* encrypted_fs_property_dir = "/data/property/";
const char* encrypted_fs_system_dir = "/data/system/";
const char* encrypted_fs_key_file_name = "/data/fs_key.dat";
const char* encrypted_fs_salt_file_name = "/data/hash_salt.dat";
const char* encrypted_fs_hash_file_src_name = "/data/system/password.key";
const char* encrypted_fs_hash_file_dst_name = "/data/hash.dat";
const char* encrypted_fs_entropy_file_src_name = "/data/system/entropy.dat";
const char* encrypted_fs_entropy_file_dst_name = "/data/ported_entropy.dat";
void get_property_file_name(char *buffer, const char *property_name) {
sprintf(buffer, "%s%s", encrypted_fs_property_dir, property_name);
}
int get_binary_file_contents(char *buffer, int buf_size, const char *file_name, int *out_size) {
FILE *in_file;
int read_bytes;
in_file = fopen(file_name, "r");
if (in_file == NULL) {
LOGE("Secure FS: error accessing key file.");
return ENCRYPTED_FS_ERROR;
}
read_bytes = fread(buffer, 1, buf_size, in_file);
if (out_size == NULL) {
if (read_bytes != buf_size) {
// Error or unexpected data
fclose(in_file);
LOGE("Secure FS: error reading conmplete key.");
return ENCRYPTED_FS_ERROR;
}
} else {
*out_size = read_bytes;
}
fclose(in_file);
return ENCRYPTED_FS_OK;
}
int set_binary_file_contents(char *buffer, int buf_size, const char *file_name) {
FILE *out_file;
int write_bytes;
out_file = fopen(file_name, "w");
if (out_file == NULL) {
LOGE("Secure FS: error setting up key file.");
return ENCRYPTED_FS_ERROR;
}
write_bytes = fwrite(buffer, 1, buf_size, out_file);
if (write_bytes != buf_size) {
// Error or unexpected data
fclose(out_file);
LOGE("Secure FS: error reading conmplete key.");
return ENCRYPTED_FS_ERROR;
}
fclose(out_file);
return ENCRYPTED_FS_OK;
}
int get_text_file_contents(char *buffer, int buf_size, char *file_name) {
FILE *in_file;
char *read_data;
in_file = fopen(file_name, "r");
if (in_file == NULL) {
LOGE("Secure FS: error accessing properties.");
return ENCRYPTED_FS_ERROR;
}
read_data = fgets(buffer, buf_size, in_file);
if (read_data == NULL) {
// Error or unexpected data
fclose(in_file);
LOGE("Secure FS: error accessing properties.");
return ENCRYPTED_FS_ERROR;
}
fclose(in_file);
return ENCRYPTED_FS_OK;
}
int set_text_file_contents(char *buffer, char *file_name) {
FILE *out_file;
int result;
out_file = fopen(file_name, "w");
if (out_file == NULL) {
LOGE("Secure FS: error setting up properties.");
return ENCRYPTED_FS_ERROR;
}
result = fputs(buffer, out_file);
if (result != 0) {
// Error or unexpected data
fclose(out_file);
LOGE("Secure FS: error setting up properties.");
return ENCRYPTED_FS_ERROR;
}
fflush(out_file);
fclose(out_file);
return ENCRYPTED_FS_OK;
}
int read_encrypted_fs_boolean_property(const char *prop_name, int *value) {
char prop_file_name[PROPERTY_KEY_MAX + 32];
char prop_value[PROPERTY_VALUE_MAX];
int result;
get_property_file_name(prop_file_name, prop_name);
result = get_text_file_contents(prop_value, PROPERTY_VALUE_MAX, prop_file_name);
if (result < 0) {
return result;
}
if (strncmp(prop_value, "1", 1) == 0) {
*value = 1;
} else if (strncmp(prop_value, "0", 1) == 0) {
*value = 0;
} else {
LOGE("Secure FS: error accessing properties.");
return ENCRYPTED_FS_ERROR;
}
return ENCRYPTED_FS_OK;
}
int write_encrypted_fs_boolean_property(const char *prop_name, int value) {
char prop_file_name[PROPERTY_KEY_MAX + 32];
char prop_value[PROPERTY_VALUE_MAX];
int result;
get_property_file_name(prop_file_name, prop_name);
// Create the directory if needed
mkdir(encrypted_fs_property_dir, 0755);
if (value == 1) {
result = set_text_file_contents("1", prop_file_name);
} else if (value == 0) {
result = set_text_file_contents("0", prop_file_name);
} else {
return ENCRYPTED_FS_ERROR;
}
if (result < 0) {
return result;
}
return ENCRYPTED_FS_OK;
}
int read_encrypted_fs_info(encrypted_fs_info *encrypted_fs_data) {
int result;
int value;
result = ensure_path_mounted("/data");
if (result != 0) {
LOGE("Secure FS: error mounting userdata partition.");
return ENCRYPTED_FS_ERROR;
}
// Read the pre-generated encrypted FS key, password hash and salt.
result = get_binary_file_contents(encrypted_fs_data->key, ENCRYPTED_FS_KEY_SIZE,
encrypted_fs_key_file_name, NULL);
if (result != 0) {
LOGE("Secure FS: error reading generated file system key.");
return ENCRYPTED_FS_ERROR;
}
result = get_binary_file_contents(encrypted_fs_data->salt, ENCRYPTED_FS_SALT_SIZE,
encrypted_fs_salt_file_name, &(encrypted_fs_data->salt_length));
if (result != 0) {
LOGE("Secure FS: error reading file system salt.");
return ENCRYPTED_FS_ERROR;
}
result = get_binary_file_contents(encrypted_fs_data->hash, ENCRYPTED_FS_MAX_HASH_SIZE,
encrypted_fs_hash_file_src_name, &(encrypted_fs_data->hash_length));
if (result != 0) {
LOGE("Secure FS: error reading password hash.");
return ENCRYPTED_FS_ERROR;
}
result = get_binary_file_contents(encrypted_fs_data->entropy, ENTROPY_MAX_SIZE,
encrypted_fs_entropy_file_src_name, &(encrypted_fs_data->entropy_length));
if (result != 0) {
LOGE("Secure FS: error reading ported entropy.");
return ENCRYPTED_FS_ERROR;
}
result = ensure_path_unmounted("/data");
if (result != 0) {
LOGE("Secure FS: error unmounting data partition.");
return ENCRYPTED_FS_ERROR;
}
return ENCRYPTED_FS_OK;
}
int restore_encrypted_fs_info(encrypted_fs_info *encrypted_fs_data) {
int result;
result = ensure_path_mounted("/data");
if (result != 0) {
LOGE("Secure FS: error mounting userdata partition.");
return ENCRYPTED_FS_ERROR;
}
// Write the pre-generated secure FS key, password hash and salt.
result = set_binary_file_contents(encrypted_fs_data->key, ENCRYPTED_FS_KEY_SIZE,
encrypted_fs_key_file_name);
if (result != 0) {
LOGE("Secure FS: error writing generated file system key.");
return ENCRYPTED_FS_ERROR;
}
result = set_binary_file_contents(encrypted_fs_data->salt, encrypted_fs_data->salt_length,
encrypted_fs_salt_file_name);
if (result != 0) {
LOGE("Secure FS: error writing file system salt.");
return ENCRYPTED_FS_ERROR;
}
result = set_binary_file_contents(encrypted_fs_data->hash, encrypted_fs_data->hash_length,
encrypted_fs_hash_file_dst_name);
if (result != 0) {
LOGE("Secure FS: error writing password hash.");
return ENCRYPTED_FS_ERROR;
}
result = set_binary_file_contents(encrypted_fs_data->entropy, encrypted_fs_data->entropy_length,
encrypted_fs_entropy_file_dst_name);
if (result != 0) {
LOGE("Secure FS: error writing ported entropy.");
return ENCRYPTED_FS_ERROR;
}
// Set the secure FS properties to their respective values
result = write_encrypted_fs_boolean_property(encrypted_fs_enabled_property, encrypted_fs_data->mode);
if (result != 0) {
return result;
}
result = ensure_path_unmounted("/data");
if (result != 0) {
LOGE("Secure FS: error unmounting data partition.");
return ENCRYPTED_FS_ERROR;
}
return ENCRYPTED_FS_OK;
}

View File

@ -1,51 +0,0 @@
/*
* Copyright (C) 2009 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <stdio.h>
#ifndef __ENCRYPTEDFS_PROVISIONING_H__
#define __ENCRYPTEDFS_PROVISIONING_H__
#define MODE_ENCRYPTED_FS_DISABLED 0
#define MODE_ENCRYPTED_FS_ENABLED 1
#define ENCRYPTED_FS_OK 0
#define ENCRYPTED_FS_ERROR (-1)
#define ENCRYPTED_FS_KEY_SIZE 16
#define ENCRYPTED_FS_SALT_SIZE 16
#define ENCRYPTED_FS_MAX_HASH_SIZE 128
#define ENTROPY_MAX_SIZE 4096
struct encrypted_fs_info {
int mode;
char key[ENCRYPTED_FS_KEY_SIZE];
char salt[ENCRYPTED_FS_SALT_SIZE];
int salt_length;
char hash[ENCRYPTED_FS_MAX_HASH_SIZE];
int hash_length;
char entropy[ENTROPY_MAX_SIZE];
int entropy_length;
};
typedef struct encrypted_fs_info encrypted_fs_info;
int read_encrypted_fs_info(encrypted_fs_info *secure_fs_data);
int restore_encrypted_fs_info(encrypted_fs_info *secure_data);
#endif /* __ENCRYPTEDFS_PROVISIONING_H__ */

View File

@ -35,8 +35,22 @@ service recovery /sbin/recovery
service adbd /sbin/adbd recovery
disabled
on property:persist.service.adb.enable=1
start adbd
# Always start adbd on userdebug and eng builds
# In recovery, always run adbd as root.
on property:ro.debuggable=1
write /sys/class/android_usb/android0/enable 0
write /sys/class/android_usb/android0/idVendor 18D1
write /sys/class/android_usb/android0/idProduct D001
write /sys/class/android_usb/android0/functions adb
#write /sys/class/android_usb/android0/enable 1
write /sys/class/android_usb/android0/iManufacturer $ro.product.manufacturer
write /sys/class/android_usb/android0/iProduct $ro.product.model
write /sys/class/android_usb/android0/iSerial $ro.serialno
#start adbd
setprop service.adb.root 1
on property:persist.service.adb.enable=0
stop adbd
# Restart adbd so it can run as root
on property:service.adb.root=1
write /sys/class/android_usb/android0/enable 0
restart adbd
write /sys/class/android_usb/android0/enable 1

View File

@ -8,7 +8,6 @@
#include <stdlib.h>
#include <string.h>
#include <sys/reboot.h>
#include <reboot/reboot.h>
#include <sys/types.h>
#include <time.h>
#include <unistd.h>
@ -26,6 +25,7 @@
#include "cutils/properties.h"
#include "firmware.h"
#include "install.h"
#include "make_ext4fs.h"
#include "minui/minui.h"
#include "minzip/DirUtil.h"
#include "roots.h"
@ -42,6 +42,7 @@
#include <libgen.h>
#include "mtdutils/mtdutils.h"
#include "bmlutils/bmlutils.h"
#include "cutils/android_reboot.h"
int signature_check_enabled = 1;
@ -444,6 +445,9 @@ int format_device(const char *device, const char *path, const char *fs_type) {
LOGE("unknown volume \"%s\"\n", path);
return -1;
}
if (strstr(path, "/data") == path && volume_for_path("/sdcard") == NULL && is_data_media()) {
return format_unknown_device(NULL, path, NULL);
}
if (strcmp(fs_type, "ramdisk") == 0) {
// you can't format the ramdisk.
LOGE("can't format_volume \"%s\"", path);
@ -495,8 +499,13 @@ int format_device(const char *device, const char *path, const char *fs_type) {
}
if (strcmp(fs_type, "ext4") == 0) {
int length = 0;
if (strcmp(v->fs_type, "ext4") == 0) {
// Our desired filesystem matches the one in fstab, respect v->length
length = v->length;
}
reset_ext4fs_info();
int result = make_ext4fs(device, NULL, NULL, 0, 0, 0);
int result = make_ext4fs(device, length);
if (result != 0) {
LOGE("format_volume: make_extf4fs failed on %s\n", device);
return -1;
@ -623,7 +632,7 @@ void show_partition_menu()
string options[255];
if(!device_volumes)
return;
return;
mountable_volumes = 0;
formatable_volumes = 0;
@ -632,25 +641,24 @@ void show_partition_menu()
format_menue = malloc(num_volumes * sizeof(FormatMenuEntry));
for (i = 0; i < num_volumes; ++i) {
Volume* v = &device_volumes[i];
if(strcmp("ramdisk", v->fs_type) != 0 && strcmp("mtd", v->fs_type) != 0 && strcmp("emmc", v->fs_type) != 0 && strcmp("bml", v->fs_type) != 0)
{
sprintf(&mount_menue[mountable_volumes].mount, "mount %s", v->mount_point);
sprintf(&mount_menue[mountable_volumes].unmount, "unmount %s", v->mount_point);
mount_menue[mountable_volumes].v = &device_volumes[i];
++mountable_volumes;
if (is_safe_to_format(v->mount_point)) {
sprintf(&format_menue[formatable_volumes].txt, "format %s", v->mount_point);
format_menue[formatable_volumes].v = &device_volumes[i];
++formatable_volumes;
}
}
else if (strcmp("ramdisk", v->fs_type) != 0 && strcmp("mtd", v->fs_type) == 0 && is_safe_to_format(v->mount_point))
{
sprintf(&format_menue[formatable_volumes].txt, "format %s", v->mount_point);
format_menue[formatable_volumes].v = &device_volumes[i];
++formatable_volumes;
}
Volume* v = &device_volumes[i];
if(strcmp("ramdisk", v->fs_type) != 0 && strcmp("mtd", v->fs_type) != 0 && strcmp("emmc", v->fs_type) != 0 && strcmp("bml", v->fs_type) != 0) {
sprintf(&mount_menue[mountable_volumes].mount, "mount %s", v->mount_point);
sprintf(&mount_menue[mountable_volumes].unmount, "unmount %s", v->mount_point);
mount_menue[mountable_volumes].v = &device_volumes[i];
++mountable_volumes;
if (is_safe_to_format(v->mount_point)) {
sprintf(&format_menue[formatable_volumes].txt, "format %s", v->mount_point);
format_menue[formatable_volumes].v = &device_volumes[i];
++formatable_volumes;
}
}
else if (strcmp("ramdisk", v->fs_type) != 0 && strcmp("mtd", v->fs_type) == 0 && is_safe_to_format(v->mount_point))
{
sprintf(&format_menue[formatable_volumes].txt, "format %s", v->mount_point);
format_menue[formatable_volumes].v = &device_volumes[i];
++formatable_volumes;
}
}
@ -660,37 +668,39 @@ void show_partition_menu()
for (;;)
{
for (i = 0; i < mountable_volumes; i++)
{
MountMenuEntry* e = &mount_menue[i];
Volume* v = e->v;
if(is_path_mounted(v->mount_point))
options[i] = e->unmount;
else
options[i] = e->mount;
}
for (i = 0; i < mountable_volumes; i++)
{
MountMenuEntry* e = &mount_menue[i];
Volume* v = e->v;
if(is_path_mounted(v->mount_point))
options[i] = e->unmount;
else
options[i] = e->mount;
}
for (i = 0; i < formatable_volumes; i++)
{
FormatMenuEntry* e = &format_menue[i];
for (i = 0; i < formatable_volumes; i++)
{
FormatMenuEntry* e = &format_menue[i];
options[mountable_volumes+i] = e->txt;
}
options[mountable_volumes+i] = e->txt;
}
options[mountable_volumes+formatable_volumes] = "mount USB storage";
options[mountable_volumes+formatable_volumes + 1] = NULL;
if (!is_data_media()) {
options[mountable_volumes + formatable_volumes] = "mount USB storage";
options[mountable_volumes + formatable_volumes + 1] = NULL;
}
else {
options[mountable_volumes + formatable_volumes] = NULL;
}
int chosen_item = get_menu_selection(headers, &options, 0, 0);
if (chosen_item == GO_BACK)
break;
if (chosen_item == (mountable_volumes+formatable_volumes))
{
if (chosen_item == (mountable_volumes+formatable_volumes)) {
show_mount_usb_storage_menu();
}
else if (chosen_item < mountable_volumes)
{
MountMenuEntry* e = &mount_menue[chosen_item];
else if (chosen_item < mountable_volumes) {
MountMenuEntry* e = &mount_menue[chosen_item];
Volume* v = e->v;
if (is_path_mounted(v->mount_point))
@ -724,7 +734,6 @@ void show_partition_menu()
free(mount_menue);
free(format_menue);
}
void show_nandroid_advanced_restore_menu(const char* path)
@ -816,7 +825,7 @@ void show_nandroid_menu()
NULL
};
if (volume_for_path("/emmc") == NULL)
if (volume_for_path("/emmc") == NULL || volume_for_path("/sdcard") == NULL && is_data_media())
list[3] = NULL;
int chosen_item = get_menu_selection(headers, list, 0, 0);
@ -894,12 +903,10 @@ void show_advanced_menu()
"Report Error",
"Key Test",
"Show log",
#ifndef BOARD_HAS_SMALL_RECOVERY
"Partition SD Card",
"Fix Permissions",
#ifdef BOARD_HAS_SDCARD_INTERNAL
"Partition Internal SD Card",
#endif
#endif
NULL
};
@ -913,7 +920,7 @@ void show_advanced_menu()
{
case 0:
{
reboot_wrapper("recovery");
android_reboot(ANDROID_RB_RESTART2, 0, "recovery");
break;
}
case 1:

View File

@ -6,7 +6,7 @@ ifeq ($(TARGET_ARCH),arm)
include $(CLEAR_VARS)
LOCAL_SRC_FILES := flashutils.c
LOCAL_MODULE := libflashutils
LOCAL_MODULE_TAGS := eng
LOCAL_MODULE_TAGS := optional
LOCAL_C_INCLUDES += bootable/recovery
LOCAL_STATIC_LIBRARIES := libmmcutils libmtdutils libbmlutils libcrecovery
@ -23,53 +23,54 @@ include $(BUILD_STATIC_LIBRARY)
include $(CLEAR_VARS)
LOCAL_SRC_FILES := flash_image.c
LOCAL_MODULE := flash_image
LOCAL_MODULE_TAGS := eng
#LOCAL_STATIC_LIBRARIES += $(BOARD_FLASH_LIBRARY)
LOCAL_STATIC_LIBRARIES := libflashutils libmtdutils libmmcutils libbmlutils
LOCAL_MODULE_TAGS := optional
LOCAL_STATIC_LIBRARIES := libflashutils libmtdutils libmmcutils libbmlutils libcrecovery
LOCAL_SHARED_LIBRARIES := libcutils libc
include $(BUILD_EXECUTABLE)
include $(CLEAR_VARS)
LOCAL_SRC_FILES := dump_image.c
LOCAL_MODULE := dump_image
LOCAL_MODULE_TAGS := eng
LOCAL_STATIC_LIBRARIES := libflashutils libmtdutils libmmcutils libbmlutils
LOCAL_MODULE_TAGS := optional
LOCAL_STATIC_LIBRARIES := libflashutils libmtdutils libmmcutils libbmlutils libcrecovery
LOCAL_SHARED_LIBRARIES := libcutils libc
include $(BUILD_EXECUTABLE)
include $(CLEAR_VARS)
LOCAL_SRC_FILES := erase_image.c
LOCAL_MODULE := erase_image
LOCAL_MODULE_TAGS := eng
LOCAL_STATIC_LIBRARIES := libflashutils libmtdutils libmmcutils libbmlutils
LOCAL_MODULE_TAGS := optional
LOCAL_STATIC_LIBRARIES := libflashutils libmtdutils libmmcutils libbmlutils libcrecovery
LOCAL_SHARED_LIBRARIES := libcutils libc
include $(BUILD_EXECUTABLE)
ALL_DEFAULT_INSTALLED_MODULES += $(addprefix $(TARGET_OUT)/bin/, flash_image dump_image erase_image)
include $(CLEAR_VARS)
LOCAL_SRC_FILES := flash_image.c
LOCAL_MODULE := libflash_image
LOCAL_MODULE_TAGS := eng
LOCAL_MODULE_TAGS := optional
LOCAL_CFLAGS += -Dmain=flash_image_main
include $(BUILD_STATIC_LIBRARY)
include $(CLEAR_VARS)
LOCAL_SRC_FILES := dump_image.c
LOCAL_MODULE := libdump_image
LOCAL_MODULE_TAGS := eng
LOCAL_MODULE_TAGS := optional
LOCAL_CFLAGS += -Dmain=dump_image_main
include $(BUILD_STATIC_LIBRARY)
include $(CLEAR_VARS)
LOCAL_SRC_FILES := erase_image.c
LOCAL_MODULE := liberase_image
LOCAL_MODULE_TAGS := eng
LOCAL_MODULE_TAGS := optional
LOCAL_CFLAGS += -Dmain=erase_image_main
include $(BUILD_STATIC_LIBRARY)
include $(CLEAR_VARS)
LOCAL_SRC_FILES := dump_image.c
LOCAL_MODULE := utility_dump_image
LOCAL_MODULE_TAGS := eng
LOCAL_MODULE_TAGS := optional
LOCAL_MODULE_CLASS := UTILITY_EXECUTABLES
LOCAL_MODULE_PATH := $(PRODUCT_OUT)/utilities
LOCAL_UNSTRIPPED_PATH := $(PRODUCT_OUT)/symbols/utilities
@ -81,7 +82,7 @@ include $(BUILD_EXECUTABLE)
include $(CLEAR_VARS)
LOCAL_SRC_FILES := flash_image.c
LOCAL_MODULE := utility_flash_image
LOCAL_MODULE_TAGS := eng
LOCAL_MODULE_TAGS := optional
LOCAL_MODULE_CLASS := UTILITY_EXECUTABLES
LOCAL_MODULE_PATH := $(PRODUCT_OUT)/utilities
LOCAL_UNSTRIPPED_PATH := $(PRODUCT_OUT)/symbols/utilities
@ -93,7 +94,7 @@ include $(BUILD_EXECUTABLE)
include $(CLEAR_VARS)
LOCAL_SRC_FILES := erase_image.c
LOCAL_MODULE := utility_erase_image
LOCAL_MODULE_TAGS := eng
LOCAL_MODULE_TAGS := optional
LOCAL_MODULE_CLASS := UTILITY_EXECUTABLES
LOCAL_MODULE_PATH := $(PRODUCT_OUT)/utilities
LOCAL_UNSTRIPPED_PATH := $(PRODUCT_OUT)/symbols/utilities

View File

@ -103,6 +103,8 @@ handle_firmware_update(char* type, char* filename, ZipArchive* zip) {
return INSTALL_SUCCESS;
}
static const char *LAST_INSTALL_FILE = "/cache/recovery/last_install";
// If the package contains an update binary, extract it and run it.
static int
try_update_binary(const char *path, ZipArchive *zip) {
@ -332,8 +334,8 @@ exit:
return NULL;
}
int
install_package(const char *path)
static int
really_install_package(const char *path)
{
ui_set_background(BACKGROUND_ICON_INSTALLING);
ui_print("Finding update package...\n");
@ -387,3 +389,23 @@ install_package(const char *path)
ui_print("Installing update...\n");
return try_update_binary(path, &zip);
}
int
install_package(const char* path)
{
FILE* install_log = fopen_path(LAST_INSTALL_FILE, "w");
if (install_log) {
fputs(path, install_log);
fputc('\n', install_log);
} else {
LOGE("failed to open last_install: %s\n", strerror(errno));
}
int result = really_install_package(path);
if (install_log) {
fputc(result == INSTALL_SUCCESS ? '1' : '0', install_log);
fputc('\n', install_log);
fclose(install_log);
chmod(LAST_INSTALL_FILE, 0644);
}
return result;
}

102
make-overlay.py Normal file
View File

@ -0,0 +1,102 @@
# Copyright (C) 2011 The Android Open Source Project
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""Script to take a set of frames (PNG files) for a recovery
"installing" icon animation and turn it into a base image plus a set
of overlays, as needed by the recovery UI code. Run with the names of
all the input frames on the command line, in order."""
import sys
try:
import Image
except ImportError:
print "This script requires the Python Imaging Library to be installed."
sys.exit(1)
# Find the smallest box that contains all the pixels which change
# between images.
print "reading", sys.argv[1]
base = Image.open(sys.argv[1])
minmini = base.size[0]-1
maxmaxi = 0
minminj = base.size[1]-1
maxmaxj = 0
for top_name in sys.argv[2:]:
print "reading", top_name
top = Image.open(top_name)
assert base.size == top.size
mini = base.size[0]-1
maxi = 0
minj = base.size[1]-1
maxj = 0
h, w = base.size
for j in range(w):
for i in range(h):
b = base.getpixel((i,j))
t = top.getpixel((i,j))
if b != t:
if i < mini: mini = i
if i > maxi: maxi = i
if j < minj: minj = j
if j > maxj: maxj = j
minmini = min(minmini, mini)
maxmaxi = max(maxmaxi, maxi)
minminj = min(minminj, minj)
maxmaxj = max(maxmaxj, maxj)
w = maxmaxi - minmini + 1
h = maxmaxj - minminj + 1
# Now write out an image containing just that box, for each frame.
for num, top_name in enumerate(sys.argv[1:]):
top = Image.open(top_name)
out = Image.new("RGB", (w, h))
for i in range(w):
for j in range(h):
t = top.getpixel((i+minmini, j+minminj))
out.putpixel((i, j), t)
fn = "icon_installing_overlay%02d.png" % (num+1,)
out.save(fn)
print "saved", fn
# Write out the base icon, which is the first frame with that box
# blacked out (just to make the file smaller, since it's always
# displayed with one of the overlays on top of it).
for i in range(w):
for j in range(h):
base.putpixel((i+minmini, j+minminj), (0, 0, 0))
fn = "icon_installing.png"
base.save(fn)
print "saved", fn
# The device_ui_init() function needs to tell the recovery UI the
# position of the overlay box.
print
print "add this to your device_ui_init() function:"
print "-" * 40
print " ui_parameters->install_overlay_offset_x = %d;" % (minmini,)
print " ui_parameters->install_overlay_offset_y = %d;" % (minminj,)
print "-" * 40

27
minelf/Android.mk Normal file
View File

@ -0,0 +1,27 @@
# Copyright (C) 2009 The Android Open Source Project
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_SRC_FILES := \
Retouch.c
LOCAL_C_INCLUDES += bootable/recovery
LOCAL_MODULE := libminelf
LOCAL_CFLAGS += -Wall
include $(BUILD_STATIC_LIBRARY)

406
minelf/Retouch.c Normal file
View File

@ -0,0 +1,406 @@
/*
* Copyright (C) 2009 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <errno.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <strings.h>
#include "Retouch.h"
#include "applypatch/applypatch.h"
typedef struct {
int32_t mmap_addr;
char tag[4]; /* 'P', 'R', 'E', ' ' */
} prelink_info_t __attribute__((packed));
#define false 0
#define true 1
static int32_t offs_prev;
static uint32_t cont_prev;
static void init_compression_state(void) {
offs_prev = 0;
cont_prev = 0;
}
// For details on the encoding used for relocation lists, please
// refer to build/tools/retouch/retouch-prepare.c. The intent is to
// save space by removing most of the inherent redundancy.
static void decode_bytes(uint8_t *encoded_bytes, int encoded_size,
int32_t *dst_offset, uint32_t *dst_contents) {
if (encoded_size == 2) {
*dst_offset = offs_prev + (((encoded_bytes[0]&0x60)>>5)+1)*4;
// if the original was negative, we need to 1-pad before applying delta
int32_t tmp = (((encoded_bytes[0] & 0x0000001f) << 8) |
encoded_bytes[1]);
if (tmp & 0x1000) tmp = 0xffffe000 | tmp;
*dst_contents = cont_prev + tmp;
} else if (encoded_size == 3) {
*dst_offset = offs_prev + (((encoded_bytes[0]&0x30)>>4)+1)*4;
// if the original was negative, we need to 1-pad before applying delta
int32_t tmp = (((encoded_bytes[0] & 0x0000000f) << 16) |
(encoded_bytes[1] << 8) |
encoded_bytes[2]);
if (tmp & 0x80000) tmp = 0xfff00000 | tmp;
*dst_contents = cont_prev + tmp;
} else {
*dst_offset =
(encoded_bytes[0]<<24) |
(encoded_bytes[1]<<16) |
(encoded_bytes[2]<<8) |
encoded_bytes[3];
if (*dst_offset == 0x3fffffff) *dst_offset = -1;
*dst_contents =
(encoded_bytes[4]<<24) |
(encoded_bytes[5]<<16) |
(encoded_bytes[6]<<8) |
encoded_bytes[7];
}
}
static uint8_t *decode_in_memory(uint8_t *encoded_bytes,
int32_t *offset, uint32_t *contents) {
int input_size, charIx;
uint8_t input[8];
input[0] = *(encoded_bytes++);
if (input[0] & 0x80)
input_size = 2;
else if (input[0] & 0x40)
input_size = 3;
else
input_size = 8;
// we already read one byte..
charIx = 1;
while (charIx < input_size) {
input[charIx++] = *(encoded_bytes++);
}
// depends on the decoder state!
decode_bytes(input, input_size, offset, contents);
offs_prev = *offset;
cont_prev = *contents;
return encoded_bytes;
}
int retouch_mask_data(uint8_t *binary_object,
int32_t binary_size,
int32_t *desired_offset,
int32_t *retouch_offset) {
retouch_info_t *r_info;
prelink_info_t *p_info;
int32_t target_offset = 0;
if (desired_offset) target_offset = *desired_offset;
int32_t p_offs = binary_size-sizeof(prelink_info_t); // prelink_info_t
int32_t r_offs = p_offs-sizeof(retouch_info_t); // retouch_info_t
int32_t b_offs; // retouch data blob
// If not retouched, we say it was a match. This might get invoked on
// non-retouched binaries, so that's why we need to do this.
if (retouch_offset != NULL) *retouch_offset = target_offset;
if (r_offs < 0) return (desired_offset == NULL) ?
RETOUCH_DATA_NOTAPPLICABLE : RETOUCH_DATA_MATCHED;
p_info = (prelink_info_t *)(binary_object+p_offs);
r_info = (retouch_info_t *)(binary_object+r_offs);
if (strncmp(p_info->tag, "PRE ", 4) ||
strncmp(r_info->tag, "RETOUCH ", 8))
return (desired_offset == NULL) ?
RETOUCH_DATA_NOTAPPLICABLE : RETOUCH_DATA_MATCHED;
b_offs = r_offs-r_info->blob_size;
if (b_offs < 0) {
printf("negative binary offset: %d = %d - %d\n",
b_offs, r_offs, r_info->blob_size);
return RETOUCH_DATA_ERROR;
}
uint8_t *b_ptr = binary_object+b_offs;
// Retouched: let's go through the work then.
int32_t offset_candidate = target_offset;
bool offset_set = false, offset_mismatch = false;
init_compression_state();
while (b_ptr < (uint8_t *)r_info) {
int32_t retouch_entry_offset;
uint32_t *retouch_entry;
uint32_t retouch_original_value;
b_ptr = decode_in_memory(b_ptr,
&retouch_entry_offset,
&retouch_original_value);
if (retouch_entry_offset < (-1) ||
retouch_entry_offset >= b_offs) {
printf("bad retouch_entry_offset: %d", retouch_entry_offset);
return RETOUCH_DATA_ERROR;
}
// "-1" means this is the value in prelink_info_t, which also gets
// randomized.
if (retouch_entry_offset == -1)
retouch_entry = (uint32_t *)&(p_info->mmap_addr);
else
retouch_entry = (uint32_t *)(binary_object+retouch_entry_offset);
if (desired_offset)
*retouch_entry = retouch_original_value + target_offset;
// Infer the randomization shift, compare to previously inferred.
int32_t offset_of_this_entry = (int32_t)(*retouch_entry-
retouch_original_value);
if (!offset_set) {
offset_candidate = offset_of_this_entry;
offset_set = true;
} else {
if (offset_candidate != offset_of_this_entry) {
offset_mismatch = true;
printf("offset is mismatched: %d, this entry is %d,"
" original 0x%x @ 0x%x",
offset_candidate, offset_of_this_entry,
retouch_original_value, retouch_entry_offset);
}
}
}
if (b_ptr > (uint8_t *)r_info) {
printf("b_ptr went too far: %p, while r_info is %p",
b_ptr, r_info);
return RETOUCH_DATA_ERROR;
}
if (offset_mismatch) return RETOUCH_DATA_MISMATCHED;
if (retouch_offset != NULL) *retouch_offset = offset_candidate;
return RETOUCH_DATA_MATCHED;
}
// On success, _override is set to the offset that was actually applied.
// This implies that once we randomize to an offset we stick with it.
// This in turn is necessary in order to guarantee recovery after crash.
bool retouch_one_library(const char *binary_name,
const char *binary_sha1,
int32_t retouch_offset,
int32_t *retouch_offset_override) {
bool success = true;
int result;
FileContents file;
file.data = NULL;
char binary_name_atomic[strlen(binary_name)+10];
strcpy(binary_name_atomic, binary_name);
strcat(binary_name_atomic, ".atomic");
// We need a path that exists for calling statfs() later.
//
// Assume that binary_name (eg "/system/app/Foo.apk") is located
// on the same filesystem as its top-level directory ("/system").
char target_fs[strlen(binary_name)+1];
char* slash = strchr(binary_name+1, '/');
if (slash != NULL) {
int count = slash - binary_name;
strncpy(target_fs, binary_name, count);
target_fs[count] = '\0';
} else {
strcpy(target_fs, binary_name);
}
result = LoadFileContents(binary_name, &file, RETOUCH_DONT_MASK);
if (result == 0) {
// Figure out the *apparent* offset to which this file has been
// retouched. If it looks good, we will skip processing (we might
// have crashed and during this recovery pass we don't want to
// overwrite a valuable saved file in /cache---which would happen
// if we blindly retouch everything again). NOTE: This implies
// that we might have to override the supplied retouch offset. We
// can do the override only once though: everything should match
// afterward.
int32_t inferred_offset;
int retouch_probe_result = retouch_mask_data(file.data,
file.size,
NULL,
&inferred_offset);
if (retouch_probe_result == RETOUCH_DATA_MATCHED) {
if ((retouch_offset == inferred_offset) ||
((retouch_offset != 0 && inferred_offset != 0) &&
(retouch_offset_override != NULL))) {
// This file is OK already and we are allowed to override.
// Let's just return the offset override value. It is critical
// to skip regardless of override: a broken file might need
// recovery down the list and we should not mess up the saved
// copy by doing unnecessary retouching.
//
// NOTE: If retouching was already started with a different
// value, we will not be allowed to override. This happens
// if on the retouch list there is a patched binary (which is
// masked in apply_patch()) before there is a non-patched
// binary.
if (retouch_offset_override != NULL)
*retouch_offset_override = inferred_offset;
success = true;
goto out;
} else {
// Retouch to zero (mask the retouching), to make sure that
// the SHA-1 check will pass below.
int32_t zero = 0;
retouch_mask_data(file.data, file.size, &zero, NULL);
SHA(file.data, file.size, file.sha1);
}
}
if (retouch_probe_result == RETOUCH_DATA_NOTAPPLICABLE) {
// In the case of not retouchable, fake it. We do not want
// to do the normal processing and overwrite the backup file:
// we might be recovering!
//
// We return a zero override, which tells the caller that we
// simply skipped the file.
if (retouch_offset_override != NULL)
*retouch_offset_override = 0;
success = true;
goto out;
}
// If we get here, either there was a mismatch in the offset, or
// the file has not been processed yet. Continue with normal
// processing.
}
if (result != 0 || FindMatchingPatch(file.sha1, &binary_sha1, 1) < 0) {
free(file.data);
printf("Attempting to recover source from '%s' ...\n",
CACHE_TEMP_SOURCE);
result = LoadFileContents(CACHE_TEMP_SOURCE, &file, RETOUCH_DO_MASK);
if (result != 0 || FindMatchingPatch(file.sha1, &binary_sha1, 1) < 0) {
printf(" failed.\n");
success = false;
goto out;
}
printf(" succeeded.\n");
}
// Retouch in-memory before worrying about backing up the original.
//
// Recovery steps will be oblivious to the actual retouch offset used,
// so might as well write out the already-retouched copy. Then, in the
// usual case, we will just swap the file locally, with no more writes
// needed. In the no-free-space case, we will then write the same to the
// original location.
result = retouch_mask_data(file.data, file.size, &retouch_offset, NULL);
if (result != RETOUCH_DATA_MATCHED) {
success = false;
goto out;
}
if (retouch_offset_override != NULL)
*retouch_offset_override = retouch_offset;
// How much free space do we need?
bool enough_space = false;
size_t free_space = FreeSpaceForFile(target_fs);
// 50% margin when estimating the space needed.
enough_space = (free_space > (file.size * 3 / 2));
// The experts say we have to allow for a retry of the
// whole process to avoid filesystem weirdness.
int retry = 1;
bool made_copy = false;
do {
// First figure out where to store a copy of the original.
// Ideally leave the original itself intact until the
// atomic swap. If no room on the same partition, fall back
// to the cache partition and remove the original.
if (!enough_space) {
printf("Target is %ldB; free space is %ldB: not enough.\n",
(long)file.size, (long)free_space);
retry = 0;
if (MakeFreeSpaceOnCache(file.size) < 0) {
printf("Not enough free space on '/cache'.\n");
success = false;
goto out;
}
if (SaveFileContents(CACHE_TEMP_SOURCE, file) < 0) {
printf("Failed to back up source file.\n");
success = false;
goto out;
}
made_copy = true;
unlink(binary_name);
size_t free_space = FreeSpaceForFile(target_fs);
printf("(now %ld bytes free for target)\n", (long)free_space);
}
result = SaveFileContents(binary_name_atomic, file);
if (result != 0) {
// Maybe the filesystem was optimistic: retry.
enough_space = false;
unlink(binary_name_atomic);
printf("Saving the retouched contents failed; retrying.\n");
continue;
}
// Succeeded; no need to retry.
break;
} while (retry-- > 0);
// Give the .atomic file the same owner, group, and mode of the
// original source file.
if (chmod(binary_name_atomic, file.st.st_mode) != 0) {
printf("chmod of \"%s\" failed: %s\n",
binary_name_atomic, strerror(errno));
success = false;
goto out;
}
if (chown(binary_name_atomic, file.st.st_uid, file.st.st_gid) != 0) {
printf("chown of \"%s\" failed: %s\n",
binary_name_atomic,
strerror(errno));
success = false;
goto out;
}
// Finally, rename the .atomic file to replace the target file.
if (rename(binary_name_atomic, binary_name) != 0) {
printf("rename of .atomic to \"%s\" failed: %s\n",
binary_name, strerror(errno));
success = false;
goto out;
}
// If this run created a copy, and we're here, we can delete it.
if (made_copy) unlink(CACHE_TEMP_SOURCE);
out:
// clean up
free(file.data);
unlink(binary_name_atomic);
return success;
}

51
minelf/Retouch.h Normal file
View File

@ -0,0 +1,51 @@
/*
* Copyright (C) 2009 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef _MINELF_RETOUCH
#define _MINELF_RETOUCH
#include <stdbool.h>
#include <sys/types.h>
typedef struct {
char tag[8]; /* "RETOUCH ", not zero-terminated */
uint32_t blob_size; /* in bytes, located right before this struct */
} retouch_info_t __attribute__((packed));
// Retouch a file. Use CACHED_SOURCE_TEMP to store a copy.
bool retouch_one_library(const char *binary_name,
const char *binary_sha1,
int32_t retouch_offset,
int32_t *retouch_offset_override);
#define RETOUCH_DONT_MASK 0
#define RETOUCH_DO_MASK 1
#define RETOUCH_DATA_ERROR 0 // This is bad. Should not happen.
#define RETOUCH_DATA_MATCHED 1 // Up to an uniform random offset.
#define RETOUCH_DATA_MISMATCHED 2 // Partially randomized, or total mess.
#define RETOUCH_DATA_NOTAPPLICABLE 3 // Not retouched. Only when inferring.
// Mask retouching in-memory. Used before apply_patch[_check].
// Also used to determine status of retouching after a crash.
//
// If desired_offset is not NULL, then apply retouching instead,
// and return that in retouch_offset.
int retouch_mask_data(uint8_t *binary_object,
int32_t binary_size,
int32_t *desired_offset,
int32_t *retouch_offset);
#endif

View File

@ -12,18 +12,17 @@ LOCAL_C_INCLUDES +=\
external/libpng\
external/zlib
ifneq ($(BOARD_LDPI_RECOVERY),)
LOCAL_CFLAGS += -DBOARD_LDPI_RECOVERY='"$(BOARD_LDPI_RECOVERY)"'
endif
ifneq ($(BOARD_HAS_JANKY_BACKBUFFER),)
LOCAL_CFLAGS += -DBOARD_HAS_JANKY_BACKBUFFER
endif
ifeq ($(BOARD_HAS_FLIPPED_SCREEN), true)
LOCAL_CFLAGS += -DBOARD_HAS_FLIPPED_SCREEN
endif
LOCAL_MODULE := libminui
ifeq ($(TARGET_RECOVERY_PIXEL_FORMAT),"RGBX_8888")
LOCAL_CFLAGS += -DRECOVERY_RGBX
endif
ifeq ($(TARGET_RECOVERY_PIXEL_FORMAT),"BGRA_8888")
LOCAL_CFLAGS += -DRECOVERY_BGRA
endif
ifneq ($(BOARD_USE_CUSTOM_RECOVERY_FONT),)
LOCAL_CFLAGS += -DBOARD_USE_CUSTOM_RECOVERY_FONT=$(BOARD_USE_CUSTOM_RECOVERY_FONT)
endif
include $(BUILD_STATIC_LIBRARY)

View File

@ -19,167 +19,33 @@
#include <fcntl.h>
#include <dirent.h>
#include <sys/poll.h>
#include <limits.h>
#include <linux/input.h>
#include "../common.h"
#include "minui.h"
#define MAX_DEVICES 16
#define MAX_MISC_FDS 16
#define VIBRATOR_TIMEOUT_FILE "/sys/class/timed_output/vibrator/enable"
#define VIBRATOR_TIME_MS 50
#define BITS_PER_LONG (sizeof(unsigned long) * 8)
#define BITS_TO_LONGS(x) (((x) + BITS_PER_LONG - 1) / BITS_PER_LONG)
#define PRESS_THRESHHOLD 10
#define test_bit(bit, array) \
((array)[(bit)/BITS_PER_LONG] & (1 << ((bit) % BITS_PER_LONG)))
#define ABS_MT_POSITION_X 0x35
#define ABS_MT_POSITION_Y 0x36
#define ABS_MT_TOUCH_MAJOR 0x30
#define SYN_MT_REPORT 2
struct virtualkey {
int scancode;
int centerx, centery;
int width, height;
struct fd_info {
ev_callback cb;
void *data;
};
struct position {
int x, y;
int pressed;
struct input_absinfo xi, yi;
};
static struct pollfd ev_fds[MAX_DEVICES + MAX_MISC_FDS];
static struct fd_info ev_fdinfo[MAX_DEVICES + MAX_MISC_FDS];
struct ev {
struct pollfd *fd;
struct virtualkey *vks;
int vk_count;
struct position p, mt_p;
int sent, mt_idx;
};
static struct pollfd ev_fds[MAX_DEVICES];
static struct ev evs[MAX_DEVICES];
static unsigned ev_count = 0;
static unsigned ev_dev_count = 0;
static unsigned ev_misc_count = 0;
static inline int ABS(int x) {
return x<0?-x:x;
}
int vibrate(int timeout_ms)
{
char str[20];
int fd;
int ret;
fd = open(VIBRATOR_TIMEOUT_FILE, O_WRONLY);
if (fd < 0)
return -1;
ret = snprintf(str, sizeof(str), "%d", timeout_ms);
ret = write(fd, str, ret);
close(fd);
if (ret < 0)
return -1;
return 0;
}
/* Returns empty tokens */
static char *vk_strtok_r(char *str, const char *delim, char **save_str)
{
if(!str) {
if(!*save_str) return NULL;
str = (*save_str) + 1;
}
*save_str = strpbrk(str, delim);
if(*save_str) **save_str = '\0';
return str;
}
static int vk_init(struct ev *e)
{
char vk_path[PATH_MAX] = "/sys/board_properties/virtualkeys.";
char vks[2048], *ts;
ssize_t len;
int vk_fd;
int i;
e->vk_count = 0;
len = strlen(vk_path);
len = ioctl(e->fd->fd, EVIOCGNAME(sizeof(vk_path) - len), vk_path + len);
if (len <= 0)
return -1;
vk_fd = open(vk_path, O_RDONLY);
if (vk_fd < 0)
return -1;
len = read(vk_fd, vks, sizeof(vks)-1);
close(vk_fd);
if (len <= 0)
return -1;
vks[len] = '\0';
/* Parse a line like:
keytype:keycode:centerx:centery:width:height:keytype2:keycode2:centerx2:...
*/
for (ts = vks, e->vk_count = 1; *ts; ++ts) {
if (*ts == ':')
++e->vk_count;
}
if (e->vk_count % 6) {
LOGW("minui: %s is %d %% 6\n", vk_path, e->vk_count % 6);
}
e->vk_count /= 6;
if (e->vk_count <= 0)
return -1;
e->sent = 0;
e->mt_idx = 0;
ioctl(e->fd->fd, EVIOCGABS(ABS_X), &e->p.xi);
ioctl(e->fd->fd, EVIOCGABS(ABS_Y), &e->p.yi);
e->p.pressed = 0;
ioctl(e->fd->fd, EVIOCGABS(ABS_MT_POSITION_X), &e->mt_p.xi);
ioctl(e->fd->fd, EVIOCGABS(ABS_MT_POSITION_Y), &e->mt_p.yi);
e->mt_p.pressed = 0;
e->vks = malloc(sizeof(*e->vks) * e->vk_count);
for (i = 0; i < e->vk_count; ++i) {
char *token[6];
int j;
for (j = 0; j < 6; ++j) {
token[j] = vk_strtok_r((i||j)?NULL:vks, ":", &ts);
}
if (strcmp(token[0], "0x01") != 0) {
/* Java does string compare, so we do too. */
LOGW("minui: %s: ignoring unknown virtual key type %s\n", vk_path, token[0]);
continue;
}
e->vks[i].scancode = strtol(token[1], NULL, 0);
e->vks[i].centerx = strtol(token[2], NULL, 0);
e->vks[i].centery = strtol(token[3], NULL, 0);
e->vks[i].width = strtol(token[4], NULL, 0);
e->vks[i].height = strtol(token[5], NULL, 0);
}
return 0;
}
int ev_init(void)
int ev_init(ev_callback input_cb, void *data)
{
DIR *dir;
struct dirent *de;
@ -188,177 +54,122 @@ int ev_init(void)
dir = opendir("/dev/input");
if(dir != 0) {
while((de = readdir(dir))) {
unsigned long ev_bits[BITS_TO_LONGS(EV_MAX)];
// fprintf(stderr,"/dev/input/%s\n", de->d_name);
if(strncmp(de->d_name,"event",5)) continue;
fd = openat(dirfd(dir), de->d_name, O_RDONLY);
if(fd < 0) continue;
/* read the evbits of the input device */
if (ioctl(fd, EVIOCGBIT(0, sizeof(ev_bits)), ev_bits) < 0) {
close(fd);
continue;
}
/* TODO: add ability to specify event masks. For now, just assume
* that only EV_KEY and EV_REL event types are ever needed. */
if (!test_bit(EV_KEY, ev_bits) && !test_bit(EV_REL, ev_bits)) {
close(fd);
continue;
}
ev_fds[ev_count].fd = fd;
ev_fds[ev_count].events = POLLIN;
evs[ev_count].fd = &ev_fds[ev_count];
/* Load virtualkeys if there are any */
vk_init(&evs[ev_count]);
ev_fdinfo[ev_count].cb = input_cb;
ev_fdinfo[ev_count].data = data;
ev_count++;
if(ev_count == MAX_DEVICES) break;
ev_dev_count++;
if(ev_dev_count == MAX_DEVICES) break;
}
}
return 0;
}
int ev_add_fd(int fd, ev_callback cb, void *data)
{
if (ev_misc_count == MAX_MISC_FDS || cb == NULL)
return -1;
ev_fds[ev_count].fd = fd;
ev_fds[ev_count].events = POLLIN;
ev_fdinfo[ev_count].cb = cb;
ev_fdinfo[ev_count].data = data;
ev_count++;
ev_misc_count++;
return 0;
}
void ev_exit(void)
{
while (ev_count-- > 0) {
if (evs[ev_count].vk_count) {
free(evs[ev_count].vks);
evs[ev_count].vk_count = 0;
}
close(ev_fds[ev_count].fd);
while (ev_count > 0) {
close(ev_fds[--ev_count].fd);
}
ev_misc_count = 0;
ev_dev_count = 0;
}
static int vk_inside_display(__s32 value, struct input_absinfo *info, int screen_size)
{
int screen_pos;
if (info->minimum == info->maximum)
return 0;
screen_pos = (value - info->minimum) * (screen_size - 1) / (info->maximum - info->minimum);
return (screen_pos >= 0 && screen_pos < screen_size);
}
static int vk_tp_to_screen(struct position *p, int *x, int *y)
{
if (p->xi.minimum == p->xi.maximum || p->yi.minimum == p->yi.maximum)
return 0;
*x = (p->x - p->xi.minimum) * (gr_fb_width() - 1) / (p->xi.maximum - p->xi.minimum);
*y = (p->y - p->yi.minimum) * (gr_fb_height() - 1) / (p->yi.maximum - p->yi.minimum);
if (*x >= 0 && *x < gr_fb_width() &&
*y >= 0 && *y < gr_fb_height()) {
return 0;
}
return 1;
}
/* Translate a virtual key in to a real key event, if needed */
/* Returns non-zero when the event should be consumed */
static int vk_modify(struct ev *e, struct input_event *ev)
{
int i;
int x, y;
if (ev->type == EV_KEY) {
if (ev->code == BTN_TOUCH)
e->p.pressed = ev->value;
return 0;
}
if (ev->type == EV_ABS) {
switch (ev->code) {
case ABS_X:
e->p.x = ev->value;
return !vk_inside_display(e->p.x, &e->p.xi, gr_fb_width());
case ABS_Y:
e->p.y = ev->value;
return !vk_inside_display(e->p.y, &e->p.yi, gr_fb_height());
case ABS_MT_POSITION_X:
if (e->mt_idx) return 1;
e->mt_p.x = ev->value;
return !vk_inside_display(e->mt_p.x, &e->mt_p.xi, gr_fb_width());
case ABS_MT_POSITION_Y:
if (e->mt_idx) return 1;
e->mt_p.y = ev->value;
return !vk_inside_display(e->mt_p.y, &e->mt_p.yi, gr_fb_height());
case ABS_MT_TOUCH_MAJOR:
if (e->mt_idx) return 1;
if (e->sent)
e->mt_p.pressed = (ev->value > 0);
else
e->mt_p.pressed = (ev->value > PRESS_THRESHHOLD);
return 0;
}
return 0;
}
if (ev->type != EV_SYN)
return 0;
if (ev->code == SYN_MT_REPORT) {
/* Ignore the rest of the points */
++e->mt_idx;
return 1;
}
if (ev->code != SYN_REPORT)
return 0;
/* Report complete */
e->mt_idx = 0;
if (!e->p.pressed && !e->mt_p.pressed) {
/* No touch */
e->sent = 0;
return 0;
}
if (!(e->p.pressed && vk_tp_to_screen(&e->p, &x, &y)) &&
!(e->mt_p.pressed && vk_tp_to_screen(&e->mt_p, &x, &y))) {
/* No touch inside vk area */
return 0;
}
if (e->sent) {
/* We've already sent a fake key for this touch */
return 1;
}
/* The screen is being touched on the vk area */
e->sent = 1;
for (i = 0; i < e->vk_count; ++i) {
int xd = ABS(e->vks[i].centerx - x);
int yd = ABS(e->vks[i].centery - y);
if (xd < e->vks[i].width/2 && yd < e->vks[i].height/2) {
/* Fake a key event */
ev->type = EV_KEY;
ev->code = e->vks[i].scancode;
ev->value = 1;
vibrate(VIBRATOR_TIME_MS);
return 0;
}
}
return 1;
}
int ev_get(struct input_event *ev, unsigned dont_wait)
int ev_wait(int timeout)
{
int r;
r = poll(ev_fds, ev_count, timeout);
if (r <= 0)
return -1;
return 0;
}
void ev_dispatch(void)
{
unsigned n;
int ret;
do {
r = poll(ev_fds, ev_count, dont_wait ? 0 : -1);
for (n = 0; n < ev_count; n++) {
ev_callback cb = ev_fdinfo[n].cb;
if (cb && (ev_fds[n].revents & ev_fds[n].events))
cb(ev_fds[n].fd, ev_fds[n].revents, ev_fdinfo[n].data);
}
}
if(r > 0) {
for(n = 0; n < ev_count; n++) {
if(ev_fds[n].revents & POLLIN) {
r = read(ev_fds[n].fd, ev, sizeof(*ev));
if(r == sizeof(*ev)) {
if (!vk_modify(&evs[n], ev))
return 0;
}
}
}
}
} while(dont_wait == 0);
int ev_get_input(int fd, short revents, struct input_event *ev)
{
int r;
if (revents & POLLIN) {
r = read(fd, ev, sizeof(*ev));
if (r == sizeof(*ev))
return 0;
}
return -1;
}
int ev_sync_key_state(ev_set_key_callback set_key_cb, void *data)
{
unsigned long key_bits[BITS_TO_LONGS(KEY_MAX)];
unsigned long ev_bits[BITS_TO_LONGS(EV_MAX)];
unsigned i;
int ret;
for (i = 0; i < ev_dev_count; i++) {
int code;
memset(key_bits, 0, sizeof(key_bits));
memset(ev_bits, 0, sizeof(ev_bits));
ret = ioctl(ev_fds[i].fd, EVIOCGBIT(0, sizeof(ev_bits)), ev_bits);
if (ret < 0 || !test_bit(EV_KEY, ev_bits))
continue;
ret = ioctl(ev_fds[i].fd, EVIOCGKEY(sizeof(key_bits)), key_bits);
if (ret < 0)
continue;
for (code = 0; code <= KEY_MAX; code++) {
if (test_bit(code, key_bits))
set_key_cb(code, 1, data);
}
}
return 0;
}

View File

@ -14,6 +14,7 @@
* limitations under the License.
*/
#include <stdbool.h>
#include <stdlib.h>
#include <unistd.h>
@ -29,14 +30,25 @@
#include <pixelflinger/pixelflinger.h>
#ifndef BOARD_LDPI_RECOVERY
#include "font_10x18.h"
#ifdef BOARD_USE_CUSTOM_RECOVERY_FONT
#include BOARD_USE_CUSTOM_RECOVERY_FONT
#else
#include "font_7x16.h"
#include "font_10x18.h"
#endif
#include "minui.h"
#if defined(RECOVERY_BGRA)
#define PIXEL_FORMAT GGL_PIXEL_FORMAT_BGRA_8888
#define PIXEL_SIZE 4
#elif defined(RECOVERY_RGBX)
#define PIXEL_FORMAT GGL_PIXEL_FORMAT_RGBX_8888
#define PIXEL_SIZE 4
#else
#define PIXEL_FORMAT GGL_PIXEL_FORMAT_RGB_565
#define PIXEL_SIZE 2
#endif
typedef struct {
GGLSurface texture;
unsigned cwidth;
@ -55,11 +67,11 @@ static int gr_fb_fd = -1;
static int gr_vt_fd = -1;
static struct fb_var_screeninfo vi;
static struct fb_fix_screeninfo fi;
static int get_framebuffer(GGLSurface *fb)
{
int fd;
struct fb_fix_screeninfo fi;
void *bits;
fd = open("/dev/graphics/fb0", O_RDWR);
@ -68,13 +80,48 @@ static int get_framebuffer(GGLSurface *fb)
return -1;
}
if (ioctl(fd, FBIOGET_FSCREENINFO, &fi) < 0) {
if (ioctl(fd, FBIOGET_VSCREENINFO, &vi) < 0) {
perror("failed to get fb0 info");
close(fd);
return -1;
}
if (ioctl(fd, FBIOGET_VSCREENINFO, &vi) < 0) {
vi.bits_per_pixel = PIXEL_SIZE * 8;
if (PIXEL_FORMAT == GGL_PIXEL_FORMAT_BGRA_8888) {
vi.red.offset = 8;
vi.red.length = 8;
vi.green.offset = 16;
vi.green.length = 8;
vi.blue.offset = 24;
vi.blue.length = 8;
vi.transp.offset = 0;
vi.transp.length = 8;
} else if (PIXEL_FORMAT == GGL_PIXEL_FORMAT_RGBX_8888) {
vi.red.offset = 24;
vi.red.length = 8;
vi.green.offset = 16;
vi.green.length = 8;
vi.blue.offset = 8;
vi.blue.length = 8;
vi.transp.offset = 0;
vi.transp.length = 8;
} else { /* RGB565*/
vi.red.offset = 11;
vi.red.length = 5;
vi.green.offset = 5;
vi.green.length = 6;
vi.blue.offset = 0;
vi.blue.length = 5;
vi.transp.offset = 0;
vi.transp.length = 0;
}
if (ioctl(fd, FBIOPUT_VSCREENINFO, &vi) < 0) {
perror("failed to put fb0 info");
close(fd);
return -1;
}
if (ioctl(fd, FBIOGET_FSCREENINFO, &fi) < 0) {
perror("failed to get fb0 info");
close(fd);
return -1;
@ -90,29 +137,20 @@ static int get_framebuffer(GGLSurface *fb)
fb->version = sizeof(*fb);
fb->width = vi.xres;
fb->height = vi.yres;
#ifdef BOARD_HAS_JANKY_BACKBUFFER
fb->stride = fi.line_length/2;
#else
fb->stride = vi.xres;
#endif
fb->stride = fi.line_length/PIXEL_SIZE;
fb->data = bits;
fb->format = GGL_PIXEL_FORMAT_RGB_565;
memset(fb->data, 0, vi.yres * vi.xres * 2);
fb->format = PIXEL_FORMAT;
memset(fb->data, 0, vi.yres * fi.line_length);
fb++;
fb->version = sizeof(*fb);
fb->width = vi.xres;
fb->height = vi.yres;
#ifdef BOARD_HAS_JANKY_BACKBUFFER
fb->stride = fi.line_length/2;
fb->stride = fi.line_length/PIXEL_SIZE;
fb->data = (void*) (((unsigned) bits) + vi.yres * fi.line_length);
#else
fb->stride = vi.xres;
fb->data = (void*) (((unsigned) bits) + vi.yres * vi.xres * 2);
#endif
fb->format = GGL_PIXEL_FORMAT_RGB_565;
memset(fb->data, 0, vi.yres * vi.xres * 2);
fb->format = PIXEL_FORMAT;
memset(fb->data, 0, vi.yres * fi.line_length);
return fd;
}
@ -121,17 +159,17 @@ static void get_memory_surface(GGLSurface* ms) {
ms->version = sizeof(*ms);
ms->width = vi.xres;
ms->height = vi.yres;
ms->stride = vi.xres;
ms->data = malloc(vi.xres * vi.yres * 2);
ms->format = GGL_PIXEL_FORMAT_RGB_565;
ms->stride = fi.line_length/PIXEL_SIZE;
ms->data = malloc(fi.line_length * vi.yres);
ms->format = PIXEL_FORMAT;
}
static void set_active_framebuffer(unsigned n)
{
if (n > 1) return;
vi.yres_virtual = vi.yres * 2;
vi.yres_virtual = vi.yres * PIXEL_SIZE;
vi.yoffset = n * vi.yres;
vi.bits_per_pixel = 16;
vi.bits_per_pixel = PIXEL_SIZE * 8;
if (ioctl(gr_fb_fd, FBIOPUT_VSCREENINFO, &vi) < 0) {
perror("active fb swap failed");
}
@ -144,20 +182,10 @@ void gr_flip(void)
/* swap front and back buffers */
gr_active_fb = (gr_active_fb + 1) & 1;
#ifdef BOARD_HAS_FLIPPED_SCREEN
/* flip buffer 180 degrees for devices with physicaly inverted screens */
unsigned int i;
for (i = 1; i < (vi.xres * vi.yres); i++) {
unsigned short tmp = gr_mem_surface.data[i];
gr_mem_surface.data[i] = gr_mem_surface.data[(vi.xres * vi.yres * 2) - i];
gr_mem_surface.data[(vi.xres * vi.yres * 2) - i] = tmp;
}
#endif
/* copy data from the in-memory surface to the buffer we're about
* to make active. */
memcpy(gr_framebuffer[gr_active_fb].data, gr_mem_surface.data,
vi.xres * vi.yres * 2);
fi.line_length * vi.yres);
/* inform the display driver */
set_active_framebuffer(gr_active_fb);
@ -179,6 +207,12 @@ int gr_measure(const char *s)
return gr_font->cwidth * strlen(s);
}
void gr_font_size(int *x, int *y)
{
*x = gr_font->cwidth;
*y = gr_font->cheight;
}
int gr_text(int x, int y, const char *s)
{
GGLContext *gl = gr_context;
@ -307,6 +341,9 @@ int gr_init(void)
gl->enable(gl, GGL_BLEND);
gl->blendFunc(gl, GGL_SRC_ALPHA, GGL_ONE_MINUS_SRC_ALPHA);
gr_fb_blank(true);
gr_fb_blank(false);
return 0;
}
@ -337,3 +374,11 @@ gr_pixel *gr_fb_data(void)
return (unsigned short *) gr_mem_surface.data;
}
void gr_fb_blank(bool blank)
{
int ret;
ret = ioctl(gr_fb_fd, FBIOBLANK, blank ? FB_BLANK_POWERDOWN : FB_BLANK_UNBLANK);
if (ret < 0)
perror("ioctl(): blank");
}

View File

@ -17,6 +17,8 @@
#ifndef _MINUI_H_
#define _MINUI_H_
#include <stdbool.h>
typedef void* gr_surface;
typedef unsigned short gr_pixel;
@ -27,11 +29,13 @@ int gr_fb_width(void);
int gr_fb_height(void);
gr_pixel *gr_fb_data(void);
void gr_flip(void);
void gr_fb_blank(bool blank);
void gr_color(unsigned char r, unsigned char g, unsigned char b, unsigned char a);
void gr_fill(int x, int y, int w, int h);
int gr_text(int x, int y, const char *s);
int gr_measure(const char *s);
void gr_font_size(int *x, int *y);
void gr_blit(gr_surface source, int sx, int sy, int w, int h, int dx, int dy);
unsigned int gr_get_width(gr_surface surface);
@ -41,9 +45,23 @@ unsigned int gr_get_height(gr_surface surface);
// see http://www.mjmwired.net/kernel/Documentation/input/ for info.
struct input_event;
int ev_init(void);
typedef int (*ev_callback)(int fd, short revents, void *data);
typedef int (*ev_set_key_callback)(int code, int value, void *data);
int ev_init(ev_callback input_cb, void *data);
void ev_exit(void);
int ev_get(struct input_event *ev, unsigned dont_wait);
int ev_add_fd(int fd, ev_callback cb, void *data);
int ev_sync_key_state(ev_set_key_callback set_key_cb, void *data);
/* timeout has the same semantics as for poll
* 0 : don't block
* < 0 : block forever
* > 0 : block for 'timeout' milliseconds
*/
int ev_wait(int timeout);
int ev_get_input(int fd, short revents, struct input_event *ev);
void ev_dispatch(void);
// Resources

View File

@ -49,6 +49,8 @@ int res_create_surface(const char* name, gr_surface* pSurface) {
png_structp png_ptr = NULL;
png_infop info_ptr = NULL;
*pSurface = NULL;
snprintf(resPath, sizeof(resPath)-1, "/res/images/%s.png", name);
resPath[sizeof(resPath)-1] = '\0';
FILE* fp = fopen(resPath, "rb");
@ -119,13 +121,18 @@ int res_create_surface(const char* name, gr_surface* pSurface) {
surface->format = (channels == 3) ?
GGL_PIXEL_FORMAT_RGBX_8888 : GGL_PIXEL_FORMAT_RGBA_8888;
int alpha = 0;
if (color_type == PNG_COLOR_TYPE_PALETTE) {
png_set_palette_to_rgb(png_ptr);
png_set_palette_to_rgb(png_ptr);
}
if (png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS)) {
png_set_tRNS_to_alpha(png_ptr);
alpha = 1;
}
int y;
if (channels == 3) {
for (y = 0; y < (int)height; ++y) {
if (channels == 3 || (channels == 1 && !alpha)) {
for (y = 0; y < height; ++y) {
unsigned char* pRow = pData + y * stride;
png_read_row(png_ptr, pRow, NULL);
@ -144,7 +151,7 @@ int res_create_surface(const char* name, gr_surface* pSurface) {
}
}
} else {
for (y = 0; y < (int)height; ++y) {
for (y = 0; y < height; ++y) {
unsigned char* pRow = pData + y * stride;
png_read_row(png_ptr, pRow, NULL);
}

197
minui/roboto_10x18.h Normal file
View File

@ -0,0 +1,197 @@
struct {
unsigned width;
unsigned height;
unsigned cwidth;
unsigned cheight;
unsigned char rundata[];
} font = {
.width = 960,
.height = 18,
.cwidth = 10,
.cheight = 18,
.rundata = {
0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,
0x3b,0x81,0x29,0x81,0x06,0x81,0x3f,0x81,0x7f,0x7f,0x7f,0x37,0x83,0x05,0x81,
0x0a,0x83,0x7f,0x7f,0x2f,0x81,0x0e,0x81,0x29,0x82,0x07,0x81,0x01,0x82,0x07,
0x81,0x02,0x81,0x05,0x83,0x05,0x82,0x0a,0x82,0x09,0x82,0x09,0x81,0x08,0x81,
0x3e,0x81,0x05,0x84,0x06,0x84,0x06,0x83,0x06,0x84,0x09,0x82,0x05,0x85,0x06,
0x84,0x04,0x87,0x04,0x84,0x07,0x84,0x39,0x83,0x06,0x84,0x07,0x81,0x06,0x86,
0x06,0x84,0x04,0x86,0x04,0x87,0x04,0x87,0x04,0x84,0x04,0x82,0x04,0x82,0x03,
0x86,0x08,0x82,0x03,0x82,0x04,0x82,0x02,0x82,0x07,0x82,0x05,0x82,0x02,0x82,
0x05,0x81,0x04,0x84,0x04,0x86,0x06,0x84,0x04,0x86,0x06,0x84,0x04,0x88,0x02,
0x82,0x05,0x81,0x01,0x82,0x06,0x81,0x01,0x81,0x07,0x81,0x02,0x81,0x05,0x82,
0x02,0x82,0x04,0x82,0x02,0x87,0x06,0x81,0x07,0x82,0x0b,0x81,0x08,0x81,0x12,
0x82,0x10,0x82,0x18,0x82,0x10,0x83,0x0d,0x82,0x0b,0x82,0x08,0x82,0x06,0x82,
0x09,0x83,0x4c,0x82,0x48,0x81,0x07,0x82,0x07,0x81,0x28,0x82,0x07,0x81,0x01,
0x82,0x07,0x81,0x02,0x81,0x04,0x82,0x01,0x82,0x03,0x81,0x02,0x81,0x08,0x81,
0x02,0x81,0x08,0x82,0x08,0x82,0x08,0x82,0x3c,0x82,0x04,0x82,0x02,0x82,0x04,
0x85,0x05,0x82,0x01,0x82,0x04,0x82,0x02,0x82,0x07,0x83,0x05,0x85,0x05,0x82,
0x02,0x81,0x09,0x82,0x03,0x82,0x02,0x82,0x05,0x82,0x02,0x82,0x37,0x82,0x01,
0x82,0x04,0x81,0x03,0x82,0x06,0x82,0x05,0x82,0x03,0x82,0x04,0x83,0x01,0x82,
0x03,0x82,0x03,0x82,0x03,0x82,0x09,0x82,0x08,0x82,0x02,0x82,0x03,0x82,0x04,
0x82,0x05,0x82,0x0a,0x82,0x03,0x82,0x03,0x82,0x03,0x82,0x07,0x82,0x05,0x82,
0x02,0x82,0x05,0x81,0x03,0x82,0x02,0x82,0x03,0x82,0x03,0x82,0x04,0x82,0x02,
0x82,0x03,0x82,0x03,0x82,0x04,0x82,0x02,0x82,0x06,0x82,0x05,0x82,0x05,0x81,
0x02,0x81,0x05,0x82,0x01,0x81,0x07,0x81,0x02,0x82,0x04,0x81,0x03,0x82,0x04,
0x82,0x07,0x82,0x06,0x81,0x08,0x81,0x0b,0x81,0x07,0x82,0x13,0x81,0x10,0x82,
0x18,0x82,0x0f,0x84,0x0d,0x82,0x1d,0x82,0x0a,0x82,0x4c,0x82,0x47,0x82,0x07,
0x82,0x07,0x82,0x27,0x82,0x07,0x81,0x01,0x82,0x06,0x81,0x02,0x81,0x04,0x82,
0x03,0x82,0x02,0x81,0x02,0x81,0x02,0x81,0x04,0x82,0x02,0x82,0x08,0x81,0x08,
0x81,0x0a,0x81,0x12,0x82,0x28,0x81,0x05,0x81,0x04,0x81,0x07,0x82,0x04,0x82,
0x03,0x82,0x03,0x81,0x04,0x81,0x07,0x83,0x05,0x81,0x08,0x82,0x0c,0x82,0x04,
0x81,0x04,0x82,0x04,0x81,0x04,0x81,0x36,0x82,0x03,0x81,0x03,0x81,0x05,0x82,
0x04,0x83,0x05,0x82,0x04,0x81,0x03,0x83,0x03,0x82,0x02,0x82,0x04,0x82,0x02,
0x82,0x09,0x82,0x07,0x82,0x04,0x82,0x02,0x82,0x04,0x82,0x05,0x82,0x0a,0x82,
0x03,0x82,0x02,0x82,0x04,0x82,0x07,0x83,0x03,0x83,0x02,0x83,0x04,0x81,0x02,
0x82,0x04,0x82,0x02,0x82,0x04,0x82,0x02,0x82,0x04,0x82,0x02,0x82,0x04,0x81,
0x03,0x82,0x04,0x81,0x06,0x82,0x05,0x82,0x05,0x81,0x02,0x81,0x05,0x82,0x01,
0x82,0x02,0x81,0x02,0x82,0x03,0x82,0x02,0x82,0x04,0x81,0x03,0x82,0x08,0x81,
0x07,0x81,0x08,0x81,0x0b,0x81,0x07,0x83,0x13,0x81,0x0f,0x82,0x18,0x82,0x0e,
0x82,0x10,0x82,0x1d,0x82,0x0a,0x82,0x4c,0x82,0x47,0x81,0x08,0x82,0x08,0x81,
0x27,0x82,0x07,0x81,0x01,0x81,0x05,0x88,0x02,0x82,0x07,0x81,0x02,0x81,0x01,
0x82,0x05,0x81,0x02,0x81,0x08,0x81,0x08,0x82,0x0a,0x82,0x07,0x81,0x09,0x82,
0x27,0x82,0x04,0x82,0x04,0x82,0x06,0x82,0x0a,0x81,0x08,0x81,0x06,0x81,0x01,
0x82,0x05,0x81,0x08,0x82,0x0c,0x81,0x05,0x81,0x04,0x82,0x04,0x81,0x04,0x81,
0x05,0x82,0x08,0x82,0x2a,0x81,0x03,0x81,0x02,0x81,0x03,0x81,0x04,0x81,0x01,
0x82,0x04,0x82,0x04,0x81,0x03,0x82,0x04,0x82,0x02,0x82,0x05,0x81,0x02,0x82,
0x09,0x82,0x07,0x82,0x04,0x82,0x02,0x82,0x04,0x82,0x05,0x82,0x0a,0x82,0x03,
0x82,0x02,0x81,0x05,0x82,0x07,0x83,0x03,0x83,0x02,0x84,0x03,0x81,0x02,0x82,
0x05,0x81,0x02,0x82,0x04,0x82,0x02,0x82,0x04,0x82,0x02,0x82,0x04,0x82,0x02,
0x82,0x0b,0x82,0x05,0x82,0x05,0x81,0x02,0x82,0x04,0x81,0x03,0x81,0x02,0x82,
0x01,0x82,0x04,0x81,0x01,0x82,0x05,0x82,0x01,0x82,0x08,0x82,0x07,0x81,0x08,
0x82,0x0a,0x81,0x06,0x82,0x01,0x81,0x1a,0x85,0x04,0x82,0x01,0x83,0x06,0x84,
0x06,0x83,0x01,0x82,0x04,0x84,0x06,0x82,0x07,0x85,0x04,0x82,0x01,0x83,0x06,
0x83,0x08,0x82,0x06,0x82,0x02,0x82,0x06,0x82,0x05,0x81,0x01,0x82,0x01,0x82,
0x03,0x82,0x01,0x84,0x05,0x84,0x04,0x82,0x01,0x83,0x06,0x83,0x01,0x82,0x03,
0x82,0x01,0x84,0x04,0x84,0x04,0x86,0x04,0x82,0x04,0x82,0x02,0x82,0x04,0x81,
0x02,0x82,0x06,0x81,0x02,0x82,0x03,0x82,0x03,0x82,0x04,0x82,0x03,0x86,0x07,
0x81,0x08,0x82,0x08,0x81,0x27,0x82,0x11,0x81,0x02,0x81,0x05,0x82,0x06,0x84,
0x01,0x81,0x06,0x83,0x12,0x82,0x0a,0x82,0x05,0x81,0x01,0x81,0x01,0x81,0x07,
0x82,0x27,0x81,0x05,0x82,0x04,0x82,0x06,0x82,0x09,0x82,0x07,0x82,0x05,0x82,
0x01,0x82,0x04,0x85,0x05,0x81,0x01,0x83,0x08,0x82,0x06,0x81,0x02,0x82,0x05,
0x81,0x04,0x81,0x05,0x82,0x08,0x82,0x0a,0x83,0x04,0x86,0x04,0x82,0x0c,0x82,
0x02,0x81,0x02,0x81,0x01,0x81,0x02,0x81,0x04,0x81,0x01,0x82,0x04,0x82,0x03,
0x82,0x03,0x82,0x08,0x82,0x05,0x81,0x02,0x82,0x09,0x82,0x07,0x81,0x09,0x82,
0x04,0x82,0x05,0x82,0x0a,0x82,0x03,0x82,0x01,0x82,0x05,0x82,0x07,0x84,0x02,
0x83,0x02,0x82,0x01,0x81,0x03,0x81,0x02,0x82,0x05,0x81,0x02,0x82,0x04,0x82,
0x02,0x81,0x06,0x81,0x02,0x82,0x03,0x82,0x04,0x82,0x0a,0x82,0x05,0x82,0x05,
0x81,0x03,0x81,0x03,0x82,0x03,0x81,0x01,0x81,0x01,0x81,0x01,0x81,0x05,0x83,
0x07,0x84,0x07,0x82,0x08,0x81,0x09,0x81,0x0a,0x81,0x06,0x81,0x02,0x81,0x19,
0x82,0x02,0x83,0x03,0x83,0x02,0x82,0x04,0x82,0x02,0x82,0x04,0x82,0x02,0x83,
0x03,0x82,0x02,0x82,0x04,0x85,0x04,0x83,0x01,0x83,0x03,0x83,0x02,0x82,0x06,
0x82,0x08,0x82,0x06,0x82,0x02,0x81,0x07,0x82,0x05,0x82,0x01,0x82,0x01,0x82,
0x02,0x83,0x03,0x82,0x03,0x82,0x02,0x82,0x03,0x83,0x02,0x82,0x04,0x82,0x02,
0x83,0x03,0x83,0x03,0x81,0x03,0x82,0x02,0x82,0x04,0x82,0x07,0x82,0x04,0x82,
0x03,0x81,0x03,0x82,0x02,0x82,0x02,0x82,0x02,0x81,0x03,0x82,0x02,0x81,0x05,
0x81,0x04,0x82,0x07,0x81,0x08,0x81,0x08,0x82,0x08,0x81,0x27,0x82,0x11,0x81,
0x02,0x81,0x06,0x83,0x08,0x81,0x07,0x82,0x13,0x82,0x0a,0x82,0x05,0x85,0x04,
0x88,0x23,0x82,0x05,0x82,0x04,0x82,0x06,0x82,0x08,0x82,0x06,0x83,0x06,0x81,
0x02,0x82,0x04,0x82,0x02,0x82,0x04,0x82,0x02,0x82,0x07,0x81,0x08,0x83,0x06,
0x82,0x02,0x82,0x19,0x83,0x11,0x83,0x09,0x82,0x03,0x81,0x01,0x81,0x02,0x81,
0x02,0x81,0x03,0x82,0x02,0x81,0x04,0x86,0x04,0x82,0x08,0x82,0x05,0x81,0x02,
0x86,0x05,0x86,0x03,0x81,0x09,0x88,0x05,0x82,0x0a,0x82,0x03,0x84,0x06,0x82,
0x07,0x82,0x01,0x81,0x01,0x81,0x01,0x82,0x02,0x82,0x01,0x82,0x02,0x81,0x02,
0x82,0x05,0x81,0x02,0x82,0x03,0x82,0x03,0x81,0x06,0x81,0x02,0x86,0x06,0x83,
0x08,0x82,0x05,0x82,0x05,0x81,0x03,0x82,0x02,0x81,0x04,0x81,0x01,0x81,0x01,
0x81,0x01,0x81,0x06,0x82,0x08,0x82,0x08,0x81,0x09,0x81,0x09,0x82,0x09,0x81,
0x06,0x81,0x02,0x82,0x1d,0x82,0x03,0x82,0x04,0x82,0x02,0x82,0x04,0x81,0x03,
0x82,0x04,0x82,0x02,0x82,0x04,0x82,0x04,0x82,0x06,0x82,0x03,0x82,0x03,0x82,
0x04,0x82,0x05,0x82,0x08,0x82,0x06,0x82,0x01,0x81,0x08,0x82,0x05,0x82,0x01,
0x82,0x01,0x82,0x02,0x82,0x04,0x82,0x02,0x82,0x04,0x82,0x02,0x82,0x04,0x82,
0x02,0x82,0x04,0x82,0x03,0x82,0x08,0x81,0x09,0x82,0x07,0x82,0x04,0x82,0x03,
0x82,0x02,0x81,0x04,0x81,0x02,0x82,0x02,0x81,0x04,0x81,0x01,0x82,0x05,0x82,
0x02,0x82,0x07,0x82,0x08,0x81,0x08,0x82,0x08,0x81,0x07,0x83,0x03,0x81,0x19,
0x82,0x11,0x81,0x02,0x81,0x08,0x82,0x07,0x81,0x01,0x82,0x03,0x82,0x01,0x81,
0x02,0x82,0x0e,0x81,0x0c,0x81,0x06,0x82,0x06,0x88,0x0d,0x86,0x10,0x81,0x06,
0x82,0x04,0x82,0x06,0x82,0x07,0x82,0x09,0x82,0x04,0x82,0x02,0x82,0x09,0x82,
0x03,0x81,0x04,0x82,0x05,0x82,0x06,0x82,0x03,0x81,0x06,0x85,0x18,0x82,0x15,
0x83,0x06,0x82,0x04,0x81,0x01,0x81,0x02,0x81,0x02,0x81,0x03,0x81,0x03,0x82,
0x03,0x82,0x04,0x82,0x02,0x82,0x08,0x82,0x05,0x81,0x02,0x82,0x09,0x82,0x07,
0x81,0x03,0x84,0x02,0x82,0x04,0x82,0x05,0x82,0x0a,0x82,0x03,0x82,0x01,0x82,
0x05,0x82,0x07,0x82,0x01,0x81,0x01,0x81,0x01,0x82,0x02,0x82,0x02,0x82,0x01,
0x81,0x02,0x82,0x05,0x81,0x02,0x86,0x04,0x81,0x06,0x81,0x02,0x82,0x03,0x82,
0x07,0x82,0x07,0x82,0x05,0x82,0x05,0x81,0x03,0x82,0x02,0x81,0x04,0x83,0x01,
0x83,0x05,0x83,0x08,0x82,0x07,0x82,0x09,0x81,0x0a,0x81,0x09,0x81,0x25,0x85,
0x03,0x82,0x04,0x82,0x02,0x82,0x08,0x82,0x04,0x82,0x02,0x88,0x04,0x82,0x06,
0x82,0x03,0x82,0x03,0x82,0x04,0x82,0x05,0x82,0x08,0x82,0x06,0x84,0x08,0x82,
0x05,0x82,0x01,0x82,0x01,0x82,0x02,0x82,0x04,0x82,0x02,0x82,0x04,0x82,0x02,
0x82,0x04,0x82,0x02,0x82,0x04,0x82,0x03,0x82,0x08,0x83,0x07,0x82,0x07,0x82,
0x04,0x82,0x04,0x81,0x02,0x81,0x04,0x81,0x02,0x82,0x02,0x81,0x05,0x82,0x06,
0x82,0x02,0x82,0x06,0x82,0x07,0x82,0x09,0x82,0x09,0x82,0x04,0x82,0x01,0x82,
0x01,0x82,0x2a,0x87,0x08,0x82,0x05,0x81,0x01,0x81,0x02,0x81,0x02,0x81,0x02,
0x82,0x01,0x82,0x0e,0x81,0x0c,0x81,0x05,0x82,0x01,0x82,0x07,0x82,0x26,0x81,
0x06,0x82,0x04,0x82,0x06,0x82,0x06,0x82,0x0b,0x82,0x03,0x87,0x08,0x82,0x03,
0x81,0x04,0x82,0x05,0x82,0x06,0x81,0x04,0x82,0x09,0x81,0x18,0x82,0x08,0x86,
0x08,0x82,0x06,0x82,0x04,0x81,0x01,0x81,0x02,0x81,0x02,0x81,0x03,0x86,0x03,
0x82,0x04,0x82,0x02,0x82,0x08,0x82,0x05,0x81,0x02,0x82,0x09,0x82,0x07,0x82,
0x04,0x82,0x02,0x82,0x04,0x82,0x05,0x82,0x0a,0x82,0x03,0x82,0x02,0x82,0x04,
0x82,0x07,0x82,0x01,0x83,0x01,0x82,0x02,0x82,0x03,0x81,0x01,0x81,0x02,0x82,
0x05,0x81,0x02,0x82,0x08,0x82,0x04,0x82,0x02,0x82,0x04,0x81,0x08,0x82,0x06,
0x82,0x05,0x82,0x05,0x81,0x04,0x81,0x01,0x82,0x05,0x82,0x02,0x82,0x05,0x81,
0x01,0x82,0x07,0x82,0x06,0x82,0x0a,0x81,0x0a,0x81,0x09,0x81,0x24,0x82,0x02,
0x82,0x03,0x82,0x04,0x82,0x02,0x82,0x08,0x82,0x04,0x82,0x02,0x82,0x0a,0x82,
0x06,0x82,0x03,0x82,0x03,0x82,0x04,0x82,0x05,0x82,0x08,0x82,0x06,0x84,0x08,
0x82,0x05,0x82,0x01,0x82,0x01,0x82,0x02,0x82,0x04,0x82,0x02,0x82,0x04,0x82,
0x02,0x82,0x04,0x82,0x02,0x82,0x04,0x82,0x03,0x82,0x0b,0x83,0x04,0x82,0x07,
0x82,0x04,0x82,0x04,0x81,0x01,0x82,0x04,0x81,0x01,0x81,0x01,0x81,0x01,0x82,
0x05,0x82,0x07,0x81,0x02,0x82,0x06,0x81,0x0a,0x81,0x08,0x82,0x08,0x81,0x06,
0x81,0x03,0x83,0x2c,0x81,0x02,0x81,0x05,0x81,0x04,0x82,0x04,0x81,0x02,0x81,
0x02,0x81,0x01,0x82,0x03,0x83,0x0f,0x82,0x0a,0x82,0x11,0x82,0x25,0x82,0x07,
0x81,0x04,0x81,0x07,0x82,0x05,0x82,0x07,0x81,0x04,0x82,0x03,0x87,0x03,0x81,
0x04,0x82,0x03,0x81,0x04,0x82,0x05,0x81,0x07,0x81,0x04,0x82,0x08,0x82,0x19,
0x84,0x10,0x83,0x0e,0x81,0x01,0x81,0x02,0x81,0x01,0x82,0x02,0x82,0x04,0x81,
0x03,0x82,0x04,0x82,0x02,0x83,0x03,0x82,0x02,0x82,0x04,0x82,0x02,0x82,0x09,
0x82,0x07,0x82,0x04,0x82,0x02,0x82,0x04,0x82,0x05,0x82,0x05,0x81,0x04,0x82,
0x03,0x82,0x03,0x81,0x04,0x82,0x07,0x82,0x02,0x81,0x02,0x82,0x02,0x82,0x03,
0x83,0x02,0x82,0x04,0x82,0x02,0x82,0x08,0x82,0x04,0x82,0x02,0x82,0x04,0x82,
0x02,0x81,0x05,0x81,0x06,0x82,0x05,0x83,0x03,0x82,0x04,0x83,0x06,0x82,0x02,
0x82,0x04,0x82,0x02,0x81,0x07,0x82,0x06,0x81,0x0b,0x81,0x0a,0x82,0x08,0x81,
0x23,0x82,0x03,0x82,0x03,0x82,0x04,0x82,0x02,0x82,0x04,0x81,0x03,0x82,0x04,
0x82,0x02,0x82,0x0a,0x82,0x06,0x82,0x03,0x82,0x03,0x82,0x04,0x82,0x05,0x82,
0x08,0x82,0x06,0x82,0x01,0x82,0x07,0x82,0x05,0x82,0x01,0x82,0x01,0x82,0x02,
0x82,0x04,0x82,0x02,0x82,0x04,0x82,0x02,0x82,0x04,0x82,0x02,0x82,0x04,0x82,
0x03,0x82,0x0d,0x81,0x04,0x82,0x07,0x82,0x03,0x83,0x04,0x83,0x06,0x82,0x02,
0x82,0x05,0x81,0x01,0x82,0x06,0x84,0x06,0x81,0x0b,0x81,0x08,0x82,0x08,0x81,
0x27,0x82,0x10,0x81,0x02,0x81,0x05,0x82,0x02,0x83,0x04,0x81,0x02,0x81,0x02,
0x81,0x02,0x81,0x04,0x82,0x0f,0x82,0x0a,0x82,0x11,0x82,0x07,0x82,0x12,0x82,
0x08,0x81,0x08,0x82,0x02,0x82,0x07,0x82,0x05,0x81,0x08,0x82,0x03,0x81,0x08,
0x82,0x04,0x82,0x02,0x82,0x04,0x82,0x02,0x82,0x06,0x81,0x07,0x82,0x02,0x82,
0x08,0x82,0x06,0x82,0x08,0x82,0x0b,0x82,0x0e,0x82,0x0a,0x82,0x04,0x81,0x01,
0x83,0x01,0x82,0x03,0x81,0x05,0x82,0x02,0x82,0x04,0x82,0x03,0x83,0x01,0x82,
0x03,0x82,0x03,0x82,0x03,0x82,0x09,0x82,0x08,0x82,0x03,0x82,0x02,0x82,0x04,
0x82,0x05,0x82,0x05,0x82,0x02,0x82,0x04,0x82,0x03,0x82,0x03,0x82,0x07,0x82,
0x05,0x82,0x02,0x82,0x04,0x82,0x03,0x82,0x02,0x82,0x03,0x82,0x09,0x82,0x02,
0x82,0x03,0x82,0x04,0x82,0x02,0x82,0x03,0x82,0x06,0x82,0x06,0x82,0x03,0x82,
0x05,0x82,0x06,0x82,0x02,0x81,0x04,0x82,0x03,0x82,0x06,0x82,0x05,0x82,0x0b,
0x81,0x0b,0x81,0x08,0x81,0x23,0x82,0x02,0x83,0x03,0x83,0x02,0x82,0x04,0x82,
0x02,0x82,0x04,0x82,0x02,0x83,0x03,0x82,0x03,0x82,0x04,0x82,0x06,0x83,0x01,
0x83,0x03,0x82,0x04,0x82,0x05,0x82,0x08,0x82,0x06,0x82,0x02,0x82,0x06,0x82,
0x05,0x82,0x01,0x82,0x01,0x82,0x02,0x82,0x04,0x82,0x03,0x82,0x02,0x82,0x03,
0x83,0x02,0x82,0x04,0x82,0x02,0x83,0x03,0x82,0x08,0x82,0x02,0x82,0x04,0x82,
0x03,0x81,0x03,0x83,0x01,0x84,0x05,0x82,0x06,0x82,0x02,0x82,0x04,0x82,0x02,
0x81,0x07,0x83,0x05,0x82,0x0b,0x81,0x08,0x82,0x08,0x81,0x27,0x82,0x10,0x81,
0x02,0x81,0x06,0x85,0x09,0x82,0x04,0x84,0x01,0x82,0x0f,0x81,0x0a,0x81,0x1b,
0x82,0x12,0x82,0x08,0x81,0x09,0x84,0x08,0x82,0x04,0x87,0x04,0x84,0x09,0x82,
0x05,0x84,0x06,0x84,0x07,0x81,0x08,0x84,0x06,0x84,0x07,0x82,0x08,0x82,0x27,
0x82,0x04,0x82,0x09,0x81,0x06,0x81,0x02,0x87,0x05,0x84,0x04,0x86,0x04,0x87,
0x04,0x82,0x09,0x85,0x03,0x82,0x04,0x82,0x03,0x86,0x04,0x84,0x05,0x82,0x04,
0x82,0x02,0x87,0x02,0x82,0x05,0x82,0x02,0x82,0x05,0x81,0x04,0x84,0x04,0x82,
0x0a,0x86,0x02,0x82,0x04,0x82,0x03,0x85,0x07,0x82,0x07,0x85,0x06,0x82,0x06,
0x82,0x02,0x81,0x04,0x82,0x04,0x82,0x05,0x82,0x05,0x87,0x06,0x81,0x0b,0x82,
0x07,0x81,0x23,0x84,0x01,0x82,0x03,0x82,0x01,0x83,0x06,0x84,0x06,0x83,0x01,
0x82,0x04,0x85,0x05,0x82,0x07,0x83,0x01,0x82,0x03,0x82,0x04,0x82,0x03,0x86,
0x06,0x82,0x06,0x82,0x03,0x81,0x04,0x86,0x03,0x82,0x01,0x82,0x01,0x82,0x02,
0x82,0x04,0x82,0x04,0x84,0x04,0x82,0x01,0x83,0x06,0x83,0x01,0x82,0x03,0x82,
0x09,0x84,0x06,0x84,0x05,0x84,0x01,0x82,0x05,0x82,0x06,0x81,0x03,0x82,0x03,
0x82,0x03,0x82,0x07,0x82,0x05,0x86,0x07,0x81,0x08,0x82,0x08,0x81,0x45,0x81,
0x27,0x81,0x0a,0x81,0x1c,0x81,0x1b,0x82,0x78,0x81,0x2e,0x82,0x7f,0x30,0x82,
0x5e,0x81,0x0c,0x81,0x07,0x81,0x0f,0x88,0x4d,0x82,0x1a,0x82,0x37,0x82,0x0e,
0x82,0x4b,0x82,0x13,0x82,0x07,0x82,0x07,0x82,0x45,0x81,0x28,0x81,0x08,0x81,
0x1c,0x81,0x1c,0x81,0x78,0x81,0x30,0x84,0x7f,0x7f,0x0e,0x83,0x0a,0x81,0x05,
0x83,0x64,0x82,0x1a,0x82,0x37,0x82,0x0e,0x82,0x4b,0x82,0x14,0x81,0x07,0x82,
0x07,0x81,0x70,0x81,0x06,0x81,0x7f,0x7f,0x7f,0x7f,0x6e,0x85,0x1a,0x82,0x38,
0x82,0x0e,0x82,0x4a,0x82,0x16,0x81,0x0e,0x81,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,
0x7f,0x62,
0x00,
}
};

281
minui/roboto_15x24.h Normal file
View File

@ -0,0 +1,281 @@
struct {
unsigned width;
unsigned height;
unsigned cwidth;
unsigned cheight;
unsigned char rundata[];
} font = {
.width = 1440,
.height = 24,
.cwidth = 15,
.cheight = 24,
.rundata = {
0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x6e,0x81,0x3e,0x81,
0x07,0x81,0x7f,0x7f,0x7f,0x7f,0x7f,0x76,0x84,0x17,0x84,0x7f,0x7f,0x7f,0x7f,
0x4c,0x81,0x3d,0x82,0x07,0x82,0x5f,0x81,0x7f,0x7f,0x7f,0x7f,0x7f,0x15,0x84,
0x07,0x82,0x0e,0x84,0x45,0x82,0x24,0x82,0x1a,0x83,0x16,0x82,0x10,0x82,0x0e,
0x82,0x0a,0x82,0x0d,0x84,0x7f,0x62,0x82,0x0b,0x82,0x0b,0x82,0x3b,0x82,0x0c,
0x82,0x02,0x82,0x0a,0x82,0x03,0x81,0x0a,0x84,0x08,0x83,0x0e,0x84,0x0b,0x82,
0x10,0x82,0x09,0x82,0x5e,0x81,0x09,0x84,0x0b,0x84,0x0b,0x84,0x0b,0x84,0x0e,
0x83,0x08,0x88,0x09,0x84,0x07,0x8a,0x08,0x84,0x0b,0x84,0x56,0x84,0x1c,0x82,
0x08,0x87,0x0b,0x85,0x07,0x87,0x09,0x89,0x06,0x8a,0x07,0x85,0x06,0x82,0x08,
0x82,0x06,0x86,0x0f,0x82,0x06,0x82,0x07,0x82,0x04,0x82,0x0a,0x83,0x09,0x82,
0x03,0x82,0x08,0x82,0x06,0x85,0x07,0x87,0x0b,0x85,0x07,0x87,0x0c,0x84,0x06,
0x8d,0x03,0x82,0x07,0x82,0x02,0x83,0x08,0x83,0x01,0x82,0x0a,0x82,0x02,0x82,
0x08,0x82,0x03,0x82,0x08,0x82,0x04,0x8b,0x09,0x82,0x09,0x82,0x10,0x82,0x0d,
0x81,0x1d,0x82,0x18,0x82,0x24,0x82,0x19,0x84,0x16,0x82,0x10,0x82,0x0e,0x82,
0x0a,0x82,0x0d,0x84,0x7f,0x61,0x82,0x0c,0x82,0x0c,0x82,0x3a,0x82,0x0c,0x82,
0x02,0x82,0x0a,0x82,0x03,0x81,0x08,0x87,0x06,0x82,0x01,0x82,0x0c,0x86,0x0a,
0x82,0x0f,0x82,0x0b,0x82,0x5c,0x82,0x08,0x87,0x07,0x86,0x0a,0x87,0x08,0x87,
0x0c,0x83,0x08,0x88,0x07,0x87,0x06,0x8a,0x07,0x87,0x07,0x87,0x54,0x87,0x08,
0x86,0x0c,0x82,0x08,0x89,0x07,0x88,0x06,0x89,0x07,0x89,0x06,0x8a,0x05,0x88,
0x05,0x82,0x08,0x82,0x06,0x86,0x0f,0x82,0x06,0x82,0x06,0x82,0x05,0x82,0x0a,
0x83,0x08,0x83,0x03,0x83,0x07,0x82,0x04,0x88,0x06,0x89,0x07,0x88,0x06,0x89,
0x08,0x88,0x04,0x8d,0x03,0x82,0x07,0x82,0x03,0x82,0x08,0x82,0x02,0x82,0x04,
0x81,0x05,0x82,0x03,0x82,0x06,0x82,0x04,0x82,0x07,0x83,0x04,0x8b,0x09,0x82,
0x0a,0x82,0x0f,0x82,0x0c,0x83,0x1d,0x82,0x17,0x82,0x24,0x82,0x18,0x83,0x18,
0x82,0x2c,0x82,0x0f,0x82,0x7f,0x60,0x83,0x0c,0x82,0x0d,0x82,0x39,0x82,0x0c,
0x82,0x02,0x82,0x0a,0x82,0x02,0x82,0x07,0x83,0x03,0x83,0x04,0x82,0x03,0x81,
0x04,0x81,0x06,0x83,0x03,0x82,0x09,0x82,0x0f,0x82,0x0b,0x82,0x5c,0x82,0x07,
0x82,0x04,0x82,0x0a,0x83,0x09,0x82,0x04,0x83,0x06,0x82,0x04,0x83,0x0a,0x84,
0x08,0x82,0x0d,0x82,0x13,0x82,0x06,0x82,0x04,0x83,0x06,0x82,0x04,0x82,0x52,
0x82,0x04,0x82,0x07,0x82,0x05,0x82,0x09,0x84,0x07,0x82,0x05,0x83,0x06,0x82,
0x05,0x82,0x05,0x82,0x05,0x83,0x06,0x82,0x0d,0x82,0x0d,0x82,0x05,0x82,0x04,
0x82,0x08,0x82,0x08,0x82,0x11,0x82,0x06,0x82,0x05,0x82,0x06,0x82,0x0a,0x83,
0x08,0x83,0x03,0x83,0x07,0x82,0x04,0x82,0x05,0x82,0x05,0x82,0x06,0x82,0x06,
0x82,0x05,0x82,0x05,0x82,0x05,0x83,0x06,0x83,0x04,0x83,0x08,0x83,0x08,0x82,
0x07,0x82,0x03,0x82,0x08,0x82,0x02,0x82,0x03,0x83,0x04,0x82,0x03,0x83,0x04,
0x83,0x05,0x82,0x06,0x82,0x0d,0x82,0x0a,0x82,0x0a,0x82,0x0f,0x82,0x0c,0x83,
0x1e,0x81,0x17,0x82,0x24,0x82,0x18,0x82,0x19,0x82,0x2c,0x82,0x0f,0x82,0x74,
0x82,0x69,0x82,0x0d,0x82,0x0d,0x82,0x39,0x82,0x0c,0x82,0x02,0x82,0x0a,0x82,
0x02,0x82,0x07,0x82,0x05,0x82,0x04,0x82,0x03,0x82,0x02,0x82,0x06,0x82,0x04,
0x82,0x09,0x82,0x0e,0x82,0x0d,0x82,0x1c,0x82,0x3c,0x82,0x08,0x82,0x05,0x82,
0x09,0x83,0x09,0x82,0x05,0x82,0x05,0x83,0x05,0x82,0x09,0x85,0x07,0x82,0x0d,
0x82,0x13,0x82,0x07,0x82,0x05,0x82,0x05,0x82,0x05,0x83,0x51,0x82,0x04,0x82,
0x06,0x82,0x07,0x82,0x08,0x84,0x07,0x82,0x06,0x82,0x05,0x82,0x07,0x82,0x04,
0x82,0x06,0x83,0x05,0x82,0x0d,0x82,0x0c,0x82,0x07,0x82,0x03,0x82,0x08,0x82,
0x08,0x82,0x11,0x82,0x06,0x82,0x04,0x83,0x06,0x82,0x0a,0x84,0x06,0x84,0x03,
0x84,0x06,0x82,0x03,0x82,0x07,0x82,0x04,0x82,0x07,0x82,0x04,0x82,0x07,0x82,
0x04,0x82,0x06,0x82,0x06,0x82,0x06,0x82,0x08,0x83,0x08,0x82,0x07,0x82,0x03,
0x83,0x06,0x83,0x02,0x82,0x03,0x83,0x03,0x82,0x05,0x82,0x04,0x82,0x06,0x82,
0x05,0x83,0x0c,0x83,0x0a,0x82,0x0b,0x82,0x0e,0x82,0x0c,0x81,0x01,0x82,0x35,
0x82,0x24,0x82,0x18,0x82,0x19,0x82,0x2c,0x82,0x0f,0x82,0x74,0x82,0x69,0x82,
0x0d,0x82,0x0d,0x83,0x38,0x82,0x0c,0x82,0x02,0x81,0x0b,0x81,0x03,0x82,0x07,
0x82,0x05,0x82,0x04,0x82,0x03,0x82,0x02,0x81,0x07,0x82,0x04,0x82,0x09,0x82,
0x0e,0x82,0x0d,0x82,0x0d,0x82,0x0d,0x82,0x3c,0x82,0x07,0x82,0x06,0x82,0x09,
0x83,0x08,0x83,0x05,0x82,0x0d,0x82,0x09,0x85,0x07,0x82,0x0d,0x82,0x12,0x83,
0x07,0x82,0x05,0x82,0x05,0x82,0x06,0x82,0x57,0x83,0x04,0x82,0x09,0x81,0x08,
0x84,0x07,0x82,0x06,0x82,0x05,0x82,0x07,0x82,0x04,0x82,0x07,0x82,0x05,0x82,
0x0d,0x82,0x0c,0x82,0x07,0x82,0x03,0x82,0x08,0x82,0x08,0x82,0x11,0x82,0x06,
0x82,0x03,0x83,0x07,0x82,0x0a,0x84,0x06,0x84,0x03,0x85,0x05,0x82,0x03,0x82,
0x07,0x82,0x04,0x82,0x07,0x82,0x04,0x82,0x07,0x82,0x04,0x82,0x06,0x83,0x05,
0x82,0x06,0x82,0x08,0x83,0x08,0x82,0x07,0x82,0x04,0x82,0x06,0x82,0x03,0x82,
0x03,0x83,0x03,0x82,0x05,0x83,0x02,0x83,0x07,0x82,0x04,0x82,0x0d,0x82,0x0b,
0x82,0x0b,0x82,0x0e,0x82,0x0b,0x82,0x01,0x82,0x29,0x84,0x08,0x82,0x01,0x84,
0x0a,0x86,0x0a,0x83,0x02,0x82,0x08,0x84,0x0a,0x86,0x0a,0x83,0x02,0x82,0x06,
0x82,0x01,0x84,0x09,0x84,0x0e,0x82,0x0a,0x82,0x04,0x83,0x08,0x82,0x07,0x81,
0x02,0x83,0x03,0x83,0x05,0x81,0x02,0x84,0x0b,0x84,0x09,0x81,0x02,0x84,0x0a,
0x83,0x02,0x82,0x08,0x81,0x02,0x84,0x08,0x84,0x08,0x88,0x07,0x82,0x06,0x82,
0x05,0x82,0x06,0x82,0x03,0x82,0x03,0x82,0x05,0x82,0x04,0x82,0x05,0x82,0x04,
0x83,0x05,0x83,0x06,0x89,0x09,0x82,0x0d,0x82,0x0d,0x83,0x38,0x82,0x0c,0x82,
0x02,0x81,0x08,0x8b,0x05,0x82,0x0b,0x82,0x03,0x81,0x02,0x82,0x07,0x83,0x02,
0x82,0x0a,0x81,0x0f,0x82,0x0d,0x82,0x0d,0x82,0x0d,0x82,0x3c,0x82,0x07,0x82,
0x06,0x82,0x09,0x83,0x10,0x82,0x0d,0x82,0x08,0x82,0x01,0x83,0x07,0x82,0x0d,
0x82,0x12,0x82,0x08,0x82,0x05,0x82,0x05,0x82,0x06,0x82,0x08,0x82,0x0d,0x82,
0x13,0x81,0x06,0x89,0x06,0x81,0x14,0x82,0x05,0x81,0x04,0x84,0x02,0x82,0x06,
0x82,0x02,0x82,0x06,0x82,0x06,0x82,0x04,0x82,0x0e,0x82,0x07,0x82,0x05,0x82,
0x0d,0x82,0x0b,0x82,0x0d,0x82,0x08,0x82,0x08,0x82,0x11,0x82,0x06,0x82,0x03,
0x82,0x08,0x82,0x0a,0x82,0x01,0x82,0x05,0x84,0x03,0x82,0x01,0x82,0x05,0x82,
0x02,0x82,0x09,0x82,0x03,0x82,0x07,0x82,0x03,0x82,0x09,0x82,0x03,0x82,0x06,
0x83,0x05,0x82,0x10,0x83,0x08,0x82,0x07,0x82,0x04,0x82,0x06,0x82,0x03,0x82,
0x03,0x81,0x01,0x82,0x02,0x82,0x06,0x82,0x02,0x82,0x08,0x82,0x03,0x83,0x0c,
0x82,0x0c,0x82,0x0b,0x82,0x0e,0x82,0x0b,0x82,0x02,0x81,0x28,0x87,0x06,0x88,
0x08,0x88,0x08,0x88,0x07,0x86,0x09,0x86,0x09,0x88,0x06,0x88,0x08,0x84,0x0e,
0x82,0x0a,0x82,0x03,0x83,0x09,0x82,0x07,0x87,0x01,0x85,0x04,0x88,0x09,0x87,
0x07,0x81,0x01,0x86,0x08,0x88,0x08,0x87,0x06,0x87,0x07,0x88,0x07,0x82,0x06,
0x82,0x05,0x82,0x05,0x82,0x04,0x82,0x03,0x82,0x05,0x82,0x04,0x83,0x03,0x83,
0x05,0x82,0x05,0x82,0x07,0x89,0x09,0x82,0x0d,0x82,0x0d,0x83,0x38,0x82,0x1b,
0x82,0x03,0x81,0x08,0x83,0x0b,0x85,0x01,0x82,0x09,0x85,0x1a,0x83,0x0d,0x83,
0x09,0x81,0x02,0x82,0x01,0x81,0x0b,0x82,0x3b,0x82,0x08,0x82,0x06,0x82,0x09,
0x83,0x0f,0x82,0x0d,0x82,0x09,0x82,0x01,0x83,0x07,0x87,0x07,0x83,0x01,0x84,
0x0c,0x82,0x09,0x83,0x03,0x82,0x06,0x82,0x06,0x82,0x08,0x82,0x0d,0x82,0x11,
0x83,0x06,0x89,0x06,0x83,0x12,0x82,0x05,0x81,0x03,0x82,0x02,0x82,0x02,0x81,
0x06,0x82,0x02,0x82,0x06,0x82,0x05,0x82,0x05,0x82,0x0e,0x82,0x07,0x83,0x04,
0x82,0x0d,0x82,0x0b,0x82,0x0d,0x82,0x08,0x82,0x08,0x82,0x11,0x82,0x06,0x82,
0x02,0x82,0x09,0x82,0x0a,0x82,0x01,0x82,0x04,0x82,0x01,0x82,0x03,0x82,0x02,
0x82,0x04,0x82,0x02,0x82,0x09,0x82,0x03,0x82,0x07,0x82,0x03,0x82,0x09,0x82,
0x03,0x82,0x06,0x82,0x06,0x83,0x0f,0x83,0x08,0x82,0x07,0x82,0x05,0x82,0x04,
0x82,0x05,0x81,0x02,0x82,0x01,0x82,0x02,0x82,0x07,0x84,0x0a,0x82,0x02,0x82,
0x0c,0x83,0x0c,0x82,0x0c,0x82,0x0d,0x82,0x0a,0x82,0x03,0x82,0x26,0x82,0x04,
0x82,0x06,0x83,0x03,0x83,0x07,0x82,0x05,0x82,0x06,0x82,0x04,0x83,0x06,0x82,
0x04,0x82,0x0a,0x82,0x0a,0x83,0x03,0x83,0x06,0x82,0x04,0x83,0x09,0x82,0x0e,
0x82,0x0a,0x82,0x03,0x82,0x0a,0x82,0x07,0x82,0x03,0x84,0x02,0x82,0x04,0x82,
0x04,0x83,0x07,0x82,0x04,0x83,0x06,0x82,0x04,0x83,0x06,0x82,0x04,0x83,0x08,
0x83,0x0a,0x82,0x04,0x82,0x08,0x82,0x0b,0x82,0x06,0x82,0x05,0x82,0x05,0x82,
0x04,0x82,0x03,0x83,0x03,0x82,0x06,0x82,0x03,0x82,0x06,0x82,0x05,0x82,0x0d,
0x82,0x0a,0x82,0x0d,0x82,0x0d,0x83,0x38,0x82,0x1b,0x82,0x02,0x82,0x09,0x85,
0x0e,0x81,0x0b,0x83,0x1b,0x82,0x0f,0x82,0x09,0x87,0x0b,0x82,0x3b,0x82,0x08,
0x82,0x06,0x82,0x09,0x83,0x0e,0x83,0x09,0x85,0x09,0x82,0x02,0x83,0x07,0x88,
0x06,0x89,0x0b,0x82,0x0a,0x86,0x07,0x82,0x06,0x82,0x27,0x85,0x17,0x84,0x0f,
0x82,0x05,0x82,0x03,0x81,0x03,0x82,0x02,0x81,0x06,0x82,0x02,0x82,0x06,0x88,
0x06,0x82,0x0e,0x82,0x07,0x83,0x04,0x88,0x07,0x88,0x05,0x82,0x0d,0x8c,0x08,
0x82,0x11,0x82,0x06,0x85,0x0a,0x82,0x0a,0x82,0x01,0x82,0x04,0x82,0x01,0x82,
0x03,0x82,0x02,0x82,0x04,0x82,0x02,0x82,0x09,0x82,0x03,0x82,0x06,0x82,0x04,
0x82,0x09,0x82,0x03,0x82,0x04,0x83,0x08,0x85,0x0c,0x83,0x08,0x82,0x07,0x82,
0x05,0x82,0x04,0x82,0x05,0x82,0x01,0x82,0x01,0x82,0x02,0x81,0x08,0x84,0x0a,
0x86,0x0c,0x82,0x0d,0x82,0x0c,0x82,0x0d,0x82,0x0a,0x82,0x03,0x82,0x26,0x82,
0x04,0x83,0x05,0x82,0x05,0x82,0x06,0x83,0x05,0x82,0x05,0x83,0x05,0x82,0x05,
0x83,0x04,0x82,0x0a,0x82,0x0a,0x82,0x05,0x82,0x06,0x82,0x05,0x82,0x09,0x82,
0x0e,0x82,0x0a,0x82,0x02,0x82,0x0b,0x82,0x07,0x82,0x03,0x83,0x03,0x83,0x03,
0x82,0x05,0x82,0x06,0x83,0x05,0x82,0x06,0x82,0x05,0x82,0x05,0x83,0x05,0x82,
0x08,0x82,0x0b,0x82,0x04,0x82,0x08,0x82,0x0b,0x82,0x06,0x82,0x06,0x82,0x04,
0x82,0x04,0x82,0x02,0x84,0x03,0x82,0x07,0x82,0x01,0x82,0x07,0x83,0x03,0x83,
0x0c,0x83,0x0a,0x82,0x0d,0x82,0x0e,0x82,0x0a,0x82,0x2c,0x82,0x1b,0x82,0x02,
0x82,0x0b,0x85,0x0b,0x82,0x09,0x85,0x1b,0x82,0x0f,0x82,0x0b,0x83,0x09,0x8b,
0x36,0x81,0x09,0x82,0x06,0x82,0x09,0x83,0x0e,0x82,0x0a,0x86,0x07,0x82,0x03,
0x83,0x07,0x82,0x04,0x83,0x05,0x84,0x03,0x83,0x09,0x82,0x0b,0x87,0x07,0x82,
0x04,0x83,0x25,0x85,0x1b,0x85,0x0b,0x82,0x06,0x82,0x02,0x82,0x03,0x82,0x02,
0x81,0x05,0x82,0x04,0x82,0x05,0x8a,0x04,0x82,0x0e,0x82,0x07,0x83,0x04,0x88,
0x07,0x88,0x05,0x82,0x04,0x86,0x03,0x8c,0x08,0x82,0x11,0x82,0x06,0x86,0x09,
0x82,0x0a,0x82,0x02,0x82,0x02,0x82,0x02,0x82,0x03,0x82,0x03,0x82,0x03,0x82,
0x02,0x82,0x09,0x82,0x03,0x8a,0x04,0x82,0x09,0x82,0x03,0x89,0x0a,0x85,0x0a,
0x83,0x08,0x82,0x07,0x82,0x05,0x82,0x04,0x82,0x05,0x82,0x01,0x82,0x02,0x81,
0x01,0x82,0x09,0x82,0x0c,0x84,0x0c,0x82,0x0e,0x82,0x0d,0x82,0x0c,0x82,0x3d,
0x83,0x05,0x82,0x05,0x82,0x06,0x82,0x0d,0x82,0x06,0x82,0x05,0x82,0x06,0x82,
0x09,0x82,0x09,0x82,0x06,0x82,0x06,0x82,0x05,0x82,0x09,0x82,0x0e,0x82,0x0a,
0x82,0x01,0x83,0x0b,0x82,0x07,0x82,0x04,0x82,0x04,0x82,0x03,0x82,0x05,0x82,
0x06,0x82,0x06,0x82,0x06,0x82,0x05,0x82,0x05,0x82,0x06,0x82,0x08,0x82,0x0b,
0x82,0x0e,0x82,0x0b,0x82,0x06,0x82,0x06,0x82,0x03,0x82,0x06,0x82,0x01,0x82,
0x01,0x81,0x03,0x82,0x07,0x82,0x01,0x82,0x08,0x82,0x03,0x82,0x0c,0x83,0x09,
0x83,0x0e,0x82,0x0e,0x83,0x07,0x86,0x04,0x82,0x24,0x82,0x1b,0x81,0x03,0x82,
0x0d,0x84,0x0a,0x81,0x02,0x84,0x03,0x83,0x01,0x83,0x03,0x82,0x15,0x82,0x0f,
0x82,0x0b,0x84,0x08,0x8b,0x15,0x86,0x1a,0x82,0x09,0x82,0x06,0x82,0x09,0x83,
0x0d,0x82,0x0f,0x83,0x06,0x82,0x03,0x83,0x0e,0x82,0x05,0x83,0x05,0x82,0x09,
0x82,0x0a,0x82,0x04,0x83,0x06,0x89,0x24,0x83,0x21,0x84,0x08,0x82,0x07,0x81,
0x03,0x82,0x03,0x81,0x03,0x81,0x05,0x82,0x04,0x82,0x05,0x82,0x06,0x83,0x03,
0x82,0x0e,0x82,0x07,0x83,0x04,0x82,0x0d,0x82,0x0b,0x82,0x04,0x86,0x03,0x82,
0x08,0x82,0x08,0x82,0x11,0x82,0x06,0x82,0x02,0x82,0x09,0x82,0x0a,0x82,0x02,
0x82,0x02,0x82,0x02,0x82,0x03,0x82,0x03,0x83,0x02,0x82,0x02,0x82,0x09,0x82,
0x03,0x88,0x06,0x82,0x09,0x82,0x03,0x82,0x05,0x83,0x0c,0x84,0x08,0x83,0x08,
0x82,0x07,0x82,0x06,0x82,0x02,0x82,0x06,0x82,0x01,0x81,0x03,0x84,0x08,0x84,
0x0b,0x83,0x0c,0x83,0x0e,0x82,0x0d,0x82,0x0c,0x82,0x39,0x87,0x05,0x82,0x05,
0x82,0x06,0x82,0x0d,0x82,0x06,0x82,0x05,0x8a,0x09,0x82,0x09,0x82,0x06,0x82,
0x06,0x82,0x05,0x82,0x09,0x82,0x0e,0x82,0x0a,0x85,0x0c,0x82,0x07,0x82,0x04,
0x82,0x04,0x82,0x03,0x82,0x05,0x82,0x06,0x82,0x06,0x82,0x06,0x82,0x05,0x82,
0x05,0x82,0x06,0x82,0x08,0x82,0x0b,0x85,0x0b,0x82,0x0b,0x82,0x06,0x82,0x06,
0x82,0x03,0x82,0x06,0x82,0x01,0x82,0x01,0x82,0x02,0x82,0x08,0x83,0x09,0x82,
0x03,0x82,0x0c,0x82,0x0a,0x82,0x0f,0x82,0x0f,0x83,0x06,0x82,0x02,0x83,0x02,
0x82,0x25,0x82,0x18,0x8b,0x0d,0x82,0x09,0x82,0x01,0x82,0x02,0x82,0x02,0x82,
0x03,0x83,0x02,0x82,0x15,0x82,0x0f,0x82,0x0a,0x82,0x01,0x82,0x0c,0x82,0x3a,
0x82,0x09,0x82,0x06,0x82,0x09,0x83,0x0c,0x82,0x11,0x82,0x05,0x82,0x04,0x83,
0x0e,0x82,0x05,0x83,0x05,0x82,0x09,0x82,0x09,0x82,0x06,0x82,0x08,0x83,0x02,
0x82,0x24,0x83,0x0c,0x89,0x0d,0x83,0x08,0x82,0x07,0x81,0x03,0x82,0x03,0x81,
0x03,0x81,0x04,0x89,0x05,0x82,0x07,0x82,0x03,0x82,0x0e,0x82,0x07,0x82,0x05,
0x82,0x0d,0x82,0x0b,0x82,0x08,0x82,0x03,0x82,0x08,0x82,0x08,0x82,0x11,0x82,
0x06,0x82,0x03,0x82,0x08,0x82,0x0a,0x82,0x03,0x81,0x02,0x81,0x03,0x82,0x03,
0x82,0x04,0x82,0x02,0x82,0x02,0x82,0x09,0x82,0x03,0x82,0x0c,0x82,0x09,0x82,
0x03,0x82,0x06,0x82,0x0e,0x82,0x08,0x83,0x08,0x82,0x07,0x82,0x06,0x82,0x02,
0x82,0x06,0x84,0x03,0x84,0x07,0x86,0x0b,0x82,0x0c,0x82,0x0f,0x82,0x0d,0x82,
0x0c,0x82,0x37,0x89,0x05,0x82,0x05,0x82,0x06,0x82,0x0d,0x82,0x06,0x82,0x05,
0x8a,0x09,0x82,0x09,0x82,0x06,0x82,0x06,0x82,0x05,0x82,0x09,0x82,0x0e,0x82,
0x0a,0x85,0x0c,0x82,0x07,0x82,0x04,0x82,0x04,0x82,0x03,0x82,0x05,0x82,0x06,
0x82,0x06,0x82,0x06,0x82,0x05,0x82,0x05,0x82,0x06,0x82,0x08,0x82,0x0d,0x85,
0x09,0x82,0x0b,0x82,0x06,0x82,0x07,0x82,0x02,0x81,0x07,0x82,0x01,0x81,0x02,
0x82,0x01,0x82,0x09,0x83,0x0a,0x82,0x01,0x83,0x0b,0x82,0x0c,0x82,0x0e,0x82,
0x0e,0x82,0x07,0x82,0x04,0x86,0x3f,0x8b,0x05,0x82,0x06,0x82,0x08,0x82,0x02,
0x81,0x04,0x81,0x02,0x82,0x04,0x85,0x16,0x82,0x0f,0x82,0x0e,0x81,0x0c,0x82,
0x39,0x82,0x0a,0x82,0x06,0x82,0x09,0x83,0x0b,0x83,0x11,0x82,0x05,0x8b,0x0c,
0x82,0x06,0x82,0x05,0x82,0x08,0x83,0x09,0x82,0x06,0x82,0x0d,0x82,0x25,0x85,
0x09,0x89,0x0a,0x85,0x09,0x82,0x07,0x81,0x03,0x82,0x03,0x81,0x02,0x82,0x04,
0x8a,0x04,0x82,0x07,0x82,0x03,0x83,0x07,0x82,0x04,0x82,0x07,0x82,0x05,0x82,
0x0d,0x82,0x0b,0x83,0x07,0x82,0x03,0x82,0x08,0x82,0x08,0x82,0x11,0x82,0x06,
0x82,0x03,0x83,0x07,0x82,0x0a,0x82,0x03,0x84,0x03,0x82,0x03,0x82,0x05,0x82,
0x01,0x82,0x02,0x83,0x07,0x83,0x03,0x82,0x0c,0x83,0x07,0x83,0x03,0x82,0x06,
0x83,0x04,0x82,0x07,0x82,0x08,0x83,0x08,0x82,0x07,0x82,0x06,0x82,0x01,0x83,
0x07,0x83,0x03,0x84,0x07,0x82,0x02,0x82,0x0b,0x82,0x0b,0x82,0x10,0x82,0x0e,
0x82,0x0b,0x82,0x36,0x83,0x04,0x83,0x05,0x82,0x05,0x82,0x06,0x82,0x0d,0x82,
0x06,0x82,0x05,0x82,0x11,0x82,0x09,0x82,0x06,0x82,0x06,0x82,0x05,0x82,0x09,
0x82,0x0e,0x82,0x0a,0x82,0x02,0x82,0x0b,0x82,0x07,0x82,0x04,0x82,0x04,0x82,
0x03,0x82,0x05,0x82,0x06,0x82,0x06,0x82,0x06,0x82,0x05,0x82,0x05,0x82,0x06,
0x82,0x08,0x82,0x10,0x83,0x08,0x82,0x0b,0x82,0x06,0x82,0x07,0x82,0x01,0x82,
0x08,0x83,0x03,0x81,0x01,0x82,0x08,0x85,0x09,0x82,0x01,0x82,0x0b,0x83,0x0d,
0x82,0x0d,0x82,0x0e,0x82,0x0f,0x82,0x43,0x82,0x02,0x82,0x08,0x83,0x05,0x82,
0x08,0x81,0x03,0x81,0x04,0x81,0x02,0x82,0x05,0x84,0x16,0x82,0x0f,0x82,0x1b,
0x82,0x39,0x82,0x0a,0x83,0x05,0x82,0x09,0x83,0x0a,0x83,0x0a,0x82,0x06,0x82,
0x0b,0x83,0x07,0x82,0x05,0x82,0x06,0x82,0x05,0x82,0x08,0x82,0x0a,0x82,0x06,
0x82,0x0c,0x83,0x27,0x85,0x18,0x84,0x15,0x82,0x02,0x82,0x02,0x82,0x02,0x81,
0x05,0x82,0x06,0x82,0x04,0x82,0x07,0x82,0x04,0x82,0x07,0x82,0x04,0x82,0x06,
0x83,0x05,0x82,0x0d,0x82,0x0c,0x82,0x07,0x82,0x03,0x82,0x08,0x82,0x08,0x82,
0x0a,0x82,0x05,0x82,0x06,0x82,0x04,0x83,0x06,0x82,0x0a,0x82,0x03,0x84,0x03,
0x82,0x03,0x82,0x05,0x85,0x03,0x82,0x07,0x82,0x04,0x82,0x0d,0x82,0x05,0x81,
0x01,0x82,0x04,0x82,0x06,0x83,0x04,0x83,0x06,0x82,0x08,0x83,0x08,0x82,0x07,
0x82,0x07,0x84,0x08,0x83,0x04,0x82,0x07,0x82,0x04,0x82,0x0a,0x82,0x0a,0x83,
0x10,0x82,0x0e,0x82,0x0b,0x82,0x36,0x82,0x05,0x83,0x05,0x82,0x05,0x82,0x06,
0x83,0x05,0x82,0x05,0x82,0x06,0x82,0x05,0x83,0x10,0x82,0x09,0x83,0x05,0x82,
0x06,0x82,0x05,0x82,0x09,0x82,0x0e,0x82,0x0a,0x82,0x02,0x83,0x0a,0x82,0x07,
0x82,0x04,0x82,0x04,0x82,0x03,0x82,0x05,0x82,0x06,0x83,0x05,0x82,0x06,0x82,
0x05,0x82,0x05,0x82,0x06,0x82,0x08,0x82,0x0a,0x82,0x05,0x82,0x08,0x82,0x0b,
0x82,0x06,0x82,0x08,0x81,0x01,0x82,0x08,0x83,0x03,0x84,0x08,0x82,0x01,0x82,
0x09,0x82,0x01,0x82,0x0b,0x82,0x0e,0x82,0x0d,0x82,0x0d,0x83,0x54,0x82,0x02,
0x82,0x09,0x82,0x04,0x83,0x07,0x82,0x03,0x81,0x04,0x81,0x02,0x82,0x06,0x82,
0x18,0x82,0x0d,0x82,0x1c,0x82,0x39,0x81,0x0c,0x82,0x04,0x83,0x09,0x83,0x09,
0x83,0x0c,0x82,0x05,0x82,0x0b,0x83,0x07,0x82,0x04,0x83,0x06,0x83,0x04,0x82,
0x08,0x82,0x0a,0x83,0x05,0x82,0x0c,0x82,0x2b,0x83,0x15,0x84,0x18,0x81,0x03,
0x83,0x01,0x83,0x05,0x82,0x07,0x83,0x03,0x82,0x06,0x83,0x04,0x83,0x05,0x82,
0x05,0x82,0x06,0x82,0x06,0x82,0x0d,0x82,0x0c,0x83,0x06,0x82,0x03,0x82,0x08,
0x82,0x08,0x82,0x0a,0x82,0x05,0x82,0x06,0x82,0x05,0x83,0x05,0x82,0x0a,0x82,
0x04,0x82,0x04,0x82,0x03,0x82,0x06,0x84,0x03,0x83,0x05,0x83,0x04,0x82,0x0d,
0x83,0x05,0x83,0x04,0x82,0x06,0x83,0x05,0x82,0x06,0x82,0x08,0x83,0x08,0x83,
0x05,0x83,0x07,0x84,0x08,0x82,0x05,0x82,0x06,0x83,0x04,0x83,0x09,0x82,0x0a,
0x82,0x11,0x82,0x0e,0x82,0x0b,0x82,0x36,0x82,0x05,0x83,0x05,0x83,0x04,0x82,
0x07,0x82,0x05,0x82,0x06,0x82,0x04,0x83,0x06,0x82,0x10,0x82,0x0a,0x82,0x04,
0x83,0x06,0x82,0x05,0x82,0x09,0x82,0x0e,0x82,0x0a,0x82,0x03,0x82,0x0a,0x82,
0x07,0x82,0x04,0x82,0x04,0x82,0x03,0x82,0x05,0x82,0x07,0x82,0x04,0x83,0x06,
0x82,0x05,0x82,0x06,0x82,0x04,0x83,0x08,0x82,0x0a,0x83,0x04,0x82,0x08,0x82,
0x03,0x82,0x06,0x83,0x04,0x83,0x08,0x83,0x09,0x82,0x04,0x83,0x08,0x82,0x03,
0x82,0x09,0x83,0x0b,0x82,0x0f,0x82,0x0d,0x82,0x0d,0x83,0x38,0x82,0x1a,0x81,
0x03,0x82,0x09,0x88,0x08,0x81,0x04,0x82,0x02,0x82,0x03,0x83,0x02,0x85,0x17,
0x82,0x0d,0x82,0x29,0x82,0x1d,0x82,0x0c,0x82,0x0c,0x83,0x02,0x83,0x0a,0x83,
0x09,0x89,0x06,0x84,0x01,0x83,0x0c,0x83,0x07,0x84,0x01,0x83,0x08,0x83,0x01,
0x83,0x09,0x82,0x0b,0x84,0x01,0x83,0x07,0x82,0x02,0x84,0x09,0x82,0x0d,0x82,
0x13,0x81,0x15,0x82,0x10,0x82,0x08,0x81,0x0f,0x82,0x08,0x82,0x03,0x8a,0x06,
0x83,0x02,0x84,0x05,0x89,0x07,0x89,0x06,0x82,0x0d,0x84,0x02,0x84,0x03,0x82,
0x08,0x82,0x06,0x86,0x09,0x83,0x01,0x83,0x07,0x82,0x06,0x83,0x04,0x8a,0x02,
0x82,0x04,0x82,0x04,0x82,0x03,0x82,0x07,0x83,0x04,0x89,0x05,0x82,0x0e,0x8a,
0x04,0x82,0x07,0x82,0x05,0x84,0x02,0x83,0x09,0x83,0x09,0x84,0x01,0x84,0x08,
0x83,0x09,0x82,0x05,0x82,0x06,0x82,0x06,0x82,0x09,0x82,0x09,0x8b,0x09,0x82,
0x0f,0x82,0x0a,0x82,0x37,0x89,0x05,0x88,0x08,0x88,0x07,0x89,0x06,0x84,0x02,
0x82,0x0a,0x82,0x0a,0x89,0x06,0x82,0x05,0x82,0x06,0x88,0x0b,0x82,0x0a,0x82,
0x04,0x82,0x06,0x88,0x04,0x82,0x04,0x82,0x04,0x82,0x03,0x82,0x05,0x82,0x07,
0x84,0x01,0x83,0x07,0x84,0x01,0x83,0x07,0x83,0x02,0x84,0x08,0x82,0x0b,0x83,
0x02,0x83,0x08,0x87,0x06,0x8a,0x08,0x83,0x09,0x82,0x05,0x82,0x07,0x83,0x03,
0x83,0x08,0x83,0x0a,0x89,0x09,0x82,0x0d,0x82,0x0d,0x83,0x38,0x82,0x1a,0x81,
0x03,0x82,0x0a,0x86,0x0f,0x84,0x05,0x86,0x01,0x83,0x16,0x82,0x0d,0x82,0x29,
0x82,0x1d,0x82,0x0c,0x82,0x0d,0x86,0x0b,0x83,0x09,0x89,0x07,0x86,0x0d,0x83,
0x08,0x86,0x0a,0x85,0x0a,0x82,0x0c,0x86,0x08,0x86,0x0b,0x82,0x0d,0x82,0x3b,
0x82,0x09,0x81,0x0e,0x82,0x08,0x82,0x03,0x89,0x08,0x86,0x07,0x88,0x08,0x89,
0x06,0x82,0x0e,0x87,0x05,0x82,0x08,0x82,0x06,0x86,0x0a,0x85,0x08,0x82,0x07,
0x82,0x04,0x8a,0x02,0x82,0x0a,0x82,0x03,0x82,0x07,0x83,0x05,0x86,0x07,0x82,
0x0f,0x86,0x01,0x83,0x03,0x82,0x07,0x82,0x07,0x86,0x0a,0x83,0x0a,0x87,0x0a,
0x82,0x09,0x82,0x06,0x81,0x05,0x83,0x06,0x83,0x08,0x82,0x09,0x8b,0x09,0x82,
0x0f,0x82,0x0a,0x82,0x37,0x85,0x02,0x82,0x05,0x81,0x01,0x85,0x0b,0x85,0x09,
0x85,0x01,0x82,0x08,0x86,0x0a,0x82,0x0b,0x85,0x01,0x82,0x06,0x82,0x05,0x82,
0x06,0x88,0x0b,0x82,0x0a,0x82,0x04,0x83,0x05,0x88,0x04,0x82,0x04,0x82,0x04,
0x82,0x03,0x82,0x05,0x82,0x09,0x85,0x08,0x87,0x09,0x85,0x01,0x82,0x08,0x82,
0x0c,0x86,0x0a,0x84,0x09,0x86,0x01,0x82,0x09,0x82,0x0a,0x81,0x05,0x82,0x07,
0x82,0x05,0x82,0x08,0x83,0x0a,0x89,0x09,0x82,0x0d,0x82,0x0d,0x82,0x68,0x81,
0x3b,0x82,0x0b,0x82,0x2a,0x82,0x2a,0x82,0x7f,0x35,0x82,0x46,0x83,0x7f,0x7f,
0x08,0x82,0x7f,0x10,0x82,0x10,0x82,0x09,0x82,0x18,0x8a,0x76,0x82,0x28,0x82,
0x54,0x82,0x14,0x82,0x71,0x82,0x1d,0x82,0x0d,0x82,0x0d,0x82,0x68,0x81,0x3b,
0x82,0x0b,0x82,0x2a,0x82,0x2a,0x82,0x7f,0x35,0x82,0x48,0x86,0x7f,0x7f,0x7f,
0x15,0x84,0x0e,0x82,0x07,0x84,0x18,0x8a,0x76,0x82,0x28,0x82,0x54,0x82,0x14,
0x82,0x71,0x82,0x1d,0x83,0x0c,0x82,0x0d,0x82,0x7f,0x26,0x82,0x09,0x82,0x2b,
0x81,0x7f,0x62,0x81,0x7f,0x7f,0x7f,0x64,0x84,0x17,0x84,0x7f,0x12,0x82,0x04,
0x82,0x28,0x83,0x54,0x82,0x14,0x82,0x70,0x83,0x1e,0x83,0x0b,0x82,0x0c,0x82,
0x7f,0x28,0x82,0x07,0x82,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x27,0x88,0x26,
0x84,0x55,0x82,0x14,0x82,0x6e,0x84,0x21,0x81,0x0b,0x82,0x0c,0x81,0x7f,0x2a,
0x81,0x07,0x81,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x2a,0x84,0x28,0x83,0x7f,
0x5d,0x83,0x64,
0x00,
}
};

View File

@ -4,10 +4,6 @@ ifeq ($(TARGET_ARCH),arm)
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
ifeq ($(BOARD_HAS_LARGE_FILESYSTEM),true)
LOCAL_CFLAGS += -DBOARD_HAS_LARGE_FILESYSTEM
endif
LOCAL_SRC_FILES := \
mmcutils.c

View File

@ -340,13 +340,8 @@ run_exec_process ( char **argv) {
int
format_ext3_device (const char *device) {
#ifdef BOARD_HAS_LARGE_FILESYSTEM
char *const mke2fs[] = {MKE2FS_BIN, "-j", "-q", device, NULL};
char *const tune2fs[] = {TUNE2FS_BIN, "-C", "1", device, NULL};
#else
char *const mke2fs[] = {MKE2FS_BIN, "-j", device, NULL};
char *const tune2fs[] = {TUNE2FS_BIN, "-j", "-C", "1", device, NULL};
#endif
// Run mke2fs
if(run_exec_process(mke2fs)) {
printf("failure while running mke2fs\n");

View File

@ -1,6 +1,3 @@
ifneq ($(TARGET_SIMULATOR),true)
ifeq ($(TARGET_ARCH),arm)
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
@ -30,6 +27,3 @@ LOCAL_STATIC_LIBRARIES := libmtdutils libcutils libc
LOCAL_FORCE_STATIC_EXECUTABLE := true
include $(BUILD_EXECUTABLE)
endif
endif # TARGET_ARCH == arm
endif # !TARGET_SIMULATOR

View File

@ -262,8 +262,8 @@ MtdReadContext *mtd_read_partition(const MtdPartition *partition)
sprintf(mtddevname, "/dev/mtd/mtd%d", partition->device_index);
ctx->fd = open(mtddevname, O_RDONLY);
if (ctx->fd < 0) {
free(ctx);
free(ctx->buffer);
free(ctx);
return NULL;
}
@ -572,17 +572,22 @@ int cmd_mtd_restore_raw_partition(const char *partition_name, const char *filena
const MtdPartition *ptn;
MtdWriteContext *write;
void *data;
unsigned sz;
FILE* f = fopen(filename, "rb");
if (f == NULL) {
fprintf(stderr, "error opening %s", filename);
return -1;
}
if (mtd_scan_partitions() <= 0)
{
printf("error scanning partitions");
fprintf(stderr, "error scanning partitions");
return -1;
}
const MtdPartition *partition = mtd_find_partition_by_name(partition_name);
if (partition == NULL)
const MtdPartition *mtd = mtd_find_partition_by_name(partition_name);
if (mtd == NULL)
{
printf("can't find %s partition", partition_name);
fprintf(stderr, "can't find %s partition", partition_name);
return -1;
}
@ -592,107 +597,35 @@ int cmd_mtd_restore_raw_partition(const char *partition_name, const char *filena
printf("error opening %s", filename);
return -1;
}
char header[HEADER_SIZE];
int headerlen = read(fd, header, sizeof(header));
if (headerlen <= 0)
{
printf("error reading %s header", filename);
return -1;
}
// Skip the header (we'll come back to it), write everything else
printf("flashing %s from %s\n", partition_name, filename);
MtdWriteContext *out = mtd_write_partition(partition);
if (out == NULL)
{
printf("error writing %s", partition_name);
return -1;
}
char buf[HEADER_SIZE];
memset(buf, 0, headerlen);
int wrote = mtd_write_data(out, buf, headerlen);
if (wrote != headerlen)
{
MtdWriteContext* ctx = mtd_write_partition(mtd);
if (ctx == NULL) {
printf("error writing %s", partition_name);
return -1;
}
int len;
while ((len = read(fd, buf, sizeof(buf))) > 0) {
wrote = mtd_write_data(out, buf, len);
if (wrote != len)
{
printf("error writing %s", partition_name);
return -1;
}
}
if (len < 0)
{
printf("error reading %s", filename);
return -1;
int success = 1;
char* buffer = malloc(BUFSIZ);
int read;
while (success && (read = fread(buffer, 1, BUFSIZ, f)) > 0) {
int wrote = mtd_write_data(ctx, buffer, read);
success = success && (wrote == read);
}
free(buffer);
fclose(f);
if (mtd_write_close(out))
{
printf("error closing %s", partition_name);
if (!success) {
fprintf(stderr, "error writing %s", partition_name);
return -1;
}
// Now come back and write the header last
out = mtd_write_partition(partition);
if (out == NULL)
{
printf("error re-opening %s", partition_name);
return -1;
if (mtd_erase_blocks(ctx, -1) == -1) {
fprintf(stderr, "error erasing blocks of %s\n", partition_name);
}
wrote = mtd_write_data(out, header, headerlen);
if (wrote != headerlen)
{
printf("error re-writing %s", partition_name);
return -1;
}
// Need to write a complete block, so write the rest of the first block
size_t block_size;
if (mtd_partition_info(partition, NULL, &block_size, NULL))
{
printf("error getting %s block size", partition_name);
return -1;
}
if (lseek(fd, headerlen, SEEK_SET) != headerlen)
{
printf("error rewinding %s", filename);
return -1;
}
int left = block_size - headerlen;
while (left < 0) left += block_size;
while (left > 0) {
len = read(fd, buf, left > (int)sizeof(buf) ? (int)sizeof(buf) : left);
if (len <= 0){
printf("error reading %s", filename);
return -1;
}
if (mtd_write_data(out, buf, len) != len)
{
printf("error writing %s", partition_name);
return -1;
}
left -= len;
}
if (mtd_write_close(out))
{
printf("error closing %s", partition_name);
return -1;
if (mtd_write_close(ctx) != 0) {
fprintf(stderr, "error closing write of %s\n", partition_name);
}
printf("%s %s partition\n", success ? "wrote" : "failed to write", partition_name);
return 0;
}

View File

@ -233,20 +233,25 @@ int nandroid_backup(const char* backup_path)
}
Volume* volume = volume_for_path(backup_path);
if (NULL == volume)
return print_and_error("Unable to find volume for backup path.\n");
if (NULL == volume) {
if (strstr(backup_path, "/sdcard") == backup_path && is_data_media())
volume = volume_for_path("/data");
else
return print_and_error("Unable to find volume for backup path.\n");
}
int ret;
struct statfs s;
if (0 != (ret = statfs(volume->mount_point, &s)))
return print_and_error("Unable to stat backup path.\n");
uint64_t bavail = s.f_bavail;
uint64_t bsize = s.f_bsize;
uint64_t sdcard_free = bavail * bsize;
uint64_t sdcard_free_mb = sdcard_free / (uint64_t)(1024 * 1024);
ui_print("SD Card space free: %lluMB\n", sdcard_free_mb);
if (sdcard_free_mb < 150)
ui_print("There may not be enough free space to complete backup... continuing...\n");
if (NULL != volume) {
if (0 != (ret = statfs(volume->mount_point, &s)))
return print_and_error("Unable to stat backup path.\n");
uint64_t bavail = s.f_bavail;
uint64_t bsize = s.f_bsize;
uint64_t sdcard_free = bavail * bsize;
uint64_t sdcard_free_mb = sdcard_free / (uint64_t)(1024 * 1024);
ui_print("SD Card space free: %lluMB\n", sdcard_free_mb);
if (sdcard_free_mb < 150)
ui_print("There may not be enough free space to complete backup... continuing...\n");
}
char tmp[PATH_MAX];
sprintf(tmp, "mkdir -p %s", backup_path);
__system(tmp);
@ -431,16 +436,23 @@ int nandroid_restore_partition_extended(const char* backup_path, const char* mou
printf("Found new backup image: %s\n", tmp);
}
// If the fs_type of this volume is "auto", let's revert to using a
// rm -rf, rather than trying to do a ext3/ext4/whatever format.
// If the fs_type of this volume is "auto" or mount_point is /data
// and is_data_media (redundantly, and vol for /sdcard is NULL), let's revert
// to using a rm -rf, rather than trying to do a
// ext3/ext4/whatever format.
// This is because some phones (like DroidX) will freak out if you
// reformat the /system or /data partitions, and not boot due to
// a locked bootloader.
// Other devices, like the Galaxy Nexus, XOOM, and Galaxy Tab 10.1
// have a /sdcard symlinked to /data/media. /data is set to "auto"
// so that when the format occurs, /data/media is not erased.
// The "auto" fs type preserves the file system, and does not
// trigger that lock.
// Or of volume does not exist (.android_secure), just rm -rf.
if (vol == NULL || 0 == strcmp(vol->fs_type, "auto"))
backup_filesystem = NULL;
else if (0 == strcmp(vol->mount_point, "/data") && volume_for_path("/sdcard") == NULL && is_data_media())
backup_filesystem = NULL;
}
ensure_directory(mount_point);

View File

@ -24,7 +24,6 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/reboot.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <time.h>
@ -35,12 +34,12 @@
#include "bootloader.h"
#include "common.h"
#include "cutils/properties.h"
#include "cutils/android_reboot.h"
#include "install.h"
#include "minui/minui.h"
#include "minzip/DirUtil.h"
#include "roots.h"
#include "recovery_ui.h"
#include "encryptedfs_provisioning.h"
#include "extendedcommands.h"
#include "flashutils/flashutils.h"
@ -50,7 +49,6 @@ static const struct option OPTIONS[] = {
{ "update_package", required_argument, NULL, 'u' },
{ "wipe_data", no_argument, NULL, 'w' },
{ "wipe_cache", no_argument, NULL, 'c' },
{ "set_encrypted_filesystems", required_argument, NULL, 'e' },
{ "show_text", no_argument, NULL, 't' },
{ NULL, 0, NULL, 0 },
};
@ -59,6 +57,7 @@ static const char *COMMAND_FILE = "/cache/recovery/command";
static const char *INTENT_FILE = "/cache/recovery/intent";
static const char *LOG_FILE = "/cache/recovery/log";
static const char *LAST_LOG_FILE = "/cache/recovery/last_log";
static const char *CACHE_ROOT = "/cache";
static const char *SDCARD_ROOT = "/sdcard";
static int allow_display_toggle = 1;
static int poweroff = 0;
@ -66,6 +65,8 @@ static const char *SDCARD_PACKAGE_FILE = "/sdcard/update.zip";
static const char *TEMPORARY_LOG_FILE = "/tmp/recovery.log";
static const char *SIDELOAD_TEMP_DIR = "/tmp/sideload";
extern UIParameters ui_parameters; // from ui.c
/*
* The recovery tool communicates with the main system through /cache files.
* /cache/recovery/command - INPUT - command line for tool, one arg per line
@ -122,33 +123,13 @@ static const char *SIDELOAD_TEMP_DIR = "/tmp/sideload";
* 8g. finish_recovery() erases BCB
* -- after this, rebooting will (try to) restart the main system --
* 9. main() calls reboot() to boot main system
*
* SECURE FILE SYSTEMS ENABLE/DISABLE
* 1. user selects "enable encrypted file systems"
* 2. main system writes "--set_encrypted_filesystems=on|off" to
* /cache/recovery/command
* 3. main system reboots into recovery
* 4. get_args() writes BCB with "boot-recovery" and
* "--set_encrypted_filesystems=on|off"
* -- after this, rebooting will restart the transition --
* 5. read_encrypted_fs_info() retrieves encrypted file systems settings from /data
* Settings include: property to specify the Encrypted FS istatus and
* FS encryption key if enabled (not yet implemented)
* 6. erase_volume() reformats /data
* 7. erase_volume() reformats /cache
* 8. restore_encrypted_fs_info() writes required encrypted file systems settings to /data
* Settings include: property to specify the Encrypted FS status and
* FS encryption key if enabled (not yet implemented)
* 9. finish_recovery() erases BCB
* -- after this, rebooting will restart the main system --
* 10. main() calls reboot() to boot main system
*/
static const int MAX_ARG_LENGTH = 4096;
static const int MAX_ARGS = 100;
// open a given path, mounting partitions as necessary
static FILE*
FILE*
fopen_path(const char *path, const char *mode) {
if (ensure_path_mounted(path) != 0) {
LOGE("Can't mount %s\n", path);
@ -180,7 +161,7 @@ static void
get_args(int *argc, char ***argv) {
struct bootloader_message boot;
memset(&boot, 0, sizeof(boot));
if (device_flash_type() == MTD) {
if (device_flash_type() == MTD || device_flash_type() == MMC) {
get_bootloader_message(&boot); // this may fail, leaving a zeroed structure
}
@ -239,9 +220,7 @@ get_args(int *argc, char ***argv) {
strlcat(boot.recovery, (*argv)[i], sizeof(boot.recovery));
strlcat(boot.recovery, "\n", sizeof(boot.recovery));
}
if (device_flash_type() == MTD) {
set_bootloader_message(&boot);
}
set_bootloader_message(&boot);
}
void
@ -303,12 +282,10 @@ finish_recovery(const char *send_intent) {
copy_log_file(LAST_LOG_FILE, false);
chmod(LAST_LOG_FILE, 0640);
if (device_flash_type() == MTD) {
// Reset to mormal system boot so recovery won't cycle indefinitely.
struct bootloader_message boot;
memset(&boot, 0, sizeof(boot));
set_bootloader_message(&boot);
}
// Reset to normal system boot so recovery won't cycle indefinitely.
struct bootloader_message boot;
memset(&boot, 0, sizeof(boot));
set_bootloader_message(&boot);
// Remove the command file, so recovery won't repeat indefinitely.
if (ensure_path_mounted(COMMAND_FILE) != 0 ||
@ -453,7 +430,8 @@ get_menu_selection(char** headers, char** items, int menu_only,
// throw away keys pressed previously, so user doesn't
// accidentally trigger menu items.
ui_clear_key_queue();
++ui_menu_level;
int item_count = ui_start_menu(headers, items, initial_selection);
int selected = initial_selection;
int chosen_item = -1;
@ -467,6 +445,16 @@ get_menu_selection(char** headers, char** items, int menu_only,
int key = ui_wait_key();
int visible = ui_text_visible();
if (key == -1) { // ui_wait_key() timed out
if (ui_text_ever_visible()) {
continue;
} else {
LOGI("timed out waiting for key input; rebooting.\n");
ui_end_menu();
return ITEM_REBOOT;
}
}
int action = device_handle_key(key, visible);
int old_selected = selected;
@ -484,7 +472,8 @@ get_menu_selection(char** headers, char** items, int menu_only,
case SELECT_ITEM:
chosen_item = selected;
if (ui_get_showing_back_button()) {
if (chosen_item == item_count) {
if (chosen_item == item_count-1) {
--ui_menu_level;
chosen_item = GO_BACK;
}
}
@ -492,6 +481,7 @@ get_menu_selection(char** headers, char** items, int menu_only,
case NO_ACTION:
break;
case GO_BACK:
--ui_menu_level;
chosen_item = GO_BACK;
break;
}
@ -525,8 +515,8 @@ static int compare_string(const void* a, const void* b) {
}
static int
sdcard_directory(const char* path) {
ensure_path_mounted(SDCARD_ROOT);
update_directory(const char* path, const char* unmount_when_done) {
ensure_path_mounted(path);
const char* MENU_HEADERS[] = { "Choose a package to install:",
path,
@ -537,7 +527,9 @@ sdcard_directory(const char* path) {
d = opendir(path);
if (d == NULL) {
LOGE("error opening %s: %s\n", path, strerror(errno));
ensure_path_unmounted(SDCARD_ROOT);
if (unmount_when_done != NULL) {
ensure_path_unmounted(unmount_when_done);
}
return 0;
}
@ -602,7 +594,7 @@ sdcard_directory(const char* path) {
char* item = zips[chosen_item];
int item_len = strlen(item);
if (chosen_item == 0) { // item 0 is always "../"
// go up but continue browsing (if the caller is sdcard_directory)
// go up but continue browsing (if the caller is update_directory)
result = -1;
break;
} else if (item[item_len-1] == '/') {
@ -612,7 +604,7 @@ sdcard_directory(const char* path) {
strlcat(new_path, "/", PATH_MAX);
strlcat(new_path, item, PATH_MAX);
new_path[strlen(new_path)-1] = '\0'; // truncate the trailing '/'
result = sdcard_directory(new_path);
result = update_directory(new_path, unmount_when_done);
if (result >= 0) break;
} else {
// selected a zip file: attempt to install it, and return
@ -625,7 +617,9 @@ sdcard_directory(const char* path) {
ui_print("\n-- Install %s ...\n", path);
set_sdcard_update_bootloader_message();
char* copy = copy_sideloaded_package(new_path);
ensure_path_unmounted(SDCARD_ROOT);
if (unmount_when_done != NULL) {
ensure_path_unmounted(unmount_when_done);
}
if (copy) {
result = install_package(copy);
free(copy);
@ -641,7 +635,9 @@ sdcard_directory(const char* path) {
free(zips);
free(headers);
ensure_path_unmounted(SDCARD_ROOT);
if (unmount_when_done != NULL) {
ensure_path_unmounted(unmount_when_done);
}
return result;
}
@ -687,7 +683,8 @@ prompt_and_wait() {
for (;;) {
finish_recovery(NULL);
ui_reset_progress();
ui_menu_level = -1;
allow_display_toggle = 1;
int chosen_item = get_menu_selection(headers, MENU_ITEMS, 0, 0);
allow_display_toggle = 0;
@ -697,6 +694,7 @@ prompt_and_wait() {
// statement below.
chosen_item = device_perform_action(chosen_item);
int status;
switch (chosen_item) {
case ITEM_REBOOT:
poweroff=0;
@ -718,34 +716,23 @@ prompt_and_wait() {
break;
case ITEM_APPLY_SDCARD:
if (confirm_selection("Confirm install?", "Yes - Install /sdcard/update.zip"))
{
ui_print("\n-- Install from sdcard...\n");
int status = install_package(SDCARD_PACKAGE_FILE);
if (status != INSTALL_SUCCESS) {
ui_set_background(BACKGROUND_ICON_ERROR);
ui_print("Installation aborted.\n");
} else if (!ui_text_visible()) {
return; // reboot if logs aren't visible
} else {
ui_print("\nInstall from sdcard complete.\n");
}
}
break;
case ITEM_INSTALL_ZIP:
show_install_update_menu();
break;
case ITEM_NANDROID:
show_nandroid_menu();
break;
case ITEM_PARTITION:
show_partition_menu();
break;
case ITEM_ADVANCED:
show_advanced_menu();
break;
case ITEM_POWEROFF:
poweroff=1;
poweroff = 1;
return;
}
}
@ -802,6 +789,7 @@ main(int argc, char **argv) {
freopen(TEMPORARY_LOG_FILE, "a", stderr); setbuf(stderr, NULL);
printf("Starting recovery on %s", ctime(&start));
device_ui_init(&ui_parameters);
ui_init();
ui_print(EXPAND(RECOVERY_VERSION)"\n");
load_volume_table();
@ -812,10 +800,7 @@ main(int argc, char **argv) {
int previous_runs = 0;
const char *send_intent = NULL;
const char *update_package = NULL;
const char *encrypted_fs_mode = NULL;
int wipe_data = 0, wipe_cache = 0;
int toggle_secure_fs = 0;
encrypted_fs_info encrypted_fs_data;
LOGI("Checking arguments.\n");
int arg;
@ -830,7 +815,6 @@ main(int argc, char **argv) {
#endif
break;
case 'c': wipe_cache = 1; break;
case 'e': encrypted_fs_mode = optarg; toggle_secure_fs = 1; break;
case 't': ui_show_text(1); break;
case '?':
LOGE("Invalid command argument\n");
@ -867,49 +851,14 @@ main(int argc, char **argv) {
printf("\n");
int status = INSTALL_SUCCESS;
if (toggle_secure_fs) {
if (strcmp(encrypted_fs_mode,"on") == 0) {
encrypted_fs_data.mode = MODE_ENCRYPTED_FS_ENABLED;
ui_print("Enabling Encrypted FS.\n");
} else if (strcmp(encrypted_fs_mode,"off") == 0) {
encrypted_fs_data.mode = MODE_ENCRYPTED_FS_DISABLED;
ui_print("Disabling Encrypted FS.\n");
} else {
ui_print("Error: invalid Encrypted FS setting.\n");
status = INSTALL_ERROR;
}
// Recovery strategy: if the data partition is damaged, disable encrypted file systems.
// This preventsthe device recycling endlessly in recovery mode.
if ((encrypted_fs_data.mode == MODE_ENCRYPTED_FS_ENABLED) &&
(read_encrypted_fs_info(&encrypted_fs_data))) {
ui_print("Encrypted FS change aborted, resetting to disabled state.\n");
encrypted_fs_data.mode = MODE_ENCRYPTED_FS_DISABLED;
}
if (status != INSTALL_ERROR) {
if (erase_volume("/data")) {
ui_print("Data wipe failed.\n");
status = INSTALL_ERROR;
} else if (erase_volume("/cache")) {
ui_print("Cache wipe failed.\n");
status = INSTALL_ERROR;
} else if ((encrypted_fs_data.mode == MODE_ENCRYPTED_FS_ENABLED) &&
(restore_encrypted_fs_info(&encrypted_fs_data))) {
ui_print("Encrypted FS change aborted.\n");
status = INSTALL_ERROR;
} else {
ui_print("Successfully updated Encrypted FS.\n");
status = INSTALL_SUCCESS;
}
}
} else if (update_package != NULL) {
if (update_package != NULL) {
status = install_package(update_package);
if (status != INSTALL_SUCCESS) ui_print("Installation aborted.\n");
} else if (wipe_data) {
if (device_wipe_data()) status = INSTALL_ERROR;
if (erase_volume("/data")) status = INSTALL_ERROR;
if (has_datadata() && erase_volume("/datadata")) status = INSTALL_ERROR;
if (wipe_cache && erase_volume("/cache")) status = INSTALL_ERROR;
if (status != INSTALL_SUCCESS) ui_print("Data wipe failed.\n");
} else if (wipe_cache) {
@ -941,7 +890,10 @@ main(int argc, char **argv) {
}
}
if (status != INSTALL_SUCCESS && !is_user_initiated_recovery) ui_set_background(BACKGROUND_ICON_ERROR);
if (status != INSTALL_SUCCESS && !is_user_initiated_recovery) {
ui_set_show_text(1);
ui_set_background(BACKGROUND_ICON_ERROR);
}
if (status != INSTALL_SUCCESS || ui_text_visible()) {
prompt_and_wait();
}
@ -951,12 +903,16 @@ main(int argc, char **argv) {
// Otherwise, get ready to boot the main system...
finish_recovery(send_intent);
if(!poweroff)
ui_print("Rebooting...\n");
else
ui_print("Shutting down...\n");
sync();
reboot((!poweroff) ? RB_AUTOBOOT : RB_POWER_OFF);
if(!poweroff) {
ui_print("Rebooting...\n");
android_reboot(ANDROID_RB_RESTART, 0, 0);
}
else {
ui_print("Shutting down...\n");
android_reboot(ANDROID_RB_POWEROFF, 0, 0);
}
return EXIT_SUCCESS;
}

View File

@ -17,6 +17,12 @@
#ifndef _RECOVERY_UI_H
#define _RECOVERY_UI_H
#include "common.h"
// Called before UI library is initialized. Can change things like
// how many frames are included in various animations, etc.
extern void device_ui_init(UIParameters* ui_parameters);
// Called when recovery starts up. Returns 0.
extern int device_recovery_start();
@ -67,14 +73,16 @@ int device_wipe_data();
#define GO_BACK -5
#define ITEM_REBOOT 0
#define ITEM_APPLY_SDCARD 1
#define ITEM_APPLY_EXT 1
#define ITEM_APPLY_SDCARD 1 // historical synonym for ITEM_APPLY_EXT
#define ITEM_WIPE_DATA 2
#define ITEM_WIPE_CACHE 3
#define ITEM_INSTALL_ZIP 4
#define ITEM_NANDROID 5
#define ITEM_PARTITION 6
#define ITEM_ADVANCED 7
#define ITEM_POWEROFF 8
// unused in cwr
#define ITEM_APPLY_CACHE 4
#define ITEM_NANDROID 4
#define ITEM_PARTITION 5
#define ITEM_ADVANCED 6
#define ITEM_POWEROFF 7
// Header text to display above the main menu.
extern char* MENU_HEADERS[];
@ -82,6 +90,9 @@ extern char* MENU_HEADERS[];
// Text of menu items.
extern char* MENU_ITEMS[];
// Loosely track the depth of the current menu
int ui_menu_level;
int
get_menu_selection(char** headers, char** items, int menu_only, int initial_selection);

BIN
res/images/icon_error.png Executable file → Normal file

Binary file not shown.

Before

Width:  |  Height:  |  Size: 10 KiB

After

Width:  |  Height:  |  Size: 19 KiB

BIN
res/images/icon_installing.png Executable file → Normal file

Binary file not shown.

Before

Width:  |  Height:  |  Size: 11 KiB

After

Width:  |  Height:  |  Size: 25 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 673 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 687 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 661 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 665 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 683 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 676 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 361 B

After

Width:  |  Height:  |  Size: 118 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 286 B

After

Width:  |  Height:  |  Size: 404 B

75
roots.c
View File

@ -56,6 +56,28 @@ static char* dupe_string(const char* sz) {
return strdup(sz);
}
static int parse_options(char* options, Volume* volume) {
char* option;
while (option = strtok(options, ",")) {
options = NULL;
if (strncmp(option, "length=", 7) == 0) {
volume->length = strtoll(option+7, NULL, 10);
} else if (strncmp(option, "fstype2=", 8) == 0) {
volume->fs_type2 = volume->fs_type;
volume->fs_type = strdup(option + 8);
} else if (strncmp(option, "fs_options=", 11) == 0) {
volume->fs_options = strdup(option + 11);
} else if (strncmp(option, "fs_options2=", 12) == 0) {
volume->fs_options2 = strdup(option + 12);
} else {
LOGE("bad option \"%s\"\n", option);
return -1;
}
}
return 0;
}
void load_volume_table() {
int alloc = 2;
device_volumes = malloc(alloc * sizeof(Volume));
@ -65,8 +87,10 @@ void load_volume_table() {
device_volumes[0].fs_type = "ramdisk";
device_volumes[0].device = NULL;
device_volumes[0].device2 = NULL;
device_volumes[0].fs_type2 = NULL;
device_volumes[0].fs_options = NULL;
device_volumes[0].fs_options2 = NULL;
device_volumes[0].length = 0;
num_volumes = 1;
FILE* fstab = fopen("/etc/recovery.fstab", "r");
@ -88,10 +112,16 @@ void load_volume_table() {
char* device = strtok(NULL, " \t\n");
// lines may optionally have a second device, to use if
// mounting the first one fails.
char* options = NULL;
char* device2 = strtok(NULL, " \t\n");
char* fs_type2 = strtok(NULL, " \t\n");
char* fs_options = strtok(NULL, " \t\n");
char* fs_options2 = strtok(NULL, " \t\n");
if (device2) {
if (device2[0] == '/') {
options = strtok(NULL, " \t\n");
} else {
options = device2;
device2 = NULL;
}
}
if (mount_point && fs_type && device) {
while (num_volumes >= alloc) {
@ -99,21 +129,22 @@ void load_volume_table() {
device_volumes = realloc(device_volumes, alloc*sizeof(Volume));
}
device_volumes[num_volumes].mount_point = strdup(mount_point);
device_volumes[num_volumes].fs_type = !is_null(fs_type2) ? strdup(fs_type2) : strdup(fs_type);
device_volumes[num_volumes].fs_type = strdup(fs_type);
device_volumes[num_volumes].device = strdup(device);
device_volumes[num_volumes].device2 =
!is_null(device2) ? strdup(device2) : NULL;
device_volumes[num_volumes].fs_type2 = !is_null(fs_type2) ? strdup(fs_type) : NULL;
device2 ? strdup(device2) : NULL;
if (!is_null(fs_type2)) {
device_volumes[num_volumes].fs_options2 = dupe_string(fs_options);
device_volumes[num_volumes].fs_options = dupe_string(fs_options2);
device_volumes[num_volumes].length = 0;
device_volumes[num_volumes].fs_type2 = NULL;
device_volumes[num_volumes].fs_options = NULL;
device_volumes[num_volumes].fs_options2 = NULL;
if (parse_options(options, device_volumes + num_volumes) != 0) {
LOGE("skipping malformed recovery.fstab line: %s\n", original);
} else {
++num_volumes;
}
else {
device_volumes[num_volumes].fs_options2 = NULL;
device_volumes[num_volumes].fs_options = dupe_string(fs_options);
}
++num_volumes;
} else {
LOGE("skipping malformed recovery.fstab line: %s\n", original);
}
@ -126,8 +157,8 @@ void load_volume_table() {
printf("=========================\n");
for (i = 0; i < num_volumes; ++i) {
Volume* v = &device_volumes[i];
printf(" %d %s %s %s %s\n", i, v->mount_point, v->fs_type,
v->device, v->device2);
printf(" %d %s %s %s %s %lld\n", i, v->mount_point, v->fs_type,
v->device, v->device2, v->length);
}
printf("\n");
}
@ -166,7 +197,7 @@ int try_mount(const char* device, const char* mount_point, const char* fs_type,
int is_data_media() {
Volume *data = volume_for_path("/data");
return data != NULL && strcmp(data->fs_type, "auto") == 0 && volume_for_path("/sdcard") == NULL;
return data != NULL && strcmp(data->fs_type, "auto") == 0 || volume_for_path("/sdcard") == NULL;
}
void setup_data_media() {
@ -184,7 +215,7 @@ int ensure_path_mounted_at_mount_point(const char* path, const char* mount_point
if (v == NULL) {
// no /sdcard? let's assume /data/media
if (strstr(path, "/sdcard") == path && is_data_media()) {
LOGW("using /data/media, no /sdcard found.\n");
LOGI("using /data/media, no /sdcard found.\n");
int ret;
if (0 != (ret = ensure_path_mounted("/data")))
return ret;
@ -303,6 +334,11 @@ int format_volume(const char* volume) {
LOGE("unknown volume \"%s\"\n", volume);
return -1;
}
// check to see if /data is being formatted, and if it is /data/media
// Note: the /sdcard check is redundant probably, just being safe.
if (strstr(volume, "/data") == volume && volume_for_path("/sdcard") == NULL && is_data_media()) {
return format_unknown_device(NULL, volume, NULL);
}
if (strcmp(v->fs_type, "ramdisk") == 0) {
// you can't format the ramdisk.
LOGE("can't format_volume \"%s\"", volume);
@ -345,8 +381,7 @@ int format_volume(const char* volume) {
}
if (strcmp(v->fs_type, "ext4") == 0) {
reset_ext4fs_info();
int result = make_ext4fs(v->device, NULL, NULL, 0, 0, 0);
int result = make_ext4fs(v->device, v->length);
if (result != 0) {
LOGE("format_volume: make_extf4fs failed on %s\n", v->device);
return -1;

View File

@ -14,8 +14,6 @@
LOCAL_PATH := $(call my-dir)
ifneq ($(TARGET_SIMULATOR),true)
include $(CLEAR_VARS)
LOCAL_FORCE_STATIC_EXECUTABLE := true
LOCAL_MODULE := add-property-tag
@ -33,5 +31,3 @@ LOCAL_MODULE_TAGS := debug
LOCAL_SRC_FILES := check-lost+found.c
LOCAL_STATIC_LIBRARIES := libcutils libc
include $(BUILD_EXECUTABLE)
endif # !TARGET_SIMULATOR

456
ui.c
View File

@ -14,18 +14,22 @@
* limitations under the License.
*/
#include <errno.h>
#include <fcntl.h>
#include <linux/input.h>
#include <pthread.h>
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/reboot.h>
#include <sys/stat.h>
#include <sys/time.h>
#include <sys/types.h>
#include <time.h>
#include <unistd.h>
#include "common.h"
#include <cutils/android_reboot.h>
#include "minui/minui.h"
#include "recovery_ui.h"
@ -43,20 +47,24 @@ static int gShowBackButton = 0;
#define MENU_MAX_COLS 64
#define MENU_MAX_ROWS 250
#ifndef BOARD_LDPI_RECOVERY
#define CHAR_WIDTH 10
#define CHAR_HEIGHT 18
#else
#define CHAR_WIDTH 7
#define CHAR_HEIGHT 16
#endif
#define MIN_LOG_ROWS 3
#define PROGRESSBAR_INDETERMINATE_STATES 6
#define PROGRESSBAR_INDETERMINATE_FPS 15
#define CHAR_WIDTH BOARD_RECOVERY_CHAR_WIDTH
#define CHAR_HEIGHT BOARD_RECOVERY_CHAR_HEIGHT
#define UI_WAIT_KEY_TIMEOUT_SEC 3600
UIParameters ui_parameters = {
6, // indeterminate progress bar frames
20, // fps
7, // installation icon frames (0 == static image)
13, 190, // installation icon overlay offset
};
static pthread_mutex_t gUpdateMutex = PTHREAD_MUTEX_INITIALIZER;
static gr_surface gBackgroundIcon[NUM_BACKGROUND_ICONS];
static gr_surface gProgressBarIndeterminate[PROGRESSBAR_INDETERMINATE_STATES];
static gr_surface *gInstallationOverlay;
static gr_surface *gProgressBarIndeterminate;
static gr_surface gProgressBarEmpty;
static gr_surface gProgressBarFill;
static int ui_has_initialized = 0;
@ -68,18 +76,13 @@ static const struct { gr_surface* surface; const char *name; } BITMAPS[] = {
{ &gBackgroundIcon[BACKGROUND_ICON_CLOCKWORK], "icon_clockwork" },
{ &gBackgroundIcon[BACKGROUND_ICON_FIRMWARE_INSTALLING], "icon_firmware_install" },
{ &gBackgroundIcon[BACKGROUND_ICON_FIRMWARE_ERROR], "icon_firmware_error" },
{ &gProgressBarIndeterminate[0], "indeterminate1" },
{ &gProgressBarIndeterminate[1], "indeterminate2" },
{ &gProgressBarIndeterminate[2], "indeterminate3" },
{ &gProgressBarIndeterminate[3], "indeterminate4" },
{ &gProgressBarIndeterminate[4], "indeterminate5" },
{ &gProgressBarIndeterminate[5], "indeterminate6" },
{ &gProgressBarEmpty, "progress_empty" },
{ &gProgressBarFill, "progress_fill" },
{ NULL, NULL },
};
static gr_surface gCurrentIcon = NULL;
static int gCurrentIcon = 0;
static int gInstallingFrame = 0;
static enum ProgressBarType {
PROGRESSBAR_TYPE_NONE,
@ -89,7 +92,7 @@ static enum ProgressBarType {
// Progress bar scope of current operation
static float gProgressScopeStart = 0, gProgressScopeSize = 0, gProgress = 0;
static time_t gProgressScopeTime, gProgressScopeDuration;
static double gProgressScopeTime, gProgressScopeDuration;
// Set to 1 when both graphics pages are the same (except for the progress bar)
static int gPagesIdentical = 0;
@ -99,11 +102,13 @@ static char text[MAX_ROWS][MAX_COLS];
static int text_cols = 0, text_rows = 0;
static int text_col = 0, text_row = 0, text_top = 0;
static int show_text = 0;
static int show_text_ever = 0; // has show_text ever been 1?
static char menu[MENU_MAX_ROWS][MENU_MAX_COLS];
static int show_menu = 0;
static int menu_top = 0, menu_items = 0, menu_sel = 0;
static int menu_show_start = 0; // this is line which menu display is starting at
static int max_menu_rows;
// Key event input queue
static pthread_mutex_t key_queue_mutex = PTHREAD_MUTEX_INITIALIZER;
@ -111,20 +116,46 @@ static pthread_cond_t key_queue_cond = PTHREAD_COND_INITIALIZER;
static int key_queue[256], key_queue_len = 0;
static volatile char key_pressed[KEY_MAX + 1];
// Return the current time as a double (including fractions of a second).
static double now() {
struct timeval tv;
gettimeofday(&tv, NULL);
return tv.tv_sec + tv.tv_usec / 1000000.0;
}
// Draw the given frame over the installation overlay animation. The
// background is not cleared or draw with the base icon first; we
// assume that the frame already contains some other frame of the
// animation. Does nothing if no overlay animation is defined.
// Should only be called with gUpdateMutex locked.
static void draw_install_overlay_locked(int frame) {
if (gInstallationOverlay == NULL) return;
gr_surface surface = gInstallationOverlay[frame];
int iconWidth = gr_get_width(surface);
int iconHeight = gr_get_height(surface);
gr_blit(surface, 0, 0, iconWidth, iconHeight,
ui_parameters.install_overlay_offset_x,
ui_parameters.install_overlay_offset_y);
}
// Clear the screen and draw the currently selected background icon (if any).
// Should only be called with gUpdateMutex locked.
static void draw_background_locked(gr_surface icon)
static void draw_background_locked(int icon)
{
gPagesIdentical = 0;
gr_color(0, 0, 0, 255);
gr_fill(0, 0, gr_fb_width(), gr_fb_height());
if (icon) {
int iconWidth = gr_get_width(icon);
int iconHeight = gr_get_height(icon);
gr_surface surface = gBackgroundIcon[icon];
int iconWidth = gr_get_width(surface);
int iconHeight = gr_get_height(surface);
int iconX = (gr_fb_width() - iconWidth) / 2;
int iconY = (gr_fb_height() - iconHeight) / 2;
gr_blit(icon, 0, 0, iconWidth, iconHeight, iconX, iconY);
gr_blit(surface, 0, 0, iconWidth, iconHeight, iconX, iconY);
if (icon == BACKGROUND_ICON_INSTALLING) {
draw_install_overlay_locked(gInstallingFrame);
}
}
}
@ -132,35 +163,39 @@ static void draw_background_locked(gr_surface icon)
// Should only be called with gUpdateMutex locked.
static void draw_progress_locked()
{
if (gProgressBarType == PROGRESSBAR_TYPE_NONE) return;
int iconHeight = gr_get_height(gBackgroundIcon[BACKGROUND_ICON_INSTALLING]);
int width = gr_get_width(gProgressBarEmpty);
int height = gr_get_height(gProgressBarEmpty);
int dx = (gr_fb_width() - width)/2;
int dy = (3*gr_fb_height() + iconHeight - 2*height)/4;
// Erase behind the progress bar (in case this was a progress-only update)
gr_color(0, 0, 0, 255);
gr_fill(dx, dy, width, height);
if (gProgressBarType == PROGRESSBAR_TYPE_NORMAL) {
float progress = gProgressScopeStart + gProgress * gProgressScopeSize;
int pos = (int) (progress * width);
if (pos > 0) {
gr_blit(gProgressBarFill, 0, 0, pos, height, dx, dy);
}
if (pos < width-1) {
gr_blit(gProgressBarEmpty, pos, 0, width-pos, height, dx+pos, dy);
}
if (gCurrentIcon == BACKGROUND_ICON_INSTALLING) {
draw_install_overlay_locked(gInstallingFrame);
}
if (gProgressBarType == PROGRESSBAR_TYPE_INDETERMINATE) {
static int frame = 0;
gr_blit(gProgressBarIndeterminate[frame], 0, 0, width, height, dx, dy);
frame = (frame + 1) % PROGRESSBAR_INDETERMINATE_STATES;
if (gProgressBarType != PROGRESSBAR_TYPE_NONE) {
int iconHeight = gr_get_height(gBackgroundIcon[BACKGROUND_ICON_INSTALLING]);
int width = gr_get_width(gProgressBarEmpty);
int height = gr_get_height(gProgressBarEmpty);
int dx = (gr_fb_width() - width)/2;
int dy = (3*gr_fb_height() + iconHeight - 2*height)/4;
// Erase behind the progress bar (in case this was a progress-only update)
gr_color(0, 0, 0, 255);
gr_fill(dx, dy, width, height);
if (gProgressBarType == PROGRESSBAR_TYPE_NORMAL) {
float progress = gProgressScopeStart + gProgress * gProgressScopeSize;
int pos = (int) (progress * width);
if (pos > 0) {
gr_blit(gProgressBarFill, 0, 0, pos, height, dx, dy);
}
if (pos < width-1) {
gr_blit(gProgressBarEmpty, pos, 0, width-pos, height, dx+pos, dy);
}
}
if (gProgressBarType == PROGRESSBAR_TYPE_INDETERMINATE) {
static int frame = 0;
gr_blit(gProgressBarIndeterminate[frame], 0, 0, width, height, dx, dy);
frame = (frame + 1) % ui_parameters.indeterminate_frames;
}
}
}
@ -187,8 +222,10 @@ static void draw_screen_locked(void)
gr_color(0, 0, 0, 160);
gr_fill(0, 0, gr_fb_width(), gr_fb_height());
int total_rows = gr_fb_height() / CHAR_HEIGHT;
int i = 0;
int j = 0;
int offset = 0; // offset of separating bar under menus
int row = 0; // current row that we are drawing on
if (show_menu) {
gr_color(MENU_TEXT_COLOR);
@ -201,8 +238,8 @@ static void draw_screen_locked(void)
row++;
}
if (menu_items - menu_show_start + menu_top >= MAX_ROWS)
j = MAX_ROWS - menu_top;
if (menu_items - menu_show_start + menu_top >= max_menu_rows)
j = max_menu_rows - menu_top;
else
j = menu_items - menu_show_start;
@ -217,14 +254,29 @@ static void draw_screen_locked(void)
draw_text_line(i - menu_show_start, menu[i]);
}
row++;
if (row >= max_menu_rows)
break;
}
gr_fill(0, row*CHAR_HEIGHT+CHAR_HEIGHT/2-1,
gr_fb_width(), row*CHAR_HEIGHT+CHAR_HEIGHT/2+1);
if (menu_items <= max_menu_rows)
offset = 1;
gr_fill(0, (row-offset)*CHAR_HEIGHT+CHAR_HEIGHT/2-1,
gr_fb_width(), (row-offset)*CHAR_HEIGHT+CHAR_HEIGHT/2+1);
}
gr_color(NORMAL_TEXT_COLOR);
for (; row < text_rows; ++row) {
draw_text_line(row, text[(row+text_top) % text_rows]);
int cur_row = text_row;
int available_rows = total_rows - row - 1;
int start_row = row + 1;
if (available_rows < MAX_ROWS)
cur_row = (cur_row + (MAX_ROWS - available_rows)) % MAX_ROWS;
else
start_row = total_rows - MAX_ROWS;
int r;
for (r = 0; r < (available_rows < MAX_ROWS ? available_rows : MAX_ROWS); r++) {
draw_text_line(start_row + r, text[(cur_row + r) % MAX_ROWS]);
}
}
}
@ -247,7 +299,7 @@ static void update_progress_locked(void)
draw_screen_locked(); // Must redraw the whole screen
gPagesIdentical = 1;
} else {
draw_progress_locked(); // Draw only the progress bar
draw_progress_locked(); // Draw only the progress bar and overlays
}
gr_flip();
}
@ -255,97 +307,130 @@ static void update_progress_locked(void)
// Keeps the progress bar updated, even when the process is otherwise busy.
static void *progress_thread(void *cookie)
{
double interval = 1.0 / ui_parameters.update_fps;
for (;;) {
usleep(1000000 / PROGRESSBAR_INDETERMINATE_FPS);
double start = now();
pthread_mutex_lock(&gUpdateMutex);
int redraw = 0;
// update the installation animation, if active
// skip this if we have a text overlay (too expensive to update)
if (gCurrentIcon == BACKGROUND_ICON_INSTALLING &&
ui_parameters.installing_frames > 0 &&
!show_text) {
gInstallingFrame =
(gInstallingFrame + 1) % ui_parameters.installing_frames;
redraw = 1;
}
// update the progress bar animation, if active
// skip this if we have a text overlay (too expensive to update)
if (gProgressBarType == PROGRESSBAR_TYPE_INDETERMINATE && !show_text) {
update_progress_locked();
redraw = 1;
}
// move the progress bar forward on timed intervals, if configured
int duration = gProgressScopeDuration;
if (gProgressBarType == PROGRESSBAR_TYPE_NORMAL && duration > 0) {
int elapsed = time(NULL) - gProgressScopeTime;
double elapsed = now() - gProgressScopeTime;
float progress = 1.0 * elapsed / duration;
if (progress > 1.0) progress = 1.0;
if (progress > gProgress) {
gProgress = progress;
update_progress_locked();
redraw = 1;
}
}
if (redraw) update_progress_locked();
pthread_mutex_unlock(&gUpdateMutex);
double end = now();
// minimum of 20ms delay between frames
double delay = interval - (end-start);
if (delay < 0.02) delay = 0.02;
usleep((long)(delay * 1000000));
}
return NULL;
}
static int rel_sum = 0;
static int input_callback(int fd, short revents, void *data)
{
struct input_event ev;
int ret;
int fake_key = 0;
ret = ev_get_input(fd, revents, &ev);
if (ret)
return -1;
if (ev.type == EV_SYN) {
return 0;
} else if (ev.type == EV_REL) {
if (ev.code == REL_Y) {
// accumulate the up or down motion reported by
// the trackball. When it exceeds a threshold
// (positive or negative), fake an up/down
// key event.
rel_sum += ev.value;
if (rel_sum > 3) {
fake_key = 1;
ev.type = EV_KEY;
ev.code = KEY_DOWN;
ev.value = 1;
rel_sum = 0;
} else if (rel_sum < -3) {
fake_key = 1;
ev.type = EV_KEY;
ev.code = KEY_UP;
ev.value = 1;
rel_sum = 0;
}
}
} else {
rel_sum = 0;
}
if (ev.type != EV_KEY || ev.code > KEY_MAX)
return 0;
pthread_mutex_lock(&key_queue_mutex);
if (!fake_key) {
// our "fake" keys only report a key-down event (no
// key-up), so don't record them in the key_pressed
// table.
key_pressed[ev.code] = ev.value;
}
const int queue_max = sizeof(key_queue) / sizeof(key_queue[0]);
if (ev.value > 0 && key_queue_len < queue_max) {
key_queue[key_queue_len++] = ev.code;
pthread_cond_signal(&key_queue_cond);
}
pthread_mutex_unlock(&key_queue_mutex);
if (ev.value > 0 && device_toggle_display(key_pressed, ev.code)) {
pthread_mutex_lock(&gUpdateMutex);
show_text = !show_text;
if (show_text) show_text_ever = 1;
update_screen_locked();
pthread_mutex_unlock(&gUpdateMutex);
}
if (ev.value > 0 && device_reboot_now(key_pressed, ev.code)) {
android_reboot(ANDROID_RB_RESTART, 0, 0);
}
return 0;
}
// Reads input events, handles special hot keys, and adds to the key queue.
static void *input_thread(void *cookie)
{
int rel_sum = 0;
int fake_key = 0;
for (;;) {
// wait for the next key event
struct input_event ev;
do {
ev_get(&ev, 0);
if (ev.type == EV_SYN) {
continue;
} else if (ev.type == EV_REL) {
if (ev.code == REL_Y) {
// accumulate the up or down motion reported by
// the trackball. When it exceeds a threshold
// (positive or negative), fake an up/down
// key event.
rel_sum += ev.value;
if (rel_sum > 3) {
fake_key = 1;
ev.type = EV_KEY;
ev.code = KEY_DOWN;
ev.value = 1;
rel_sum = 0;
} else if (rel_sum < -3) {
fake_key = 1;
ev.type = EV_KEY;
ev.code = KEY_UP;
ev.value = 1;
rel_sum = 0;
}
}
} else {
rel_sum = 0;
}
} while (ev.type != EV_KEY || ev.code > KEY_MAX);
pthread_mutex_lock(&key_queue_mutex);
if (!fake_key) {
// our "fake" keys only report a key-down event (no
// key-up), so don't record them in the key_pressed
// table.
key_pressed[ev.code] = ev.value;
}
fake_key = 0;
const int queue_max = sizeof(key_queue) / sizeof(key_queue[0]);
if (ev.value > 0 && key_queue_len < queue_max) {
key_queue[key_queue_len++] = ev.code;
pthread_cond_signal(&key_queue_cond);
}
pthread_mutex_unlock(&key_queue_mutex);
if (ev.value > 0 && device_toggle_display(key_pressed, ev.code)) {
pthread_mutex_lock(&gUpdateMutex);
show_text = !show_text;
update_screen_locked();
pthread_mutex_unlock(&gUpdateMutex);
}
if (ev.value > 0 && device_reboot_now(key_pressed, ev.code)) {
reboot(RB_AUTOBOOT);
}
if (!ev_wait(-1))
ev_dispatch();
}
return NULL;
}
@ -354,10 +439,13 @@ void ui_init(void)
{
ui_has_initialized = 1;
gr_init();
ev_init();
ev_init(input_callback, NULL);
text_col = text_row = 0;
text_rows = gr_fb_height() / CHAR_HEIGHT;
max_menu_rows = text_rows - MIN_LOG_ROWS;
if (max_menu_rows > MENU_MAX_ROWS)
max_menu_rows = MENU_MAX_ROWS;
if (text_rows > MAX_ROWS) text_rows = MAX_ROWS;
text_top = 1;
@ -368,15 +456,49 @@ void ui_init(void)
for (i = 0; BITMAPS[i].name != NULL; ++i) {
int result = res_create_surface(BITMAPS[i].name, BITMAPS[i].surface);
if (result < 0) {
if (result == -2) {
LOGI("Bitmap %s missing header\n", BITMAPS[i].name);
} else {
LOGE("Missing bitmap %s\n(Code %d)\n", BITMAPS[i].name, result);
}
*BITMAPS[i].surface = NULL;
LOGE("Missing bitmap %s\n(Code %d)\n", BITMAPS[i].name, result);
}
}
gProgressBarIndeterminate = malloc(ui_parameters.indeterminate_frames *
sizeof(gr_surface));
for (i = 0; i < ui_parameters.indeterminate_frames; ++i) {
char filename[40];
// "indeterminate01.png", "indeterminate02.png", ...
sprintf(filename, "indeterminate%02d", i+1);
int result = res_create_surface(filename, gProgressBarIndeterminate+i);
if (result < 0) {
LOGE("Missing bitmap %s\n(Code %d)\n", filename, result);
}
}
if (ui_parameters.installing_frames > 0) {
gInstallationOverlay = malloc(ui_parameters.installing_frames *
sizeof(gr_surface));
for (i = 0; i < ui_parameters.installing_frames; ++i) {
char filename[40];
// "icon_installing_overlay01.png",
// "icon_installing_overlay02.png", ...
sprintf(filename, "icon_installing_overlay%02d", i+1);
int result = res_create_surface(filename, gInstallationOverlay+i);
if (result < 0) {
LOGE("Missing bitmap %s\n(Code %d)\n", filename, result);
}
}
// Adjust the offset to account for the positioning of the
// base image on the screen.
if (gBackgroundIcon[BACKGROUND_ICON_INSTALLING] != NULL) {
gr_surface bg = gBackgroundIcon[BACKGROUND_ICON_INSTALLING];
ui_parameters.install_overlay_offset_x +=
(gr_fb_width() - gr_get_width(bg)) / 2;
ui_parameters.install_overlay_offset_y +=
(gr_fb_height() - gr_get_height(bg)) / 2;
}
} else {
gInstallationOverlay = NULL;
}
pthread_t t;
pthread_create(&t, NULL, progress_thread, NULL);
pthread_create(&t, NULL, input_thread, NULL);
@ -402,7 +524,7 @@ char *ui_copy_image(int icon, int *width, int *height, int *bpp) {
void ui_set_background(int icon)
{
pthread_mutex_lock(&gUpdateMutex);
gCurrentIcon = gBackgroundIcon[icon];
gCurrentIcon = icon;
update_screen_locked();
pthread_mutex_unlock(&gUpdateMutex);
}
@ -423,7 +545,7 @@ void ui_show_progress(float portion, int seconds)
gProgressBarType = PROGRESSBAR_TYPE_NORMAL;
gProgressScopeStart += gProgressScopeSize;
gProgressScopeSize = portion;
gProgressScopeTime = time(NULL);
gProgressScopeTime = now();
gProgressScopeDuration = seconds;
gProgress = 0;
update_progress_locked();
@ -533,14 +655,17 @@ int ui_start_menu(char** headers, char** items, int initial_selection) {
for (; i < MENU_MAX_ROWS; ++i) {
if (items[i-menu_top] == NULL) break;
strcpy(menu[i], MENU_ITEM_HEADER);
strncpy(menu[i] + MENU_ITEM_HEADER_LENGTH, items[i-menu_top], text_cols-1 - MENU_ITEM_HEADER_LENGTH);
menu[i][text_cols-1] = '\0';
strncpy(menu[i] + MENU_ITEM_HEADER_LENGTH, items[i-menu_top], MENU_MAX_COLS - 1 - MENU_ITEM_HEADER_LENGTH);
menu[i][MENU_MAX_COLS-1] = '\0';
}
if (gShowBackButton) {
if (gShowBackButton && ui_menu_level > 0) {
strcpy(menu[i], " - +++++Go Back+++++");
++i;
}
strcpy(menu[i], " ");
++i;
menu_items = i - menu_top;
show_menu = 1;
@ -548,7 +673,7 @@ int ui_start_menu(char** headers, char** items, int initial_selection) {
update_screen_locked();
}
pthread_mutex_unlock(&gUpdateMutex);
if (gShowBackButton) {
if (gShowBackButton && ui_menu_level > 0) {
return menu_items - 1;
}
return menu_items;
@ -561,16 +686,16 @@ int ui_menu_select(int sel) {
old_sel = menu_sel;
menu_sel = sel;
if (menu_sel < 0) menu_sel = menu_items + menu_sel;
if (menu_sel >= menu_items) menu_sel = menu_sel - menu_items;
if (menu_sel < 0) menu_sel = menu_items-1 + menu_sel;
if (menu_sel >= menu_items-1) menu_sel = menu_sel - menu_items+1;
if (menu_sel < menu_show_start && menu_show_start > 0) {
menu_show_start = menu_sel;
}
if (menu_sel - menu_show_start + menu_top >= text_rows) {
menu_show_start = menu_sel + menu_top - text_rows + 1;
if (menu_sel - menu_show_start + menu_top >= max_menu_rows) {
menu_show_start = menu_sel + menu_top - max_menu_rows + 1;
}
sel = menu_sel;
@ -599,23 +724,68 @@ int ui_text_visible()
return visible;
}
int ui_text_ever_visible()
{
pthread_mutex_lock(&gUpdateMutex);
int ever_visible = show_text_ever;
pthread_mutex_unlock(&gUpdateMutex);
return ever_visible;
}
void ui_show_text(int visible)
{
pthread_mutex_lock(&gUpdateMutex);
show_text = visible;
if (show_text) show_text_ever = 1;
update_screen_locked();
pthread_mutex_unlock(&gUpdateMutex);
}
// Return true if USB is connected.
static int usb_connected() {
int fd = open("/sys/class/android_usb/android0/state", O_RDONLY);
if (fd < 0) {
printf("failed to open /sys/class/android_usb/android0/state: %s\n",
strerror(errno));
return 0;
}
char buf;
/* USB is connected if android_usb state is CONNECTED or CONFIGURED */
int connected = (read(fd, &buf, 1) == 1) && (buf == 'C');
if (close(fd) < 0) {
printf("failed to close /sys/class/android_usb/android0/state: %s\n",
strerror(errno));
}
return connected;
}
int ui_wait_key()
{
pthread_mutex_lock(&key_queue_mutex);
while (key_queue_len == 0) {
pthread_cond_wait(&key_queue_cond, &key_queue_mutex);
}
int key = key_queue[0];
memcpy(&key_queue[0], &key_queue[1], sizeof(int) * --key_queue_len);
// Time out after UI_WAIT_KEY_TIMEOUT_SEC, unless a USB cable is
// plugged in.
do {
struct timeval now;
struct timespec timeout;
gettimeofday(&now, NULL);
timeout.tv_sec = now.tv_sec;
timeout.tv_nsec = now.tv_usec * 1000;
timeout.tv_sec += UI_WAIT_KEY_TIMEOUT_SEC;
int rc = 0;
while (key_queue_len == 0 && rc != ETIMEDOUT) {
rc = pthread_cond_timedwait(&key_queue_cond, &key_queue_mutex,
&timeout);
}
} while (usb_connected() && key_queue_len == 0);
int key = -1;
if (key_queue_len > 0) {
key = key_queue[0];
memcpy(&key_queue[0], &key_queue[1], sizeof(int) * --key_queue_len);
}
pthread_mutex_unlock(&key_queue_mutex);
return key;
}

View File

@ -30,6 +30,7 @@ LOCAL_STATIC_LIBRARIES += libflashutils libmtdutils libmmcutils libbmlutils
LOCAL_STATIC_LIBRARIES += $(TARGET_RECOVERY_UPDATER_LIBS) $(TARGET_RECOVERY_UPDATER_EXTRA_LIBS)
LOCAL_STATIC_LIBRARIES += libapplypatch libedify libmtdutils libminzip libz
LOCAL_STATIC_LIBRARIES += libmincrypt libbz
LOCAL_STATIC_LIBRARIES += libminelf libcrecovery
LOCAL_STATIC_LIBRARIES += libcutils libstdc++ libc
LOCAL_C_INCLUDES += $(LOCAL_PATH)/..
@ -60,9 +61,9 @@ $(inc) : libs := $(TARGET_RECOVERY_UPDATER_LIBS)
$(inc) : $(inc).list
$(hide) mkdir -p $(dir $@)
$(hide) echo "" > $@
$(hide) $(foreach lib,$(libs),echo "extern void Register_$(lib)(void);" >> $@)
$(hide) $(foreach lib,$(libs),echo "extern void Register_$(lib)(void);" >> $@;)
$(hide) echo "void RegisterDeviceExtensions() {" >> $@
$(hide) $(foreach lib,$(libs),echo " Register_$(lib)();" >> $@)
$(hide) $(foreach lib,$(libs),echo " Register_$(lib)();" >> $@;)
$(hide) echo "}" >> $@
$(call intermediates-dir-for,EXECUTABLES,updater)/updater.o : $(inc)
@ -73,9 +74,3 @@ LOCAL_MODULE := updater
LOCAL_FORCE_STATIC_EXECUTABLE := true
include $(BUILD_EXECUTABLE)
file := $(PRODUCT_OUT)/utilities/update-binary
ALL_PREBUILT += $(file)
$(file) : $(TARGET_OUT)/bin/updater | $(ACP)
$(transform-prebuilt-to-target)

View File

@ -25,12 +25,15 @@
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>
#include <fcntl.h>
#include <time.h>
#include "cutils/misc.h"
#include "cutils/properties.h"
#include "edify/expr.h"
#include "mincrypt/sha.h"
#include "minzip/DirUtil.h"
#include "minelf/Retouch.h"
#include "mounts.h"
#include "mtdutils/mtdutils.h"
#include "updater.h"
@ -176,19 +179,23 @@ done:
}
// format(fs_type, partition_type, location)
// format(fs_type, partition_type, location, fs_size)
//
// fs_type="yaffs2" partition_type="MTD" location=partition
// fs_type="ext4" partition_type="EMMC" location=device
// fs_type="yaffs2" partition_type="MTD" location=partition fs_size=<bytes>
// fs_type="ext4" partition_type="EMMC" location=device fs_size=<bytes>
// if fs_size == 0, then make_ext4fs uses the entire partition.
// if fs_size > 0, that is the size to use
// if fs_size < 0, then reserve that many bytes at the end of the partition
Value* FormatFn(const char* name, State* state, int argc, Expr* argv[]) {
char* result = NULL;
if (argc != 3) {
return ErrorAbort(state, "%s() expects 3 args, got %d", name, argc);
if (argc != 4) {
return ErrorAbort(state, "%s() expects 4 args, got %d", name, argc);
}
char* fs_type;
char* partition_type;
char* location;
if (ReadArgs(state, argv, 3, &fs_type, &partition_type, &location) < 0) {
char* fs_size;
if (ReadArgs(state, argv, 4, &fs_type, &partition_type, &location, &fs_size) < 0) {
return NULL;
}
@ -235,8 +242,7 @@ Value* FormatFn(const char* name, State* state, int argc, Expr* argv[]) {
result = location;
#ifdef USE_EXT4
} else if (strcmp(fs_type, "ext4") == 0) {
reset_ext4fs_info();
int status = make_ext4fs(location, NULL, NULL, 0, 0, 0);
int status = make_ext4fs(location, atoll(fs_size));
if (status != 0) {
fprintf(stderr, "%s: make_ext4fs failed (%d) on %s",
name, status, location);
@ -449,6 +455,119 @@ Value* PackageExtractFileFn(const char* name, State* state,
}
// retouch_binaries(lib1, lib2, ...)
Value* RetouchBinariesFn(const char* name, State* state,
int argc, Expr* argv[]) {
UpdaterInfo* ui = (UpdaterInfo*)(state->cookie);
char **retouch_entries = ReadVarArgs(state, argc, argv);
if (retouch_entries == NULL) {
return StringValue(strdup("t"));
}
// some randomness from the clock
int32_t override_base;
bool override_set = false;
int32_t random_base = time(NULL) % 1024;
// some more randomness from /dev/random
FILE *f_random = fopen("/dev/random", "rb");
uint16_t random_bits = 0;
if (f_random != NULL) {
fread(&random_bits, 2, 1, f_random);
random_bits = random_bits % 1024;
fclose(f_random);
}
random_base = (random_base + random_bits) % 1024;
// make sure we never randomize to zero; this let's us look at a file
// and know for sure whether it has been processed; important in the
// crash recovery process
if (random_base == 0) random_base = 1;
// make sure our randomization is page-aligned
random_base *= -0x1000;
override_base = random_base;
int i = 0;
bool success = true;
while (i < (argc - 1)) {
success = success && retouch_one_library(retouch_entries[i],
retouch_entries[i+1],
random_base,
override_set ?
NULL :
&override_base);
if (!success)
ErrorAbort(state, "Failed to retouch '%s'.", retouch_entries[i]);
free(retouch_entries[i]);
free(retouch_entries[i+1]);
i += 2;
if (success && override_base != 0) {
random_base = override_base;
override_set = true;
}
}
if (i < argc) {
free(retouch_entries[i]);
success = false;
}
free(retouch_entries);
if (!success) {
Value* v = malloc(sizeof(Value));
v->type = VAL_STRING;
v->data = NULL;
v->size = -1;
return v;
}
return StringValue(strdup("t"));
}
// undo_retouch_binaries(lib1, lib2, ...)
Value* UndoRetouchBinariesFn(const char* name, State* state,
int argc, Expr* argv[]) {
UpdaterInfo* ui = (UpdaterInfo*)(state->cookie);
char **retouch_entries = ReadVarArgs(state, argc, argv);
if (retouch_entries == NULL) {
return StringValue(strdup("t"));
}
int i = 0;
bool success = true;
int32_t override_base;
while (i < (argc-1)) {
success = success && retouch_one_library(retouch_entries[i],
retouch_entries[i+1],
0 /* undo => offset==0 */,
NULL);
if (!success)
ErrorAbort(state, "Failed to unretouch '%s'.",
retouch_entries[i]);
free(retouch_entries[i]);
free(retouch_entries[i+1]);
i += 2;
}
if (i < argc) {
free(retouch_entries[i]);
success = false;
}
free(retouch_entries);
if (!success) {
Value* v = malloc(sizeof(Value));
v->type = VAL_STRING;
v->data = NULL;
v->size = -1;
return v;
}
return StringValue(strdup("t"));
}
// symlink target src1 src2 ...
// unlinks any previously existing src1, src2, etc before creating symlinks.
Value* SymlinkFn(const char* name, State* state, int argc, Expr* argv[]) {
@ -681,33 +800,41 @@ static bool write_raw_image_cb(const unsigned char* data,
return false;
}
// write_raw_image(file, partition)
// write_raw_image(filename_or_blob, partition)
Value* WriteRawImageFn(const char* name, State* state, int argc, Expr* argv[]) {
char* result = NULL;
char* partition;
char* filename;
if (ReadArgs(state, argv, 2, &filename, &partition) < 0) {
Value* partition_value;
Value* contents;
if (ReadValueArgs(state, argv, 2, &contents, &partition_value) < 0) {
return NULL;
}
if (partition_value->type != VAL_STRING) {
ErrorAbort(state, "partition argument to %s must be string", name);
goto done;
}
char* partition = partition_value->data;
if (strlen(partition) == 0) {
ErrorAbort(state, "partition argument to %s can't be empty", name);
goto done;
}
if (strlen(filename) == 0) {
if (contents->type == VAL_STRING && strlen((char*) contents->data) == 0) {
ErrorAbort(state, "file argument to %s can't be empty", name);
goto done;
}
char* filename = contents->data;
if (0 == restore_raw_partition(NULL, partition, filename))
result = strdup(partition);
else
else {
result = strdup("");
goto done;
}
done:
if (result != partition) free(partition);
free(filename);
if (result != partition) FreeValue(partition_value);
FreeValue(contents);
return StringValue(result);
}
@ -980,7 +1107,7 @@ Value* Sha1CheckFn(const char* name, State* state, int argc, Expr* argv[]) {
return args[i];
}
// Read a local file and return its contents (the char* returned
// Read a local file and return its contents (the Value* returned
// is actually a FileContents*).
Value* ReadFileFn(const char* name, State* state, int argc, Expr* argv[]) {
if (argc != 1) {
@ -993,7 +1120,7 @@ Value* ReadFileFn(const char* name, State* state, int argc, Expr* argv[]) {
v->type = VAL_BLOB;
FileContents fc;
if (LoadFileContents(filename, &fc) != 0) {
if (LoadFileContents(filename, &fc, RETOUCH_DONT_MASK) != 0) {
ErrorAbort(state, "%s() loading \"%s\" failed: %s",
name, filename, strerror(errno));
free(filename);
@ -1020,6 +1147,8 @@ void RegisterInstallFunctions() {
RegisterFunction("delete_recursive", DeleteFn);
RegisterFunction("package_extract_dir", PackageExtractDirFn);
RegisterFunction("package_extract_file", PackageExtractFileFn);
RegisterFunction("retouch_binaries", RetouchBinariesFn);
RegisterFunction("undo_retouch_binaries", UndoRetouchBinariesFn);
RegisterFunction("symlink", SymlinkFn);
RegisterFunction("set_perm", SetPermFn);
RegisterFunction("set_perm_recursive", SetPermFn);

View File

@ -1,11 +1,8 @@
LOCAL_PATH := $(call my-dir)
ifndef BOARD_HAS_SMALL_RECOVERY
include $(CLEAR_VARS)
LOCAL_MODULE := fix_permissions
LOCAL_MODULE_TAGS := eng
LOCAL_MODULE_TAGS := optional
LOCAL_MODULE_CLASS := RECOVERY_EXECUTABLES
LOCAL_MODULE_PATH := $(TARGET_RECOVERY_ROOT_OUT)/sbin
LOCAL_SRC_FILES := $(LOCAL_MODULE)
@ -13,7 +10,7 @@ include $(BUILD_PREBUILT)
include $(CLEAR_VARS)
LOCAL_MODULE := parted
LOCAL_MODULE_TAGS := eng
LOCAL_MODULE_TAGS := optional
LOCAL_MODULE_CLASS := RECOVERY_EXECUTABLES
LOCAL_MODULE_PATH := $(TARGET_RECOVERY_ROOT_OUT)/sbin
LOCAL_SRC_FILES := $(LOCAL_MODULE)
@ -21,52 +18,53 @@ include $(BUILD_PREBUILT)
include $(CLEAR_VARS)
LOCAL_MODULE := sdparted
LOCAL_MODULE_TAGS := eng
LOCAL_MODULE_TAGS := optional
LOCAL_MODULE_CLASS := RECOVERY_EXECUTABLES
LOCAL_MODULE_PATH := $(TARGET_RECOVERY_ROOT_OUT)/sbin
LOCAL_SRC_FILES := $(LOCAL_MODULE)
include $(BUILD_PREBUILT)
endif
# include $(CLEAR_VARS)
# LOCAL_MODULE := e2fsck
# LOCAL_MODULE_TAGS := optional
# LOCAL_MODULE_CLASS := RECOVERY_EXECUTABLES
# LOCAL_MODULE_PATH := $(TARGET_RECOVERY_ROOT_OUT)/sbin
# LOCAL_SRC_FILES := $(LOCAL_MODULE)
# include $(BUILD_PREBUILT)
include $(CLEAR_VARS)
LOCAL_MODULE := e2fsck
LOCAL_MODULE_TAGS := eng
LOCAL_MODULE_CLASS := RECOVERY_EXECUTABLES
LOCAL_MODULE_PATH := $(TARGET_RECOVERY_ROOT_OUT)/sbin
LOCAL_SRC_FILES := $(LOCAL_MODULE)
include $(BUILD_PREBUILT)
# include $(CLEAR_VARS)
# LOCAL_MODULE := tune2fs
# LOCAL_MODULE_TAGS := optional
# LOCAL_MODULE_CLASS := RECOVERY_EXECUTABLES
# LOCAL_MODULE_PATH := $(TARGET_RECOVERY_ROOT_OUT)/sbin
# LOCAL_SRC_FILES := $(LOCAL_MODULE)
# include $(BUILD_PREBUILT)
# include $(CLEAR_VARS)
# LOCAL_MODULE := mke2fs
# LOCAL_MODULE_TAGS := optional
# LOCAL_MODULE_CLASS := RECOVERY_EXECUTABLES
# LOCAL_MODULE_PATH := $(TARGET_RECOVERY_ROOT_OUT)/sbin
# ifeq ($(BOARD_MKE2FS),)
# LOCAL_SRC_FILES := $(LOCAL_MODULE)
# else
# LOCAL_SRC_FILES := ../../../$(BOARD_MKE2FS)
# endif
# include $(BUILD_PREBUILT)
include $(CLEAR_VARS)
LOCAL_MODULE := tune2fs
LOCAL_MODULE_TAGS := eng
LOCAL_MODULE_CLASS := RECOVERY_EXECUTABLES
LOCAL_MODULE_PATH := $(TARGET_RECOVERY_ROOT_OUT)/sbin
LOCAL_SRC_FILES := $(LOCAL_MODULE)
include $(BUILD_PREBUILT)
ifeq ($(BOARD_HAS_LARGE_FILESYSTEM),true)
include $(CLEAR_VARS)
LOCAL_MODULE := mke2fs
LOCAL_MODULE_TAGS := eng
LOCAL_MODULE_CLASS := RECOVERY_EXECUTABLES
LOCAL_MODULE_PATH := $(TARGET_RECOVERY_ROOT_OUT)/sbin
ifeq ($(BOARD_MKE2FS),)
LOCAL_SRC_FILES := $(LOCAL_MODULE)
ifneq ($(TARGET_RECOVERY_FSTAB),)
BOARD_RECOVERY_RFS_CHECK := $(shell grep rfs $(TARGET_RECOVERY_FSTAB))
else
LOCAL_SRC_FILES := ../../../$(BOARD_MKE2FS)
endif
include $(BUILD_PREBUILT)
BOARD_RECOVERY_RFS_CHECK := $(shell grep rfs $(TARGET_DEVICE_DIR)/recovery.fstab)
endif
BOARD_RECOVERY_RFS_CHECK := $(shell grep rfs $(TARGET_DEVICE_DIR)/recovery.fstab)
ifneq ($(BOARD_RECOVERY_RFS_CHECK),)
include $(CLEAR_VARS)
LOCAL_MODULE := fat.format
LOCAL_MODULE_TAGS := eng
LOCAL_MODULE_TAGS := optional
LOCAL_MODULE_CLASS := RECOVERY_EXECUTABLES
LOCAL_MODULE_PATH := $(TARGET_RECOVERY_ROOT_OUT)/sbin
LOCAL_SRC_FILES := $(LOCAL_MODULE)
include $(BUILD_PREBUILT)
endif

View File

@ -173,7 +173,7 @@ int verify_file(const char* path, const RSAPublicKey *pKeys, unsigned int numKey
// the signing tool appends after the signature itself.
if (RSA_verify(pKeys+i, eocd + eocd_size - 6 - RSANUMBYTES,
RSANUMBYTES, sha1)) {
LOGI("whole-file signature verified\n");
LOGI("whole-file signature verified against key %d\n", i);
free(eocd);
return VERIFY_SUCCESS;
}