Merge lp:~humpolec-team/humpolec/UbuntuInstaller-alfa-release-fixes into lp:humpolec
- UbuntuInstaller-alfa-release-fixes
- Merge into UbuntuInstaller
Status: | Merged |
---|---|
Merged at revision: | 26 |
Proposed branch: | lp:~humpolec-team/humpolec/UbuntuInstaller-alfa-release-fixes |
Merge into: | lp:humpolec |
Diff against target: |
846 lines (+180/-169) 8 files modified
AndroidManifest.xml (+3/-2) assets/system-image-upgrader (+11/-9) make_release.sh (+16/-0) res/menu/installer_menu.xml (+2/-2) res/menu/launcher_menu.xml (+2/-2) res/values/strings.xml (+3/-2) src/com/canonical/ubuntu/installer/InstallActivity.java (+68/-71) src/com/canonical/ubuntu/installer/UbuntuInstallService.java (+75/-81) |
To merge this branch: | bzr merge lp:~humpolec-team/humpolec/UbuntuInstaller-alfa-release-fixes |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Rex Tsai | Needs Information | ||
Yuan-Chen Cheng (community) | Approve | ||
The Humpolec team | Pending | ||
Review via email: mp+199740@code.launchpad.net |
Commit message
Description of the change
Fixing UI issue when sometimes Install activity was out of sync from service and showing fetching channels
Fixing UI issue when app tasked away during download, then auto install progress was dimmed
Cleanup of service state changes, now broadcasted whenever it changes.
Fixing CyanogenMod issue. CM su behaves differently and requires correction in scripts
Renaming tar to u_tar so when we use tar, it's not accidentally using platform (busybox) one
Cleaning install and download fail and following cleanup.
Fixing downloaded version and update command out of sync, causing non functional "resume install" state
Adding new ROOT permission used by CyanogenMod
Adding signing script
Rex Tsai (chihchun) wrote : | # |
+1 for fixed fetching channels UI issues
+Adding new ROOT permission used by CyanogenMod
+Fixing CyanogenMod su issue.
+0 on Cleaning install and download fail and following cleanup
1. It should check if the original installation exist.
2. It should prompt a confirmation dialog to let user's know his/her installation will be deleted.
Yuan-Chen Cheng (ycheng-twn) wrote : | # |
If we don't consider user install ubuntu phone by other method, as in InstallActivity, there always should not have any previous installtion. If yes, the disk space calculation will get confused.
We should use something like sudo to detect whether there exists previous installation in next version.
Preview Diff
1 | === modified file 'AndroidManifest.xml' |
2 | --- AndroidManifest.xml 2013-12-18 13:27:15 +0000 |
3 | +++ AndroidManifest.xml 2013-12-20 03:53:27 +0000 |
4 | @@ -1,8 +1,8 @@ |
5 | <?xml version="1.0" encoding="utf-8"?> |
6 | <manifest xmlns:android="http://schemas.android.com/apk/res/android" |
7 | package="com.canonical.ubuntu.installer" |
8 | - android:versionCode="1" |
9 | - android:versionName="1.0" > |
10 | + android:versionCode="19" |
11 | + android:versionName="0.2" > |
12 | |
13 | <uses-sdk |
14 | android:minSdkVersion="17" |
15 | @@ -22,6 +22,7 @@ |
16 | <uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS" /> |
17 | <uses-permission android:name="android.permission.ACCESS_CACHE_FILESYSTEM" /> |
18 | <uses-permission android:name="android.permission.REBOOT"/> |
19 | + <uses-permission android:name="android.permission.ACCESS_SUPERUSER"/> |
20 | |
21 | <application |
22 | android:allowBackup="true" |
23 | |
24 | === modified file 'assets/system-image-upgrader' |
25 | --- assets/system-image-upgrader 2013-12-18 01:01:21 +0000 |
26 | +++ assets/system-image-upgrader 2013-12-20 03:53:27 +0000 |
27 | @@ -3,6 +3,8 @@ |
28 | export PATH=$PATH:${PWD} |
29 | UPDATE_FOLDER=${PWD} |
30 | PRIVATE_DIR=$2 |
31 | +BUSYBOX=busybox |
32 | +TAR=u_tar |
33 | set -e |
34 | |
35 | if [ ! -e "$1" ]; then |
36 | @@ -61,9 +63,9 @@ |
37 | fi |
38 | |
39 | # Unpacking |
40 | - TMPDIR=$(busybox mktemp -d ${TMP}/tempdir.XXXXXXXX) |
41 | + TMPDIR=$($BUSYBOX mktemp -d ${TMP}/tempdir.XXXXXXXX) |
42 | cd $TMPDIR |
43 | - cat $1 | busybox unxz | tar xf - |
44 | + cat $1 | $BUSYBOX unxz | $TAR xf - |
45 | if [ ! -e keyring.json ] || [ ! -e keyring.gpg ]; then |
46 | rm -Rf $TMPDIR |
47 | echo "Invalid keyring: $1" |
48 | @@ -71,7 +73,7 @@ |
49 | fi |
50 | |
51 | # Extract the expiry |
52 | - keyring_expiry=$(grep "^ \"expiry\": " keyring.json | busybox cut -d: -f2 | busybox sed -e "s/[ \",]//g") |
53 | + keyring_expiry=$(grep "^ \"expiry\": " keyring.json | $BUSYBOX cut -d: -f2 | $BUSYBOX sed -e "s/[ \",]//g") |
54 | if [ -n "$keyring_expiry" ] && [ "$keyring_expiry" -lt "$(date +%s)" ]; then |
55 | rm -Rf $TMPDIR |
56 | echo "Keyring expired: $1" |
57 | @@ -79,7 +81,7 @@ |
58 | fi |
59 | |
60 | # Extract the keyring type |
61 | - keyring_type=$(grep "^ \"type\": " keyring.json | busybox cut -d: -f2 | busybox sed -e "s/[, \"]//g") |
62 | + keyring_type=$(grep "^ \"type\": " keyring.json | $BUSYBOX cut -d: -f2 | $BUSYBOX sed -e "s/[, \"]//g") |
63 | if [ -z "$keyring_type" ]; then |
64 | rm -Rf $TMPDIR |
65 | echo "Missing keyring type: $1" |
66 | @@ -153,8 +155,8 @@ |
67 | FULL_IMAGE=1 |
68 | rm -f /data/system.img |
69 | rm -f /data/.layout_version |
70 | - busybox dd if=/dev/zero of=/data/system.img seek=500K bs=4096 count=1 |
71 | - busybox mkfs.ext2 -F /data/system.img |
72 | + $BUSYBOX dd if=/dev/zero of=/data/system.img seek=500K bs=4096 count=1 |
73 | + $BUSYBOX mkfs.ext2 -F /data/system.img |
74 | ;; |
75 | |
76 | data) |
77 | @@ -233,7 +235,7 @@ |
78 | |
79 | # Start by removing any file listed in "removed" |
80 | if [ "$FULL_IMAGE" != "1" ]; then |
81 | - cat $UPDATE_FOLDER/$2 | busybox unxz | tar xf - removed >/dev/null 2>&1 || true |
82 | + cat $UPDATE_FOLDER/$2 | $BUSYBOX unxz | $TAR xf - removed >/dev/null 2>&1 || true |
83 | if [ -e removed ]; then |
84 | while read file; do |
85 | rm -Rf $file |
86 | @@ -243,7 +245,7 @@ |
87 | fi |
88 | |
89 | # Unpack everything else on top of the system partition |
90 | - cat $UPDATE_FOLDER/$2 | busybox unxz | tar --checkpoint=200 -xf - |
91 | + cat $UPDATE_FOLDER/$2 | $BUSYBOX unxz | $TAR --checkpoint=200 -xf - |
92 | rm -f removed |
93 | |
94 | if [ -e "partitions/boot.img" ]; then |
95 | @@ -287,7 +289,7 @@ |
96 | echo "Moving SWAP device to final destination" >&2 |
97 | mv $PRIVATE_DIR/SWAP.img /data/ |
98 | echo "Calling mkswap on /data/SWAP.img" >&2 |
99 | - busybox mkswap /data/SWAP.img |
100 | + $BUSYBOX mkswap /data/SWAP.img |
101 | fi |
102 | |
103 | touch /data/.last_update || true |
104 | |
105 | === renamed file 'assets/tar' => 'assets/u_tar' |
106 | === added file 'make_release.sh' |
107 | --- make_release.sh 1970-01-01 00:00:00 +0000 |
108 | +++ make_release.sh 2013-12-20 03:53:27 +0000 |
109 | @@ -0,0 +1,16 @@ |
110 | + #!/sbin/sh |
111 | + KEY=$1 |
112 | + if [[ -z "$KEY" ]]; then |
113 | + echo "Pass path to the keystore" |
114 | + exit -1 |
115 | + fi |
116 | + echo "Release tool, using key" |
117 | + echo "Getting ready for build" |
118 | + android update project --path . |
119 | + echo "Removing old release" |
120 | + rm -rf bin/ |
121 | + ant release |
122 | + echo "Signing build" |
123 | + jarsigner -verbose -sigalg SHA1withRSA -digestalg SHA1 -keystore $KEY bin/MainActivity-release-unsigned.apk humpolec |
124 | + mv bin/MainActivity-release-unsigned.apk bin/UbuntuInstaller.apk |
125 | + echo "Signed relase is at bin/UbuntuInstaller.apk" |
126 | \ No newline at end of file |
127 | |
128 | === modified file 'res/menu/installer_menu.xml' |
129 | --- res/menu/installer_menu.xml 2013-12-13 01:06:14 +0000 |
130 | +++ res/menu/installer_menu.xml 2013-12-20 03:53:27 +0000 |
131 | @@ -5,10 +5,10 @@ |
132 | android:orderInCategory="100" |
133 | android:showAsAction="never" |
134 | android:title="@string/action_detele_download"/> |
135 | - <item |
136 | +<!-- <item |
137 | android:id="@+id/action_settings" |
138 | android:orderInCategory="100" |
139 | android:showAsAction="never" |
140 | android:title="@string/action_settings"/> |
141 | - |
142 | + --> |
143 | </menu> |
144 | |
145 | === modified file 'res/menu/launcher_menu.xml' |
146 | --- res/menu/launcher_menu.xml 2013-12-13 01:06:14 +0000 |
147 | +++ res/menu/launcher_menu.xml 2013-12-20 03:53:27 +0000 |
148 | @@ -11,10 +11,10 @@ |
149 | android:showAsAction="never" |
150 | android:title="@string/action_delete_user_data"/> |
151 | |
152 | - <item |
153 | +<!-- <item |
154 | android:id="@+id/action_settings" |
155 | android:orderInCategory="100" |
156 | android:showAsAction="never" |
157 | android:title="@string/action_settings"/> |
158 | - |
159 | +--> |
160 | </menu> |
161 | |
162 | === modified file 'res/values/strings.xml' |
163 | --- res/values/strings.xml 2013-12-19 09:09:25 +0000 |
164 | +++ res/values/strings.xml 2013-12-20 03:53:27 +0000 |
165 | @@ -11,11 +11,12 @@ |
166 | <string name="action_delete_udata_button">Delete</string> |
167 | <string name="cancel">Cancel</string> |
168 | <string name="welcome_world">Your life is about to change, welcome in Ubuntu installer</string> |
169 | - <string name="install_button_label_install">Install Ubuntu</string> |
170 | + <string name="install_button_label_install">Choose channel to install</string> |
171 | <string name="install_button_label_fetching"><![CDATA[Install Ubuntu<br/><small>fetching channel list</small>]]></string> |
172 | <string name="install_button_label_no_channel"><![CDATA[Install Ubuntu<br/><small>no available channels</small>]]></string> |
173 | <string name="install_button_label_resume">Resume install</string> |
174 | - <string name="install_button_label_cancel">Cancel install</string> |
175 | + <string name="install_button_label_cancel_download">Cancel download</string> |
176 | + <string name="install_button_label_cancel_install">Cancel install</string> |
177 | <string name="channel_picker_dialog_title">Select channel to install</string> |
178 | <string name="version_picker_dialog_title">Select version to install</string> |
179 | <string name="bootstrap_check">bootstrap</string> |
180 | |
181 | === modified file 'src/com/canonical/ubuntu/installer/InstallActivity.java' |
182 | --- src/com/canonical/ubuntu/installer/InstallActivity.java 2013-12-19 12:57:21 +0000 |
183 | +++ src/com/canonical/ubuntu/installer/InstallActivity.java 2013-12-20 03:53:27 +0000 |
184 | @@ -32,7 +32,8 @@ |
185 | public class InstallActivity extends Activity { |
186 | private static final String TAG = "UbuntuInstaller"; |
187 | |
188 | - private UbuntuButton mInstallButton; |
189 | + private UbuntuButton mInstallButton; |
190 | + private boolean mObserversRegistered; |
191 | |
192 | private InstallerState mStatus = InstallerState.READY; |
193 | private VersionInfo mDownloadedVersion = null; |
194 | @@ -79,28 +80,31 @@ |
195 | filter.addAction(UbuntuInstallService.VERSION_UPDATE); |
196 | filter.addAction(UbuntuInstallService.SERVICE_STATE); |
197 | registerReceiver(mServiceObserver, filter); |
198 | + mObserversRegistered = true; |
199 | |
200 | // do we know last activity |
201 | - if (mStatus == InstallerState.READY) { |
202 | - requestServiceState(); |
203 | - mDownloadedVersion = UbuntuInstallService.getDownloadedVersion(this.getApplicationContext()); |
204 | - } else if (mStatus == InstallerState.DOWNLOADING || mStatus == InstallerState.INSTALLING) { |
205 | + if (mStatus == InstallerState.DOWNLOADING || mStatus == InstallerState.INSTALLING) { |
206 | // request last progress / status. this will update UI accordingly |
207 | startService(new Intent(UbuntuInstallService.GET_PROGRESS_STATUS)); |
208 | } else { |
209 | // READY + mDownloadedVersion != null => READY_TO_INSTALL |
210 | mDownloadedVersion = UbuntuInstallService.getDownloadedVersion(this.getApplicationContext()); |
211 | - mStatus = InstallerState.READY; |
212 | - updateUiElements(); |
213 | + if (mDownloadedVersion == null) { |
214 | + requestChannelList(); |
215 | + } |
216 | } |
217 | + requestServiceState(); |
218 | } |
219 | |
220 | @Override |
221 | public void onPause() { |
222 | super.onPause(); |
223 | - mInstallButton.setOnClickListener(null); |
224 | // cancel observer if there is any |
225 | - unregisterReceiver(mServiceObserver); |
226 | + if (mObserversRegistered) { |
227 | + mInstallButton.setOnClickListener(null); |
228 | + unregisterReceiver(mServiceObserver); |
229 | + } |
230 | + mObserversRegistered = false; |
231 | } |
232 | |
233 | @Override |
234 | @@ -114,10 +118,13 @@ |
235 | public boolean onOptionsItemSelected(MenuItem item) { |
236 | switch (item.getItemId()) { |
237 | case R.id.action_delete_download: |
238 | + // also attempt to uninstall ubuntu, since there should be none anyway, keep user data |
239 | + Intent action = new Intent(UbuntuInstallService.UNINSTALL_UBUNTU); |
240 | + action.putExtra(UbuntuInstallService.UNINSTALL_UBUNTU_EXTRA_REMOVE_USER_DATA, false); |
241 | + startService(action); |
242 | deleteDownload(); |
243 | mDownloadedVersion = null; |
244 | - mStatus = InstallerState.READY; |
245 | - updateUiElements(); |
246 | + requestServiceState(); |
247 | break; |
248 | } |
249 | return super.onOptionsItemSelected(item); |
250 | @@ -184,8 +191,7 @@ |
251 | true /* default latest settings*/).show(); |
252 | } else { |
253 | // there are no channels to pick from, this was mistake, disable button |
254 | - mStatus = InstallerState.READY; |
255 | - updateUiElements(); |
256 | + requestServiceState(); |
257 | } |
258 | } |
259 | }; |
260 | @@ -209,8 +215,6 @@ |
261 | Utils.showToast(this, "Starting Ubuntu installation"); |
262 | // reset progress bar |
263 | mProgressBar.setProgress(0); |
264 | - mStatus = InstallerState.INSTALLING; |
265 | - updateUiElements(); |
266 | } |
267 | |
268 | TextPickerDialog.OnChannelPicktListener mInstallDialogListener |
269 | @@ -238,8 +242,6 @@ |
270 | startService(startDownload); |
271 | mTerminal.setText(R.string.downloading_starting); |
272 | mProgressBar.setProgress(0); |
273 | - mStatus = InstallerState.DOWNLOADING; |
274 | - updateUiElements(); |
275 | } |
276 | |
277 | private void downloadVersion(final Context context, final String channel, final boolean bootstrap) { |
278 | @@ -284,50 +286,56 @@ |
279 | } |
280 | |
281 | private void updateUiElements() { |
282 | - switch (mStatus) { |
283 | - case READY: |
284 | - { |
285 | - if (mDownloadedVersion != null) { |
286 | - mInstallButton.setText(R.string.install_button_label_resume); |
287 | - mInstallButton.setEnabled(true); |
288 | - mProgressBar.setEnabled(false); |
289 | - mProgressBar.setProgress(0); |
290 | - mProgressText.setText(""); |
291 | - } else if (mAvailableChannels.size() > 0) { |
292 | - mInstallButton.setText(R.string.install_button_label_install); |
293 | - mInstallButton.setEnabled(true); |
294 | - mProgressBar.setEnabled(false); |
295 | - mProgressBar.setProgress(0); |
296 | - mProgressText.setText(""); |
297 | - } else { |
298 | - mInstallButton.setText(Html.fromHtml(getResources().getString(R.string.install_button_label_no_channel))); |
299 | - mInstallButton.setEnabled(false); |
300 | - mProgressBar.setEnabled(false); |
301 | - mProgressBar.setProgress(0); |
302 | - mProgressText.setText(""); |
303 | + this.runOnUiThread(new Runnable() { |
304 | + @Override |
305 | + public void run() { |
306 | + Log.v(TAG,"updateUiElements(" + mStatus + ")"); |
307 | + switch (mStatus) { |
308 | + case READY: |
309 | + { |
310 | + if (mDownloadedVersion != null) { |
311 | + mInstallButton.setText(R.string.install_button_label_resume); |
312 | + mInstallButton.setEnabled(true); |
313 | + mProgressBar.setEnabled(false); |
314 | + mProgressBar.setProgress(0); |
315 | + mProgressText.setText(""); |
316 | + } else if (mAvailableChannels.size() > 0) { |
317 | + mInstallButton.setText(R.string.install_button_label_install); |
318 | + mInstallButton.setEnabled(true); |
319 | + mProgressBar.setEnabled(false); |
320 | + mProgressBar.setProgress(0); |
321 | + mProgressText.setText(""); |
322 | + } else { |
323 | + mInstallButton.setText(Html.fromHtml(getResources().getString(R.string.install_button_label_no_channel))); |
324 | + mInstallButton.setEnabled(false); |
325 | + mProgressBar.setEnabled(false); |
326 | + mProgressBar.setProgress(0); |
327 | + mProgressText.setText(""); |
328 | + } |
329 | + } |
330 | + break; |
331 | + case FETCHING_CHANNELS: |
332 | + mInstallButton.setText(Html.fromHtml(getResources().getString(R.string.install_button_label_fetching))); |
333 | + mInstallButton.setEnabled(false); |
334 | + mProgressBar.setEnabled(false); |
335 | + mProgressBar.setProgress(0); |
336 | + mProgressText.setText(""); |
337 | + break; |
338 | + case DOWNLOADING: |
339 | + mInstallButton.setText(R.string.install_button_label_cancel_download); |
340 | + mInstallButton.setEnabled(true); |
341 | + mProgressBar.setEnabled(true); |
342 | + mProgressText.setText(R.string.downloading_release); |
343 | + break; |
344 | + case INSTALLING: |
345 | + mInstallButton.setText(R.string.install_button_label_cancel_install); |
346 | + mInstallButton.setEnabled(true); |
347 | + mProgressBar.setEnabled(true); |
348 | + mProgressText.setText(R.string.installing_release); |
349 | + break; |
350 | } |
351 | } |
352 | - break; |
353 | - case FETCHING_CHANNELS: |
354 | - mInstallButton.setText(Html.fromHtml(getResources().getString(R.string.install_button_label_fetching))); |
355 | - mInstallButton.setEnabled(false); |
356 | - mProgressBar.setEnabled(false); |
357 | - mProgressBar.setProgress(0); |
358 | - mProgressText.setText(""); |
359 | - break; |
360 | - case DOWNLOADING: |
361 | - mInstallButton.setText(R.string.install_button_label_cancel); |
362 | - mInstallButton.setEnabled(true); |
363 | - mProgressBar.setEnabled(true); |
364 | - mProgressText.setText(R.string.downloading_release); |
365 | - break; |
366 | - case INSTALLING: |
367 | - mInstallButton.setText(R.string.install_button_label_cancel); |
368 | - mInstallButton.setEnabled(true); |
369 | - mProgressBar.setEnabled(true); |
370 | - mProgressText.setText(R.string.installing_release); |
371 | - break; |
372 | - } |
373 | + }); |
374 | } |
375 | |
376 | BroadcastReceiver mServiceObserver = new BroadcastReceiver() { |
377 | @@ -335,8 +343,8 @@ |
378 | @SuppressWarnings("unchecked") |
379 | @Override |
380 | public void onReceive(Context context, Intent intent) { |
381 | - |
382 | String action = intent.getAction(); |
383 | + Log.v(TAG,"mServiceObserver.onReceive(" + action + ")"); |
384 | // List of available channels fetched |
385 | if (action.equals(UbuntuInstallService.AVAILABLE_CHANNELS)) { |
386 | // ignore channel list if we have already downloaded release |
387 | @@ -379,12 +387,10 @@ |
388 | mDownloadedVersion = UbuntuInstallService.getDownloadedVersion(context); |
389 | if (UbuntuInstallService.checkifReadyToInstall(context)) { |
390 | mDownloadedVersion = UbuntuInstallService.getDownloadedVersion(context); |
391 | - mStatus = InstallerState.READY; |
392 | } else { |
393 | deleteDownload(); |
394 | mDownloadedVersion = null; |
395 | requestChannelList(); |
396 | - mStatus = InstallerState.FETCHING_CHANNELS; |
397 | } |
398 | updateUiElements(); |
399 | } |
400 | @@ -405,8 +411,6 @@ |
401 | updateInfoOnUiThread(reason); |
402 | // delete failed download |
403 | deleteDownload(); |
404 | - mStatus = InstallerState.READY; |
405 | - updateUiElements(); |
406 | requestChannelList(); |
407 | } |
408 | } else if (action.equals(UbuntuInstallService.VERSION_UPDATE)) { |
409 | @@ -415,7 +419,6 @@ |
410 | // check what button should be shown |
411 | if (UbuntuInstallService.checkifReadyToInstall(context)) { |
412 | mDownloadedVersion = UbuntuInstallService.getDownloadedVersion(context); |
413 | - mStatus = InstallerState.READY; |
414 | } |
415 | updateUiElements(); |
416 | } |
417 | @@ -423,12 +426,6 @@ |
418 | checkIfUbuntuIsInstalled(); |
419 | if (!isFinishing()) { |
420 | mStatus = InstallerState.fromOrdian(intent.getIntExtra(UbuntuInstallService.SERVICE_STATE, 0)); |
421 | - if (mStatus != InstallerState.FETCHING_CHANNELS && |
422 | - mStatus != InstallerState.DOWNLOADING && |
423 | - mStatus != InstallerState.INSTALLING) { |
424 | - requestChannelList(); |
425 | - mStatus = InstallerState.FETCHING_CHANNELS; |
426 | - } |
427 | mDownloadedVersion = UbuntuInstallService.getDownloadedVersion(context); |
428 | updateUiElements(); |
429 | } |
430 | |
431 | === modified file 'src/com/canonical/ubuntu/installer/UbuntuInstallService.java' |
432 | --- src/com/canonical/ubuntu/installer/UbuntuInstallService.java 2013-12-19 11:21:02 +0000 |
433 | +++ src/com/canonical/ubuntu/installer/UbuntuInstallService.java 2013-12-20 03:53:27 +0000 |
434 | @@ -148,7 +148,7 @@ |
435 | // ================================================================================================= |
436 | private static final String BUSYBOX = "busybox"; |
437 | private static final String GPG = "gpg"; |
438 | - private static final String TAR = "tar"; |
439 | + private static final String TAR = "u_tar"; |
440 | private static final String ANDROID_LOOP_MOUNT = "aloopmount"; |
441 | private static final String ANDROID_BOOTMGR = "bootmgr"; |
442 | private static final String UPDATE_SCRIPT = "system-image-upgrader"; |
443 | @@ -187,7 +187,7 @@ |
444 | private long mProgress; // so far handled amount downloaded/processed |
445 | private int mLastSignalledProgress; |
446 | private long mTotalSize; // calculated |
447 | - private InstallerState mServiceState; |
448 | + private InstallerState mInstallerState; |
449 | |
450 | public class Channel { |
451 | String alias; |
452 | @@ -236,13 +236,13 @@ |
453 | mRootOfWorkPath = getFilesDir().toString(); // "/data/data/com.canonical.ubuntuinstaller/files"; |
454 | workPathInCache = false; |
455 | } |
456 | - mServiceState = InstallerState.READY; |
457 | + mInstallerState = InstallerState.READY; |
458 | } |
459 | |
460 | @Override |
461 | public int onStartCommand(Intent intent, int flags, int startId) { |
462 | // if service is not in ready state, handle specific requests here |
463 | - if (mServiceState != InstallerState.READY) { |
464 | + if (mInstallerState != InstallerState.READY) { |
465 | String action = intent.getAction(); |
466 | if (action.equals(CANCEL_DOWNLOAD)) { |
467 | // set the cancel flag, but let it remove downloaded files on worker thread |
468 | @@ -250,7 +250,7 @@ |
469 | } else if (action.equals(GET_PROGRESS_STATUS)) { |
470 | broadcastProgress(mLastSignalledProgress, ""); |
471 | } else if (action.equals(GET_SERVICE_STATE)) { |
472 | - broadcastServiceState(); |
473 | + broadcastInstallerState(); |
474 | } |
475 | } |
476 | return super.onStartCommand(intent, flags, startId); |
477 | @@ -263,10 +263,10 @@ |
478 | |
479 | Log.d(TAG, this.toString() + " onHandleIntent: " + action); |
480 | if (action.equals(GET_CHANNEL_LIST)) { |
481 | - mServiceState = InstallerState.FETCHING_CHANNELS; |
482 | + updateInstallerState(InstallerState.FETCHING_CHANNELS); |
483 | result = doGetChannelList(intent); |
484 | } else if (action.equals(DOWNLOAD_RELEASE)) { |
485 | - mServiceState = InstallerState.DOWNLOADING; |
486 | + updateInstallerState(InstallerState.DOWNLOADING); |
487 | result = doDownloadRelease(intent); |
488 | } else if (action.equals(CANCEL_DOWNLOAD)) { |
489 | // download should be already cancelled, now delete all the files |
490 | @@ -274,22 +274,22 @@ |
491 | } else if (action.equals(PAUSE_DOWNLOAD)) { |
492 | // TODO: handle download |
493 | } else if (action.equals(RESUME_DOWNLOAD)) { |
494 | - mServiceState = InstallerState.DOWNLOADING; |
495 | + updateInstallerState(InstallerState.DOWNLOADING); |
496 | // TODO: handle download |
497 | } else if (action.equals(CLEAN_DOWNLOAD)) { |
498 | result = doRemoreDownload(intent); |
499 | } else if (action.equals(INSTALL_UBUNTU)) { |
500 | - mServiceState = InstallerState.INSTALLING; |
501 | + updateInstallerState(InstallerState.INSTALLING); |
502 | result = doInstallUbuntu(intent); |
503 | } else if (action.equals(CANCEL_INSTALL)) { |
504 | // install should be already cancelled, try to delete it now |
505 | - mServiceState = InstallerState.UNINSTALLING; |
506 | + updateInstallerState(InstallerState.UNINSTALLING); |
507 | result = doUninstallUbuntu(intent); |
508 | } else if (action.equals(UNINSTALL_UBUNTU)) { |
509 | - mServiceState = InstallerState.UNINSTALLING; |
510 | + updateInstallerState(InstallerState.UNINSTALLING); |
511 | result = doUninstallUbuntu(intent); |
512 | } else if (action.equals(DELETE_UBUNTU_USER_DATA)) { |
513 | - mServiceState = InstallerState.DELETING_USER_DATA; |
514 | + updateInstallerState(InstallerState.DELETING_USER_DATA); |
515 | result = doDeleteUbuntuUserData(intent); |
516 | } else if(action.equals(REBOOT_UBUNTU)) { |
517 | Log.d(TAG, this.toString() + ": REBOOT_UBUNTU"); |
518 | @@ -298,12 +298,12 @@ |
519 | } else { |
520 | // for any other request broadcast service state |
521 | result = new Intent(SERVICE_STATE); |
522 | - result.putExtra(SERVICE_STATE_EXTRA_STATE, mServiceState.ordinal()); |
523 | + result.putExtra(SERVICE_STATE_EXTRA_STATE, mInstallerState.ordinal()); |
524 | } |
525 | if (result != null) { |
526 | sendBroadcast(result); |
527 | } |
528 | - mServiceState = InstallerState.READY; |
529 | + updateInstallerState(InstallerState.READY); |
530 | Log.d(TAG, this.toString() + " onHandleIntent: " + action + " END"); |
531 | } |
532 | |
533 | @@ -335,7 +335,7 @@ |
534 | if (alias == null || alias.equals("")) { |
535 | alias = key; // use key instead |
536 | } |
537 | - Log.v(TAG, "Channel:" + alias + " url:" + url); |
538 | + // Log.v(TAG, "Channel:" + alias + " url:" + url); |
539 | if (!hidden || includeHidden) { |
540 | channels.put(alias, url); |
541 | } |
542 | @@ -354,12 +354,14 @@ |
543 | } |
544 | |
545 | private Intent doRemoreDownload(Intent intent) { |
546 | - Intent result = new Intent(); |
547 | + Intent result = new Intent(SERVICE_STATE); |
548 | String s = deleteRelease(); |
549 | if (s!= null) { |
550 | + broadcastProgress(-1, s); |
551 | // delete failed |
552 | } |
553 | - return result; |
554 | + result.putExtra(SERVICE_STATE, InstallerState.READY.ordinal()); |
555 | + return result; |
556 | } |
557 | |
558 | private Intent doInstallUbuntu(Intent intent) { |
559 | @@ -367,14 +369,11 @@ |
560 | Intent result = new Intent(INSTALL_RESULT); |
561 | // get update command file |
562 | SharedPreferences pref = getSharedPreferences( SHARED_PREF, Context.MODE_PRIVATE); |
563 | - String updateCommand = // "/cache/ubuntu_release/update_command"; |
564 | - pref.getString(PREF_KEY_UPDATE_COMMAND,""); |
565 | + String updateCommand = pref.getString(PREF_KEY_UPDATE_COMMAND,""); |
566 | mTotalSize = pref.getInt(PREF_KEY_ESTIMATED_CHECKPOINTS, 0); |
567 | mLastSignalledProgress = 0; |
568 | if (updateCommand.equals("") || ! new File(updateCommand).exists()) { |
569 | - result.putExtra(INSTALL_RESULT_EXTRA_INT, -1); |
570 | - result.putExtra(INSTALL_RESULT_EXTRA_STR, "Missing update command"); |
571 | - return result; |
572 | + return handleInstallFail(result, -1, "Missing update command"); |
573 | } |
574 | mWakeLock = mPowerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "ubuntu-installing"); |
575 | try { |
576 | @@ -394,9 +393,7 @@ |
577 | Utils.extractExecutableAsset(this, U_REBOOT_APP_ASC, supportingFiles.toString(), false); |
578 | } catch (IOException e) { |
579 | e.printStackTrace(); |
580 | - result.putExtra(INSTALL_RESULT_EXTRA_INT, -1); |
581 | - result.putExtra(INSTALL_RESULT_EXTRA_STR, "Failed to extract supporting assets"); |
582 | - return result; |
583 | + return handleInstallFail(result, -1, "Failed to extract supporting assets"); |
584 | } |
585 | // get superuser and run update script |
586 | broadcastProgress(-1, "Starting update script"); |
587 | @@ -405,30 +402,34 @@ |
588 | DataOutputStream os = new DataOutputStream(process.getOutputStream()); |
589 | // debug purpose. |
590 | // os.writeBytes("set -x\n"); |
591 | + // make sure we are in work folder |
592 | + os.writeBytes(String.format("cd %s\n", supportingFiles.getAbsolutePath())); |
593 | + os.writeBytes("echo \"SU granted\"\n"); |
594 | // run system-image-upgrader. |
595 | os.writeBytes(String.format("sh %s %s %s\n", |
596 | UPDATE_SCRIPT, |
597 | updateCommand, |
598 | - getFilesDir().toString() |
599 | + getFilesDir().getAbsolutePath() |
600 | )); |
601 | + os.writeBytes(String.format("cd %s\n", supportingFiles.getAbsolutePath())); |
602 | // backup original recovery. |
603 | if(!new File(getFilesDir().toString(), ANDROID_REOCVERY_IMG).exists()) { |
604 | - os.writeBytes(String.format("%s/%s -b %s %s/%s\n", |
605 | - supportingFiles.toString(), |
606 | + os.writeBytes(String.format("./%s -b %s %s/%s\n", |
607 | ANDROID_BOOTMGR, |
608 | Utils.getRecoveryPartitionPath(), |
609 | - getFilesDir().toString(), |
610 | + getFilesDir().getAbsolutePath(), |
611 | ANDROID_REOCVERY_IMG |
612 | )); |
613 | } |
614 | + os.writeBytes(String.format("cd %s\n", supportingFiles.getAbsolutePath())); |
615 | // overwrite the recovery partition. |
616 | - os.writeBytes(String.format("%s/%s -b %s/%s %s\n", |
617 | - supportingFiles.toString(), |
618 | + os.writeBytes(String.format("./%s -b %s/%s %s\n", |
619 | ANDROID_BOOTMGR, |
620 | - getFilesDir().toString(), |
621 | + getFilesDir().getAbsolutePath(), |
622 | UBUNTU_BOOT_IMG, |
623 | Utils.getRecoveryPartitionPath() |
624 | )); |
625 | + |
626 | // close terminal |
627 | os.writeBytes("exit\n"); |
628 | os.flush(); |
629 | @@ -474,13 +475,9 @@ |
630 | Log.v(TAG, "Worker thread exited with: " + ret); |
631 | // if script was not executed, then user did not granted SU permissions |
632 | if (ret == 255 || !scriptExecuted ) { |
633 | - result.putExtra(INSTALL_RESULT_EXTRA_INT, -1); |
634 | - result.putExtra(INSTALL_RESULT_EXTRA_STR, "Failed to get SU permissions"); |
635 | - return result; |
636 | + return handleInstallFail(result, -1, "Failed to get SU permissions"); |
637 | } else if (ret != 0) { |
638 | - result.putExtra(INSTALL_RESULT_EXTRA_INT, -1); |
639 | - result.putExtra(INSTALL_RESULT_EXTRA_STR, "Instalation failed"); |
640 | - return result; |
641 | + return handleInstallFail(result, -1, "Instalation failed"); |
642 | } |
643 | running =false; |
644 | } catch (IllegalThreadStateException e) { |
645 | @@ -491,9 +488,7 @@ |
646 | } catch (IOException e) { |
647 | e.printStackTrace(); |
648 | Log.w(TAG, "Update failed"); |
649 | - result.putExtra(INSTALL_RESULT_EXTRA_INT, -1); |
650 | - result.putExtra(INSTALL_RESULT_EXTRA_STR, "Install failed"); |
651 | - return result; |
652 | + return handleInstallFail(result, -1, "Install failed"); |
653 | } |
654 | } finally { |
655 | if (mWakeLock != null && mWakeLock.isHeld()) { |
656 | @@ -508,6 +503,13 @@ |
657 | result.putExtra(INSTALL_RESULT_EXTRA_INT, 0); |
658 | return result; |
659 | } |
660 | + |
661 | + private Intent handleInstallFail(Intent i, int res, String failReason) { |
662 | + i.putExtra(INSTALL_RESULT_EXTRA_INT, -1); |
663 | + i.putExtra(INSTALL_RESULT_EXTRA_STR, "Missing update command"); |
664 | + doUninstallUbuntu(i); |
665 | + return i; |
666 | + } |
667 | |
668 | private Intent doUninstallUbuntu(Intent intent) { |
669 | File workingFolder = new File(mRootOfWorkPath, TEMP_FOLDER); |
670 | @@ -588,13 +590,13 @@ |
671 | try { |
672 | Process process = Runtime.getRuntime().exec("su", null, getFilesDir()); |
673 | DataOutputStream os = new DataOutputStream(process.getOutputStream()); |
674 | - |
675 | + |
676 | Utils.extractExecutableAsset(this, ANDROID_BOOTMGR, getFilesDir().toString(), true); |
677 | // overwrite the recovery partition. |
678 | os.writeBytes(String.format("%s/%s -b %s/%s %s\n", |
679 | - getFilesDir().toString(), |
680 | + getFilesDir().getAbsolutePath(), |
681 | ANDROID_BOOTMGR, |
682 | - getFilesDir().toString(), |
683 | + getFilesDir().getAbsolutePath(), |
684 | UBUNTU_BOOT_IMG, |
685 | Utils.getRecoveryPartitionPath() |
686 | )); |
687 | @@ -643,9 +645,12 @@ |
688 | try { |
689 | Process process = Runtime.getRuntime().exec("su", null, workingFolder); |
690 | DataOutputStream os = new DataOutputStream(process.getOutputStream()); |
691 | + // make sure we are in work folder |
692 | os.writeBytes("echo \"SU granted\"\n"); |
693 | for (String c : commands) { |
694 | Log.v(TAG, "Executing:" + c); |
695 | + // make sure we are always at working folder before running next command |
696 | + os.writeBytes(String.format("cd %s\n", workingFolder.getAbsolutePath())); |
697 | os.writeBytes(c); |
698 | } |
699 | os.writeBytes(String.format("rm -rf %s\n", workingFolder.getAbsolutePath())); |
700 | @@ -728,9 +733,7 @@ |
701 | if (releases.size() == 0 || releases.get(0).files.length == 0 ) { |
702 | // something is wrong, empty release |
703 | Log.e(TAG, "Empty releas"); |
704 | - result.putExtra(DOWNLOAD_RESULT_EXTRA_INT, -1); |
705 | - result.putExtra(DOWNLOAD_RESULT_EXTRA_STR, "Empty release"); |
706 | - return result; |
707 | + return handleDownloadError(result, -1, "Empty release"); |
708 | } |
709 | // get right version, otherwise first since that is most recent one |
710 | Image choosenRelease = null; |
711 | @@ -744,9 +747,7 @@ |
712 | } |
713 | if (choosenRelease == null) { |
714 | Log.e(TAG, "wrong release vwersion"); |
715 | - result.putExtra(DOWNLOAD_RESULT_EXTRA_INT, -1); |
716 | - result.putExtra(DOWNLOAD_RESULT_EXTRA_STR, "wrong release vwersion"); |
717 | - return result; |
718 | + return handleDownloadError(result, -1, "wrong release vwersion"); |
719 | } |
720 | } else { |
721 | choosenRelease = releases.get(0); |
722 | @@ -771,9 +772,7 @@ |
723 | String s = deleteRelease(); |
724 | if (s != null) { |
725 | // remove failed |
726 | - result.putExtra(DOWNLOAD_RESULT_EXTRA_INT, -1); |
727 | - result.putExtra(DOWNLOAD_RESULT_EXTRA_STR, s); |
728 | - return result; |
729 | + return handleDownloadError(result, -1, s); |
730 | } |
731 | // make sure release folder exists |
732 | File release = new File(rootFolder,RELEASE_FOLDER); |
733 | @@ -794,10 +793,7 @@ |
734 | msg += "/data need 2.5G for system plus " + String.valueOf(mTotalSize) + " bytes for download"; |
735 | } |
736 | Log.i(TAG, msg); |
737 | - |
738 | - result.putExtra(DOWNLOAD_RESULT_EXTRA_INT, -1); |
739 | - result.putExtra(DOWNLOAD_RESULT_EXTRA_STR, msg); |
740 | - return result; |
741 | + return handleDownloadError(result, -1, msg); |
742 | } |
743 | |
744 | // mProgressSteps = mTotalDownloadSize / 100; // we want 1% steps |
745 | @@ -832,29 +828,19 @@ |
746 | } |
747 | } catch (MalformedURLException e) { |
748 | Log.e(TAG, "Failed to download release:", e); |
749 | - result.putExtra(DOWNLOAD_RESULT_EXTRA_INT, -1); |
750 | - result.putExtra(DOWNLOAD_RESULT_EXTRA_STR, "Malformed release url"); |
751 | - return result; |
752 | + return handleDownloadError(result, -1, "Malformed release url"); |
753 | } catch (FileNotFoundException e) { |
754 | Log.e(TAG, "Failed to download release:", e); |
755 | - result.putExtra(DOWNLOAD_RESULT_EXTRA_INT, -1); |
756 | - result.putExtra(DOWNLOAD_RESULT_EXTRA_STR, "File not found"); |
757 | - return result; |
758 | + return handleDownloadError(result, -1, "File not found"); |
759 | } catch (IOException e){ |
760 | Log.e(TAG, "Failed to download release:", e); |
761 | - result.putExtra(DOWNLOAD_RESULT_EXTRA_INT, -1); |
762 | - result.putExtra(DOWNLOAD_RESULT_EXTRA_STR, "IO Error"); |
763 | - return result; |
764 | + return handleDownloadError(result, -1, "IO Error"); |
765 | } catch (ESumNotMatchException e) { |
766 | // Download file check sum error !! |
767 | - result.putExtra(DOWNLOAD_RESULT_EXTRA_INT, -1); |
768 | - result.putExtra(DOWNLOAD_RESULT_EXTRA_STR, "Download check sum error"); |
769 | - return result; |
770 | + return handleDownloadError(result, -1, "Download check sum error"); |
771 | } catch (ECancelException e) { |
772 | // Download was cancelled by user |
773 | - result.putExtra(DOWNLOAD_RESULT_EXTRA_INT, -2); |
774 | - result.putExtra(DOWNLOAD_RESULT_EXTRA_STR, "Download cancelled by user"); |
775 | - return result; |
776 | + return handleDownloadError(result, -2, "Download cancelled by user"); |
777 | } |
778 | |
779 | Log.i(TAG, "Download done in " + (System.currentTimeMillis() - time )/1000 + " seconds"); |
780 | @@ -907,9 +893,7 @@ |
781 | } |
782 | } catch (IOException e) { |
783 | e.printStackTrace(); |
784 | - result.putExtra(DOWNLOAD_RESULT_EXTRA_INT, -1); |
785 | - result.putExtra(DOWNLOAD_RESULT_EXTRA_STR, "Failed to generate update command"); |
786 | - return result; |
787 | + return handleDownloadError(result, -1, "Failed to generate update command"); |
788 | } |
789 | broadcastProgress(-1, "Download done in " + (System.currentTimeMillis() - time )/1000 + " seconds"); |
790 | int estimatedCheckCount = 0; |
791 | @@ -939,9 +923,11 @@ |
792 | return result; |
793 | } |
794 | |
795 | - class DownloadTask { |
796 | - URL url; |
797 | - File targetFolder; |
798 | + private Intent handleDownloadError(Intent i, int res, String reason) { |
799 | + i.putExtra(DOWNLOAD_RESULT_EXTRA_INT, -1); |
800 | + i.putExtra(DOWNLOAD_RESULT_EXTRA_STR, "Failed to generate update command"); |
801 | + deleteRelease(); |
802 | + return i; |
803 | } |
804 | |
805 | private String doDownloadUrl(URL url, File targerLocation) throws MalformedURLException, |
806 | @@ -1018,12 +1004,19 @@ |
807 | return null; |
808 | } |
809 | |
810 | - private void broadcastServiceState() { |
811 | + private void broadcastInstallerState() { |
812 | Intent i = new Intent(SERVICE_STATE); |
813 | - i.putExtra(SERVICE_STATE, mServiceState.ordinal()); |
814 | + i.putExtra(SERVICE_STATE, mInstallerState.ordinal()); |
815 | sendBroadcast(i); |
816 | } |
817 | |
818 | + private void updateInstallerState(InstallerState newState) { |
819 | + mInstallerState = newState; |
820 | + Intent i = new Intent(SERVICE_STATE); |
821 | + i.putExtra(SERVICE_STATE, mInstallerState.ordinal()); |
822 | + sendBroadcast(i); |
823 | + } |
824 | + |
825 | private void broadcastProgress(int val, String progress) { |
826 | Intent i = new Intent(PROGRESS); |
827 | i.putExtra(PROGRESS_EXTRA_INT, val); |
828 | @@ -1092,16 +1085,17 @@ |
829 | public static boolean checkifReadyToInstall(Context context) { |
830 | SharedPreferences pref = context.getSharedPreferences(SHARED_PREF, Context.MODE_PRIVATE); |
831 | String command = pref.getString(PREF_KEY_UPDATE_COMMAND, ""); |
832 | - boolean ready = false; |
833 | if (!command.equals("")){ |
834 | File f = new File(command); |
835 | if (f.exists()) { |
836 | return true; |
837 | } else { |
838 | pref.edit().putString(PREF_KEY_UPDATE_COMMAND, "").commit(); |
839 | + VersionInfo.storeEmptyVersion(pref.edit(), PREF_KEY_DOWNLOADED_VERSION); |
840 | return false; |
841 | } |
842 | } |
843 | + VersionInfo.storeEmptyVersion(pref.edit(), PREF_KEY_DOWNLOADED_VERSION); |
844 | return false; |
845 | } |
846 | } |
look good to me.