Bumping gaia.json for 3 gaia revision(s) a=gaia-bump
[gecko.git] / b2g / components / RecoveryService.js
blob313efed46444dd15f2780f85a01f73ebe9c00988
1 /* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
2 /* vim: set shiftwidth=2 tabstop=2 autoindent cindent expandtab: */
3 /* This Source Code Form is subject to the terms of the Mozilla Public
4  * License, v. 2.0. If a copy of the MPL was not distributed with this file,
5  * You can obtain one at http://mozilla.org/MPL/2.0/. */
6 "use strict";
8 const {classes: Cc, interfaces: Ci, utils: Cu, results: Cr} = Components;
10 Cu.import("resource://gre/modules/XPCOMUtils.jsm");
11 Cu.import("resource://gre/modules/ctypes.jsm");
13 const RECOVERYSERVICE_CID = Components.ID("{b3caca5d-0bb0-48c6-912b-6be6cbf08832}");
14 const RECOVERYSERVICE_CONTRACTID = "@mozilla.org/recovery-service;1";
16 function log(msg) {
17   dump("-*- RecoveryService: " + msg + "\n");
20 #ifdef MOZ_WIDGET_GONK
21 let librecovery = (function() {
22   let library;
23   try {
24     library = ctypes.open("librecovery.so");
25   } catch (e) {
26     log("Unable to open librecovery.so");
27     throw Cr.NS_ERROR_FAILURE;
28   }
29   let FotaUpdateStatus = new ctypes.StructType("FotaUpdateStatus", [
30                                                 { result: ctypes.int },
31                                                 { updatePath: ctypes.char.ptr }
32                                               ]);
34   return {
35     factoryReset:        library.declare("factoryReset",
36                                          ctypes.default_abi,
37                                          ctypes.int),
38     installFotaUpdate:   library.declare("installFotaUpdate",
39                                          ctypes.default_abi,
40                                          ctypes.int,
41                                          ctypes.char.ptr,
42                                          ctypes.int),
44     FotaUpdateStatus:    FotaUpdateStatus,
45     getFotaUpdateStatus: library.declare("getFotaUpdateStatus",
46                                          ctypes.default_abi,
47                                          ctypes.int,
48                                          FotaUpdateStatus.ptr)
49   };
50 })();
52 const gFactoryResetFile = "__post_reset_cmd__";
54 #endif
56 function RecoveryService() {}
58 RecoveryService.prototype = {
59   classID: RECOVERYSERVICE_CID,
60   QueryInterface: XPCOMUtils.generateQI([Ci.nsIRecoveryService]),
61   classInfo: XPCOMUtils.generateCI({
62     classID: RECOVERYSERVICE_CID,
63     contractID: RECOVERYSERVICE_CONTRACTID,
64     interfaces: [Ci.nsIRecoveryService],
65     classDescription: "B2G Recovery Service"
66   }),
68   factoryReset: function RS_factoryReset(reason) {
69 #ifdef MOZ_WIDGET_GONK
70     function doReset() {
71       // If this succeeds, then the device reboots and this never returns
72       if (librecovery.factoryReset() != 0) {
73         log("Error: Factory reset failed. Trying again after clearing cache.");
74       }
75       let cache = Cc["@mozilla.org/netwerk/cache-storage-service;1"]
76                     .getService(Ci.nsICacheStorageService);
77       cache.clear();
78       if (librecovery.factoryReset() != 0) {
79         log("Error: Factory reset failed again");
80       }
81     }
83     log("factoryReset " + reason);
84     if (reason == "wipe") {
85       let volumeService = Cc["@mozilla.org/telephony/volume-service;1"]
86                           .getService(Ci.nsIVolumeService);
87       let volNames = volumeService.getVolumeNames();
88       log("Found " + volNames.length + " volumes");
89       let text = "";
90       for (let i = 0; i < volNames.length; i++) {
91         let name = volNames.queryElementAt(i, Ci.nsISupportsString);
92         let volume = volumeService.getVolumeByName(name.data);
93         log("Got volume: " + name.data + " at " + volume.mountPoint);
94         text += "wipe " + volume.mountPoint + "\n";
95       }
97       Cu.import("resource://gre/modules/osfile.jsm");
98       let dir = Cc["@mozilla.org/file/local;1"].createInstance(Ci.nsIFile);
99       dir.initWithPath("/persist");
100       var postResetFile = dir.exists() ?
101                           OS.Path.join("/persist", gFactoryResetFile):
102                           OS.Path.join("/cache", gFactoryResetFile);
103       let encoder = new TextEncoder();
104       let array = encoder.encode(text);
105       let promise = OS.File.writeAtomic(postResetFile, array,
106                                         { tmpPath: postResetFile + ".tmp" });
108       promise.then(doReset, function onError(error) {
109         log("Error: " + error);
110       });
111     } else {
112       doReset();
113     }
114 #endif
115     throw Cr.NS_ERROR_FAILURE;
116   },
118   installFotaUpdate: function RS_installFotaUpdate(updatePath) {
119 #ifdef MOZ_WIDGET_GONK
120     // If this succeeds, then the device reboots and this never returns
121     if (librecovery.installFotaUpdate(updatePath, updatePath.length) != 0) {
122       log("Error: FOTA install failed. Trying again after clearing cache.");
123     }
124     var cache = Cc["@mozilla.org/netwerk/cache-storage-service;1"].getService(Ci.nsICacheStorageService);
125     cache.clear();
126     if (librecovery.installFotaUpdate(updatePath, updatePath.length) != 0) {
127       log("Error: FOTA install failed again");
128     }
129 #endif
130     throw Cr.NS_ERROR_FAILURE;
131   },
133   getFotaUpdateStatus: function RS_getFotaUpdateStatus() {
134     let status =  Ci.nsIRecoveryService.FOTA_UPDATE_UNKNOWN;
135 #ifdef MOZ_WIDGET_GONK
136     let cStatus = librecovery.FotaUpdateStatus();
138     if (librecovery.getFotaUpdateStatus(cStatus.address()) == 0) {
139       status = cStatus.result;
140     }
142 #endif
143     return status;
144   }
147 this.NSGetFactory = XPCOMUtils.generateNSGetFactory([RecoveryService]);