summaryrefslogtreecommitdiff
path: root/core/java/android/os/RecoverySystem.java
diff options
context:
space:
mode:
authorTao Bao <tbao@google.com>2016-09-27 11:15:42 -0700
committerTao Bao <tbao@google.com>2016-09-29 16:07:19 -0700
commit794c8b0b3fe16051843c22232d58d6b184dde49b (patch)
tree9165917ea4d7b2d036e4731d47a16dfefb42ff84 /core/java/android/os/RecoverySystem.java
parentf0aa998233c308fcc945493135448dfe51fb39b7 (diff)
Handle the race condition when calling uncrypt services.
We call uncrypt services to setup / clear bootloader control block (BCB) for scheduling tasks under recovery (applying OTAs, performing FDR). However, we cannot start multiple requests simultaneously. Because they all use the same socket (/dev/socket/uncrypt) for communication and init deletes the socket on service exits. This CL fixes the issue by a) adding synchronized blocks for the service requests; b) checking the availability of the socket before initiating a new one. Note that adding synchronized blocks to RecoverySystem doesn't help, because the calls could be made from different processes (e.g. priv-app, system_server). Bug: 31526152 Test: FDR works while a priv-app keeps calling clear BCB. Change-Id: I95308989e849a9c98a9503ac509f2bc51ed3de19
Diffstat (limited to 'core/java/android/os/RecoverySystem.java')
-rw-r--r--core/java/android/os/RecoverySystem.java41
1 files changed, 23 insertions, 18 deletions
diff --git a/core/java/android/os/RecoverySystem.java b/core/java/android/os/RecoverySystem.java
index 028e30ab93f0..df7df64de813 100644
--- a/core/java/android/os/RecoverySystem.java
+++ b/core/java/android/os/RecoverySystem.java
@@ -663,28 +663,22 @@ public class RecoverySystem {
* @throws IOException if something goes wrong.
*/
private static void bootCommand(Context context, String... args) throws IOException {
- synchronized (sRequestLock) {
- LOG_FILE.delete();
+ LOG_FILE.delete();
- StringBuilder command = new StringBuilder();
- for (String arg : args) {
- if (!TextUtils.isEmpty(arg)) {
- command.append(arg);
- command.append("\n");
- }
+ StringBuilder command = new StringBuilder();
+ for (String arg : args) {
+ if (!TextUtils.isEmpty(arg)) {
+ command.append(arg);
+ command.append("\n");
}
+ }
- // Write the command into BCB (bootloader control block).
- RecoverySystem rs = (RecoverySystem) context.getSystemService(
- Context.RECOVERY_SERVICE);
- rs.setupBcb(command.toString());
-
- // Having set up the BCB, go ahead and reboot.
- PowerManager pm = (PowerManager) context.getSystemService(Context.POWER_SERVICE);
- pm.reboot(PowerManager.REBOOT_RECOVERY);
+ // Write the command into BCB (bootloader control block) and boot from
+ // there. Will not return unless failed.
+ RecoverySystem rs = (RecoverySystem) context.getSystemService(Context.RECOVERY_SERVICE);
+ rs.rebootRecoveryWithCommand(command.toString());
- throw new IOException("Reboot failed (no permissions?)");
- }
+ throw new IOException("Reboot failed (no permissions?)");
}
// Read last_install; then report time (in seconds) and I/O (in MiB) for
@@ -879,6 +873,17 @@ public class RecoverySystem {
}
/**
+ * Talks to RecoverySystemService via Binder to set up the BCB command and
+ * reboot into recovery accordingly.
+ */
+ private void rebootRecoveryWithCommand(String command) {
+ try {
+ mService.rebootRecoveryWithCommand(command);
+ } catch (RemoteException ignored) {
+ }
+ }
+
+ /**
* Internally, recovery treats each line of the command file as a separate
* argv, so we only need to protect against newlines and nulls.
*/