diff --git a/.classpath b/.classpath index e4d3936..dcdecd4 100644 --- a/.classpath +++ b/.classpath @@ -3,6 +3,7 @@ - - + + + diff --git a/Android.mk b/Android.mk new file mode 100644 index 0000000..dfa3511 --- /dev/null +++ b/Android.mk @@ -0,0 +1,27 @@ +LOCAL_PATH:= $(call my-dir) + +include $(CLEAR_VARS) +LOCAL_MODULE_NAME := libGson +LOCAL_MODULE_TAGS := optional +LOCAL_PREBUILT_STATIC_JAVA_LIBRARIES := libGson:Gson/gson-2.2.2.jar +#LOCAL_PROGUARD_FLAG_FILES := proguard.cfg +include $(BUILD_MULTI_PREBUILT) + + +include $(CLEAR_VARS) +LOCAL_PACKAGE_NAME := RomUpdater +LOCAL_MODULE_TAGS := optional + +LOCAL_CERTIFICATE := shared +LOCAL_PROGUARD_FLAG_FILES := proguard.cfg + +LOCAL_SRC_FILES := \ + $(call all-java-files-under, google) \ + $(call all-java-files-under, src) \ + +LOCAL_STATIC_JAVA_LIBRARIES := libGson + +# LOCAL_JAVACFLAGS += -Xlint:unchecked + +include $(BUILD_PACKAGE) + diff --git a/AndroidManifest.xml b/AndroidManifest.xml index 116f310..e700392 100644 --- a/AndroidManifest.xml +++ b/AndroidManifest.xml @@ -1,10 +1,11 @@ + android:versionName="2.10-JB" android:versionCode="10210"> + android:label="@string/app_name" + android:icon="@drawable/ic_launcher_romupdater" + android:allowClearUserData="true" android:allowBackup="true"> @@ -13,14 +14,37 @@ - - - - - - - - + + + + + + + + + + + + + - - \ No newline at end of file + + + + + + + + diff --git a/CleanSpec.mk b/CleanSpec.mk new file mode 100644 index 0000000..639dea8 --- /dev/null +++ b/CleanSpec.mk @@ -0,0 +1,15 @@ +# ************************************************ +# NEWER CLEAN STEPS MUST BE AT THE END OF THE LIST +# ************************************************ + +# For example: +# $(call add-clean-step, rm -rf $(OUT_DIR)/target/common/obj/APPS/AndroidTests_intermediates) +# $(call add-clean-step, rm -rf $(OUT_DIR)/target/common/obj/JAVA_LIBRARIES/core_intermediates) +# $(call add-clean-step, find $(OUT_DIR) -type f -name "IGTalkSession*" -print0 | xargs -0 rm -f) +# $(call add-clean-step, rm -rf $(PRODUCT_OUT)/data/*) + +$(call add-clean-step, rm -rf $(OUT_DIR)/target/common/obj/JAVA_LIBRARIES/libGson_intermediates) +$(call add-clean-step, rm -rf $(OUT_DIR)/target/common/obj/APPS/RomUpdater_intermediates) +$(call add-clean-step, rm -rf $(OUT_DIR)/target/common/R/org/elegosproject) +$(call add-clean-step, rm -rf $(PRODUCT_OUT)/obj/APPS/RomUpdater_intermediates) + diff --git a/Gson/LICENSE b/Gson/LICENSE new file mode 100644 index 0000000..892eaed --- /dev/null +++ b/Gson/LICENSE @@ -0,0 +1,203 @@ +Google Gson + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright 2008-2011 Google Inc. + + 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. diff --git a/Gson/README b/Gson/README new file mode 100644 index 0000000..a0562cc --- /dev/null +++ b/Gson/README @@ -0,0 +1,7 @@ +Gson is a Java library that can be used to convert a Java object into its +JSON representation. It can also be used to convert a JSON string into an +equivalent Java object. Gson can work with arbitrary Java objects including +pre-existing objects that you do not have source-code of. + +Complete Gson documentation is available at its project page +http://code.google.com/p/google-gson diff --git a/Gson/gson-1.6.jar b/Gson/gson-1.6.jar deleted file mode 100644 index 4f79705..0000000 Binary files a/Gson/gson-1.6.jar and /dev/null differ diff --git a/Gson/gson-2.2.2-sources.jar b/Gson/gson-2.2.2-sources.jar new file mode 100644 index 0000000..db8fb05 Binary files /dev/null and b/Gson/gson-2.2.2-sources.jar differ diff --git a/Gson/gson-2.2.2.jar b/Gson/gson-2.2.2.jar new file mode 100644 index 0000000..f2108e0 Binary files /dev/null and b/Gson/gson-2.2.2.jar differ diff --git a/README b/README index 2b73240..3777147 100644 --- a/README +++ b/README @@ -1,18 +1,29 @@ +About this Fork (Android Repo Version) +-------------------------------------------------------------------------------- + +This project was forked by epsylon3 from elegos version to be integrated +in a repo build process and to support dynamic json file (via php or other) + +This version is customized via an overlay xml placed in device tree +to customize default repositories urls and Application name. + +-------------------------------------------------------------------------------- + ROMUpdater is meant to be an Android universal ROM updater. -It checks for the build.prop's ro.build.display.id and -downloads a series of JSON files that describe and give +It checks for the build.prop's ro.modversion or ro.cm.version +an downloads a series of JSON files that describe and give a link to the available versions (from the next one upwards, if available). It can also execute the most common Recovery actions (via /cache/recovery/command and extendedcommand), for example Nandroid backup, -cache/data wipe, or simply enter the removery mode. +dalvik and cache wipe, or simply enter the recovery mode. This application requires root. ROMUpdater is a free software and its source code is being distributed under the GNU GPL v.3. -You can find the final APK in the market as +You can find the original APK in the market as "ROMUpdater" by Giacomo Furlan For more informations please visit the following sites: diff --git a/default.properties b/default.properties deleted file mode 100644 index 46769a7..0000000 --- a/default.properties +++ /dev/null @@ -1,11 +0,0 @@ -# This file is automatically generated by Android Tools. -# Do not modify this file -- YOUR CHANGES WILL BE ERASED! -# -# This file must be checked in Version Control Systems. -# -# To customize properties used by the Ant build system use, -# "build.properties", and override values to adapt the script to your -# project structure. - -# Project target. -target=android-7 diff --git a/proguard.cfg b/proguard.cfg index 8ad7d33..56735dd 100644 --- a/proguard.cfg +++ b/proguard.cfg @@ -5,12 +5,25 @@ -verbose -optimizations !code/simplification/arithmetic,!field/*,!class/merging/* +# Gson uses generic type information stored in a class file when working with fields. Proguard +-keepattributes Signature +# To use GSON @Expose annotation +-keepattributes *Annotation* +# Gson specific classes +-keep class sun.misc.Unsafe { *; } +# Application classes that will be serialized/deserialized over Gson +-keep class com.google.gson.examples.android.model.** { *; } + +-keepclassmembers class com.google.gson.internal.UnsafeAllocator { + public java.lang.Object allocateInstance(java.lang.Class); + public java.lang.reflect.Field theUnsafe; +} + -keep public class * extends android.app.Activity -keep public class * extends android.app.Application -keep public class * extends android.app.Service -keep public class * extends android.content.BroadcastReceiver --keep public class * extends android.content.ContentProvider --keep public class com.android.vending.licensing.ILicensingService +-keep public class * extends android.content.*Provider -keepclasseswithmembernames class * { native ; diff --git a/project.properties b/project.properties new file mode 100644 index 0000000..0840b4a --- /dev/null +++ b/project.properties @@ -0,0 +1,14 @@ +# This file is automatically generated by Android Tools. +# Do not modify this file -- YOUR CHANGES WILL BE ERASED! +# +# This file must be checked in Version Control Systems. +# +# To customize properties used by the Ant build system edit +# "ant.properties", and override values to adapt the script to your +# project structure. +# +# To enable ProGuard to shrink and obfuscate your code, uncomment this (available properties: sdk.dir, user.home): +#proguard.config=${sdk.dir}/tools/proguard/proguard-android.txt:proguard-project.txt + +# Project target. +target=android-15 diff --git a/res/drawable-hdpi/ic_launcher_romupdater.png b/res/drawable-hdpi/ic_launcher_romupdater.png index 0dd58fb..88bdd9f 100644 Binary files a/res/drawable-hdpi/ic_launcher_romupdater.png and b/res/drawable-hdpi/ic_launcher_romupdater.png differ diff --git a/res/drawable-hdpi/ic_menu_exit.png b/res/drawable-hdpi/ic_menu_exit.png deleted file mode 100644 index 7740596..0000000 Binary files a/res/drawable-hdpi/ic_menu_exit.png and /dev/null differ diff --git a/res/drawable-hdpi/ic_menu_info.png b/res/drawable-hdpi/ic_menu_info.png deleted file mode 100644 index ff57dc7..0000000 Binary files a/res/drawable-hdpi/ic_menu_info.png and /dev/null differ diff --git a/res/drawable-ldpi/ic_launcher_romupdater.png b/res/drawable-ldpi/ic_launcher_romupdater.png index 80461de..ae8111f 100644 Binary files a/res/drawable-ldpi/ic_launcher_romupdater.png and b/res/drawable-ldpi/ic_launcher_romupdater.png differ diff --git a/res/drawable-ldpi/ic_menu_exit.png b/res/drawable-ldpi/ic_menu_exit.png deleted file mode 100644 index 8d64f66..0000000 Binary files a/res/drawable-ldpi/ic_menu_exit.png and /dev/null differ diff --git a/res/drawable-ldpi/ic_menu_info.png b/res/drawable-ldpi/ic_menu_info.png deleted file mode 100644 index 1de8db1..0000000 Binary files a/res/drawable-ldpi/ic_menu_info.png and /dev/null differ diff --git a/res/drawable-mdpi/ic_launcher_romupdater.png b/res/drawable-mdpi/ic_launcher_romupdater.png index 8a444d0..7cb59a5 100644 Binary files a/res/drawable-mdpi/ic_launcher_romupdater.png and b/res/drawable-mdpi/ic_launcher_romupdater.png differ diff --git a/res/drawable-mdpi/ic_menu_exit.png b/res/drawable-mdpi/ic_menu_exit.png deleted file mode 100644 index a0ab614..0000000 Binary files a/res/drawable-mdpi/ic_menu_exit.png and /dev/null differ diff --git a/res/drawable-mdpi/ic_menu_info.png b/res/drawable-mdpi/ic_menu_info.png deleted file mode 100644 index efd0e2f..0000000 Binary files a/res/drawable-mdpi/ic_menu_info.png and /dev/null differ diff --git a/res/layout/downloads.xml b/res/layout/downloads.xml index 8e41c46..4a068ae 100644 --- a/res/layout/downloads.xml +++ b/res/layout/downloads.xml @@ -1,9 +1,8 @@ - + xmlns:android="http://schemas.android.com/apk/res/android" + android:layout_width="fill_parent" + android:layout_height="fill_parent"> - - + android:layout_width="fill_parent" + android:layout_height="fill_parent"> + diff --git a/res/layout/repo_list.xml b/res/layout/repo_list.xml index 6faef7b..dfa79ea 100644 --- a/res/layout/repo_list.xml +++ b/res/layout/repo_list.xml @@ -1,11 +1,11 @@ + xmlns:android="http://schemas.android.com/apk/res/android" + android:layout_width="fill_parent" + android:layout_height="fill_parent"> + /> diff --git a/res/layout/restore.xml b/res/layout/restore.xml index 84a6b46..8ced28d 100644 --- a/res/layout/restore.xml +++ b/res/layout/restore.xml @@ -1,11 +1,11 @@ - + diff --git a/res/layout/version.xml b/res/layout/version.xml index 7b7d496..059e3bb 100644 --- a/res/layout/version.xml +++ b/res/layout/version.xml @@ -4,16 +4,31 @@ android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="fill_parent"> - - - \ No newline at end of file + + + + + diff --git a/res/layout/versions_list.xml b/res/layout/versions_list.xml index b977865..130cf11 100644 --- a/res/layout/versions_list.xml +++ b/res/layout/versions_list.xml @@ -2,17 +2,11 @@ - - + android:layout_width="fill_parent" + android:layout_height="fill_parent" +> + diff --git a/res/menu/menu.xml b/res/menu/menu.xml index 745f90b..b3f8cd7 100644 --- a/res/menu/menu.xml +++ b/res/menu/menu.xml @@ -2,13 +2,19 @@ + diff --git a/res/values-es/messages.xml b/res/values-es/messages.xml new file mode 100644 index 0000000..8433537 --- /dev/null +++ b/res/values-es/messages.xml @@ -0,0 +1,32 @@ + + + Mantener pulsado para ver la lista de cambios + La URL del repositorio de ROM ha sido modificado + Actualmente el repositorio de ROM es inaccesible. Porfavor compúebalo, o intenta más tarde. + Al parecer el escaneador de codigo de barras (com.google.zxing.client.android) no está instalado. + El teléfono se reinciará al modo recovery y realizará la limpieza. + El teléfono se reinciará al modo recovery y realizará la limpieza. + El teléfono se reinciará al modo recovery y realizará la copia de seguridad. + El teléfono se reinciará al modo recovery. + el archivo que usted intenta descargar es inaccesible o inválido. Por favor intente descargar luego, o contáctese con el mantenedor del repositorio. + Desea aplicar la actuaización? + Your mod seems to be different from the repository one. You\'ll be able to download only the full versions. + El archivo descriptor de la versión no fue encontrado + su ROM ya está actualizado a la última versión + No hay información disponible de la versión en el repositorio + Would you like to help the developer know more about the ROM name and version you\'ll download? You can anonymously send this data. If you want, you can find the setting under the preferences pane. + Su teléfono no es compatible con este repositorio. + Actualmente no hay repositorios disponibles + Precaución: Está intentando instalar una ROM que no ha sido diseñada para su modelo de teléfono. Aborte + Usted no tiene copias de seguridad en la actual carpeta de respaldos.. + La carpeta de respaldos aparentemente no existe. Revisar en sus ajustes. + Ocurrió un error mientras se descargaba el archivo. + El archivo JSON no fue encontrado + Ocurrió un error mientras se descargaba el archivo JSON + You haven\'t set the ROM repository from the settings menu. Clicking on Ok the Settings window will appear. + Desea realizar la limpieza de la partición SD-EXT también? + Está seguro de que desea restaurar esta copia de seguridad? + Al parecer el nombre de la ROM difiere de la que descargó. Desea realizar una limpieza, o una copia de seguridad y limpieza de los datos de usuario antes de actualizar? + No hay archivos en el directorio de descargas + This list is dynamically created via the anonymous data sent by other users. The author of the application doesn\'t decide which repositories are being displayed, nor is responsible for any of them. + diff --git a/res/values-es/strings.xml b/res/values-es/strings.xml new file mode 100644 index 0000000..662ad6a --- /dev/null +++ b/res/values-es/strings.xml @@ -0,0 +1,56 @@ + + + Lista de versiones + Preferencias + Lista de repositorios + Restoaurar una copia de seguridad + Archivos .zip descargados + Detalles de la versión + Comprobar actualizaciones + Archivos descargados + Ajustes... + Limpiar Dalvik caché + Eliminar aplicaciones y datos + Copia de seguridad + Respaldar ROM + Restaurar la copia de seguridad de la ROM + Modo recovery + Bootmenu + Respositorio del ROM + Otros ajustes + Enviar información anónima + Envíe anonimamente el nombre de la ROM instalada, versión y URL al autor de la aplicación. No se usará información personal. + "URL del repositorio (manual)" + Ingrese manualmente la URL del repositorio + Carpeta de respaldos + Cambiar carpeta de destino de los respaldos, Por ejemplo de clockworkmod/backup a /sdcard/clockworkmod/backup + "URL del repositorio (Código QR)" + "Ingresar la URL del repositorio a través del Escáner de barras (Debe estar instalado)" + Una lista de ROMs disponibles y complementos + Realizado + Cancelar + Si + No + Limpiar + Respaldado + Actualización + Informaciones + Ajustes + Salir + Versión + Descriptor no encontrado + Está seguro de querer ingresarlo como repositorio? + Alerta + Importante + Eliminar la copia de seguridad + Eliminar el archivo + Realizar copia de sgeuridad y limpiar + Copia de seguridad solamente + Instalar + Cargando, porfavor espere + Lista de cambios : + + Lista de versiones de ROM + Comenzar Descarga + Descargando + diff --git a/res/values-fr/messages.xml b/res/values-fr/messages.xml new file mode 100644 index 0000000..d8124b2 --- /dev/null +++ b/res/values-fr/messages.xml @@ -0,0 +1,32 @@ + + + Appui long pour afficher le changelog + L\'url du serveur de ROM a été modifiée + Le serveur de ROM n\'est pas disponible. Vérifiez votre connexion ou réessayer ultérieurement. + Il semble que Barcode Scanner (com.google.zxing.client.android) n\'est pas installé. + L\'appareil va redémarrer en mode recovery et va vider le cache dalvik. + L\'appareil va redémarrer en mode recovery et va effacer les données (wipe data/app). + L\'appareil va redémarrer en mode recovery pour effectuer la sauvegarde. + L\'appareil va maintenant redémarrer en mode recovery. + Le fichier que vous souhaitez télécharger n\'est pas disponible actuellement. Veuillez réessayer ultérieurement. + Voulez-vous appliquer la mise à jour maintenant ? + Votre ROM semble être différente de celle disponible sur le serveur. Vous pouvez la télécharger mais il est recommandé d\'effacer les données avant l\'installation. + La description de cette version n\'a pas été trouvée. + Vous utilisez la dernière mise à jour disponible. + Il n\'y a pas de versions disponibles sur le serveur + Envoyer les informations (nom, url et version) des ROMs téléchargées ?\n\nLes données envoyées sont anonymes mais permettent de comptabiliser les téléchargements. + Votre appareil n\'est pas compatible avec ce serveur. + Il n\'y a pas de serveur disponible. + Attention: vous essayez d\'installer une ROM qui n\'est pas conçue pour votre appareil. Annulation. + Il n\'y a aucune sauvegarde dans le répertoire spécifié. + Le répertoire de sauvegarde ne semble pas exister. Vérifiez vos paramètres. + Erreur lors du téléchargement du fichier. + Fichier JSON non trouvé + Impossible de télécharger le fichier JSON + Vous n\'avez pas défini le serveur de ROM dans les paramètres. Validez pour le paramétrer... + Voulez-vous effacer également la partition SD-EXT ? + Confirmez-vous la restauration de cette sauvegarde ? + Il semble que le nom de votre ROM soit différente de celle téléchargée. Il est nécessaire d\'effacer vos données utilisateur (wipe data), souhaitez vous sauvegarder avant de les effacer ? + Il n\'y a aucun fichier dans le répertoire de téléchargement + Cette liste est fabriquée automatiquement à partir des données envoyées par les utilisateurs. L\'auteur de cette application n\'est pas responsable du contenu de ceux-ci. + diff --git a/res/values-fr/strings.xml b/res/values-fr/strings.xml new file mode 100644 index 0000000..d352253 --- /dev/null +++ b/res/values-fr/strings.xml @@ -0,0 +1,56 @@ + + + Liste des versions + Paramètres... + Liste des serveurs + Voir les sauvegardes + Fichiers zip téléchargés + Détails du paquet + Rechercher mises à jour + Fichiers téléchargés + Paramètres... + Vider cache dalvik + Effacer appli. et données + Sauvegarder + Effectuer une sauvegarde + Restaurer une sauvegarde + Mode Recovery + Bootmenu + Serveur de ROM (Repository) + URL du serveur + Saisir l\'URL du serveur de ROMs + URL du serveur (QR code) + Scanner une url QR Code avec Barcode Scanner (doit être installé) + Liste des ROMs et addons disponibles + Répertoire Backup + Chemin sur la carte SD, par ex. clockworkmod/backup pour /sdcard/clockworkmod/backup + Autres paramètres + Statistiques anonymes + Envoyer anonymement les versions des ROMs installées. Vos données personnelles ne sont pas utilisées. + OK + Annuler + Oui + Non + Wipe + Recovery + Update + A Propos... + Paramètres + Quitter + Version + Descriptor not found + Are you sure you want to set this as repository? + Alerte + Important + Supprimer la sauvegarde + Supprimer le fichier + Sauvegarde et Effacer + Sauvegarde et Installer + Installer + Chargement, veuillez patienter... + Nouveautés : + + Liste des ROMs + Télécharger + Téléchargement + diff --git a/res/values-it/strings.xml b/res/values-it/strings.xml index db34936..fc9d7ad 100644 --- a/res/values-it/strings.xml +++ b/res/values-it/strings.xml @@ -1,15 +1,13 @@ - ROM Updater Lista delle versioni - Tipi di aggiornamento disponibili Preferenze Lista di repository Ripristina un backup File zip scaricati Controlla per aggiornamenti File scaricati - Impostazioni + Impostazioni... Svuota cache Cancella i dati Backup @@ -26,7 +24,7 @@ Nella SD card, ad esempio clockworkmod/backup per /sdcard/clockworkmod/backup Respository URL (codice QR) Imposta l\'URL tramite Barcode Scanner (dev\'essere installato) - Una lista di ROM, creata grazie ai dati anonimi. + Una lista di ROM e addons. OK Annulla @@ -35,6 +33,7 @@ Recovery Installa Informazioni + Impostazioni Esci Versione Descrittore non trovato diff --git a/res/values-zh-rCN/strings.xml b/res/values-zh-rCN/strings.xml index 77da8bf..cf2c4da 100644 --- a/res/values-zh-rCN/strings.xml +++ b/res/values-zh-rCN/strings.xml @@ -1,8 +1,6 @@ - ROM更新器 版本列表 - 可用更新类别 选项 更新服务器列表 恢复备份 @@ -26,7 +24,7 @@ SD卡目录,比如设置clockworkmod/backup表示设置备份目录为 /sdcard/clockworkmod/backup 设置更新服务器(二维码) 通过二维码识别软件获得更新服务器URL,比如(Barcode Scanner) - ROM更新列表,通过匿名数据创建 + ROM更新列表 确定 取消 @@ -35,6 +33,7 @@ 恢复 更新 信息 + 设置 退出 版本 未发现描述 diff --git a/res/values/messages.xml b/res/values/messages.xml index 6a1747f..b723050 100644 --- a/res/values/messages.xml +++ b/res/values/messages.xml @@ -1,31 +1,32 @@ - Long press to view the changelog - The ROM repository URL has been changed - The ROM repository is currently unreachable. Please check it, or try again later. - It seems that Barcode Scanner (com.google.zxing.client.android) is not installed. - The phone will reboot into recovery mode and it will perform the wipe. - The phone will reboot into recovery mode and it will perform the wipe. - The phone will reboot into recovery mode and it will perform the backup. - The phone will reboot into recovery mode. - The file you\'re trying to download is unreachable or unavailable. Please try again later, or contact the repository maintainer. - Do you want to apply the update right now? - Your mod seems to be different from the repository one. You\'ll be able to download only the full versions. - The version descriptor file has not been found. - Your ROM is already updated to the latest version. - Would you like to help the developer know more about the ROM name and version you\'ll download? You can anonymously send this data. If you want, you can find the setting under the preferences pane. - Your phone is not compatible with this repository. - There are actually no available repositories. Share yours sending anonymous data! - Attention: you\'re attempting to install a ROM not designed for your phone model. Abort. - You have no backups in the current backup folder. - The backup folder doesn\'t appear to exist. Check it in your settings. - There was an error downloading the file. - The JSON file was not found - There was an error downloading the JSON file - You haven\'t set the ROM repository from the settings menu. Clicking on Ok the Settings window will appear. - Do you want to wipe the SD-EXT partition too? - Are you sure you want to restore this backup? - It seems that your ROM name differs from the one you\'ve downloaded. Do you want to wipe, or backup and wipe the user data before updating? - There are no files in the download directory - This list is dynamically created via the anonymous data sent by other users. The author of the application doesn\'t decide which repositories are being displayed, nor is responsible for any of them. - + Mantenha pressionado para ver o registro + URL do repositório foi modificada + Repositório não disponível. Verifique novamente ou tente depois. + Barcode Scanner (com.google.zxing.client.android) não está instalado. + Aparelho será reinicado em Modo Recuperação para limpeza do cache. + Aparelho será reinicado em Modo Recuperação para exclusão do dados. + Aparelho será reinicado em Modo Recuperação para realizar backup. + Aparelho será reinicado em Modo Recuperação. + Arquivo não disponível para baixar. Tente novamente ou procure o mantenedor do repositório. + Deseja aplicar as atualizações agora? + Sua ROM é diferente da ROM escolhida. Você poderá baixar somente versões inteiras. + A versão não foi encontrada. + Você possui a última versão instalada. + Não existem informações da versão no repositório + Ajude o desenvolvedor a conhecer o nome e a versão que deseja baixar. Envie os dados anonimamente. Utilize os ajustes do menu das preferências. + Seu aparelho não é compatível com o repositório. + Sem repositórios disponíveis. Compartilhe seus dados anonimamente! + Atenção: você está tentando instalar uma versão não desenvolvida para o seu aparelho. Abortado. + Não existem arquivos salvos na pasta de backup. + A pasta de backup não existe. Confira os ajustes para backup. + Erro ao baixar o arquivo. + O arquivo JSON não foi encontrado + Erro ao baixar o arquivo JSON + Você não escolheu um repositório de ROM. Clicando em OK o menu de ajustes será exibido. + Você deseja formatar a partição SD-EXT também? + Tem certeza que deseja recuperar este backup? + O nome da ROM é diferente da ROM baixada. Você deseja fazer wipe, ou fazer backup e depois wipe antes de atualizar? + Não existem arquivos na pasta de download + Esta lista é criada dinamicamente pelos dados anônimos enviados pelos usuários. O autor do aplicativo não decide quais repositórios serão disponibilizados e não é responsável por isso. + \ No newline at end of file diff --git a/res/values/strings.xml b/res/values/strings.xml index 0022a3a..742842f 100644 --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -1,49 +1,64 @@ - ROM Updater - Versions list - Available update types - Preferences - Repositories list - Restore a backup - Downloaded zip files - Check for updates - Downloaded files - Settings - Wipe cache - Wipe data + ROM Updater + + Lista de versões + Preferências + Lista de repositórios + Restaurar um backup + Arquivos zipados baixados + Detalhes do pacote + Procurar atualizações + Arquivos baixados + Ajustes... + Limpar dalvik cache + Excluir aplicativos e dados Backup - Backup the ROM - Restore a ROM backup - Recovery mode - ROM Repository - Other settings - Send anonymous data - Anonymously send the ROM name, version and URL to the app author. No personal data will be used. - Repository URL (manual) - Manually insert the repository URL in a textbox - Backup folder - SDCard folder, i.e. clockworkmod/backup for /sdcard/clockworkmod/backup - Respository URL (QR code) - Set the repository URL via Barcode Scanner (must be installed) - A list of ROMs, built with anonymous data + Backup da ROM + Restaurar backup da ROM + Modo Recuperação + Bootmenu + Repositório da ROM + Outros ajustes + Enviar dados anonimamente + Enviar anonimamente ao autor do aplicativo: o nome da ROM, a versão e a URL. Dados pessoais não serão enviados. + URL do repositório (manual) + Inserir manualmente, na caixa de texto, uma URL de repositório + Pasta para backup + Pasta do SDCard, ex. clockworkmod/backup para /sdcard/clockworkmod/backup + URL do respositório (QR code) + Usar URL de repositório via Barcode Scanner (necessária instalação) + Lista de ROMs disponíveis OK - Cancel - Yes - No - Wipe - Recovery - Update - Informations - Exit - Version - Descriptor not found - Are you sure you want to set this as repository? - Alert - Important - Delete the backup - Delete the file - Backup and wipe - Backup only - Loading, please wait... + Cancelar + Sim + Não + Excluir + Recuperar + Atualizar + Informações + Ajustes + Sair + Versão + Descriptor não encontrado + Você deseja usar este repositório? + Atenção + Importante + Deletar backup + Deletar arquivo + Backup e wipe + Backup somente + Instalar + Carregando, aguarde... + Registro : + + Lista de versão(ões) de ROM + Iniciar Download + Baixando + + + + + http://www.elegosproject.org/android/upload.php + http://www.elegosproject.org/android/repositories.php diff --git a/res/xml/preferences.xml b/res/xml/preferences.xml index 5d303f7..b03fb13 100644 --- a/res/xml/preferences.xml +++ b/res/xml/preferences.xml @@ -7,7 +7,7 @@ android:key="repository_url" android:title="@string/repository_url_manual" android:summary="@string/repository_url_manual_summary" - android:defaultValue="" + android:defaultValue="@string/reposerver_url" /> 0) { + try { + conn.connect(); + } catch (SocketTimeoutException te) { + conn.disconnect(); + } + retries--; + } + + String setcookie=""; + switch (conn.getResponseCode()) { + case HttpURLConnection.HTTP_OK: + Log.d(TAG, "HTTP OK"); + conn.getInputStream().close(); + conn.disconnect(); + break; + case HttpURLConnection.HTTP_MOVED_TEMP: + case HttpURLConnection.HTTP_MOVED_PERM: + referer=theUrl; + String loc = conn.getHeaderField("Location"); + conn.getInputStream().close(); + Log.d(TAG, "HTTP redirect to " + loc); + try { + setcookie = conn.getHeaderField("Set-Cookie"); + } catch (Exception e) {} + if (TextUtils.isEmpty(cookies) && !TextUtils.isEmpty(setcookie)) { + if (setcookie.contains("expires")) { + setcookie = setcookie.substring(0, setcookie.indexOf("expires")); + setcookie = setcookie.substring(0, setcookie.lastIndexOf(";")); + } + cookies = setcookie; + Log.i(TAG, "Cookies received " + cookies); + } + conn.getInputStream().close(); + return checkHttpFile(loc); + //throw new RedirectRequiredException(httpConn); + default: + referer=theUrl; + try { + setcookie = conn.getHeaderField("Set-Cookie"); + } catch (Exception e) {} + if (TextUtils.isEmpty(cookies) && !TextUtils.isEmpty(setcookie)) { + if (setcookie.contains("expires")) { + setcookie = setcookie.substring(0, setcookie.indexOf("expires")); + setcookie = setcookie.substring(0, setcookie.lastIndexOf(";")); + } + cookies = setcookie; + Log.i(TAG, "Cookies received " + cookies); + conn.getInputStream().close(); + return checkHttpFile(theUrl); + } + Log.w(TAG, "HTTP Response code: "+conn.getResponseCode()); + Map> hf = conn.getHeaderFields(); + for (String key : hf.keySet()) + Log.d(TAG, key + ": " + conn.getHeaderField(key)); + + int size = conn.getContentLength(); + int index = 0; + int current = 0; + File file = new File("/sdcard/404_debug.txt"); + try { + FileOutputStream output = new FileOutputStream(file); + InputStream input = conn.getInputStream(); + BufferedInputStream buffer = new BufferedInputStream(input); + byte[] bBuffer = new byte[4096]; + + while((current = buffer.read(bBuffer)) != -1) { + try { + output.write(bBuffer, 0, current); + } catch (IOException e) { + e.printStackTrace(); + } + index += current; + } + output.close(); + } catch (Exception e) { + e.printStackTrace(); + return false; + } + + conn.disconnect(); + Log.e(TAG, "check content of /sdcard/404_debug.txt"); + return false; + } + } catch (IOException e) { + Log.e(TAG,e.toString()); + e.printStackTrace(); + return false; + } + return true; + } + + class CheckHttpFile extends AsyncTask + { + public boolean success=false; + @Override + protected Boolean doInBackground(String... params) { + String urlToCheck = params[0]; + success = DownloadManager.checkHttpFile(urlToCheck); + Log.d(TAG, "CheckHttpFile: "+success); + return success; + } + } + + public boolean sendAnonymousData(Context ctx) { + + // http://www.elegosproject.org/android/upload.php + + String link = ctx.getResources().getString(R.string.statserver_url); + String data; + + Log.d(TAG, "Stat report url set to " + link); + + SharedData shared = SharedData.getInstance(); + String romName = shared.getRepositoryROMName(); + String romVersion = shared.getDownloadVersion(); + String romPhone = shared.getRepositoryModel(); + String romRepository = shared.getRepositoryUrl(); + + if(romName.equals("") || + romVersion.equals("") || + romPhone.equals("") || + romRepository.equals("")) { + Log.e(TAG,"Internal error - missing system variables."); + return false; + } + + cookies = ""; + + CheckHttpFile check = new CheckHttpFile(); + try { + check.execute(link); + check.get(); + } catch (Exception e) { + return false; + } + + if (!check.success) return false; + try { + data = URLEncoder.encode("phone", "UTF-8") + "=" + URLEncoder.encode(romPhone, "UTF-8"); + data += "&"+URLEncoder.encode("rom_name", "UTF-8") + "=" + URLEncoder.encode(romName, "UTF-8"); + data += "&"+URLEncoder.encode("rom_version", "UTF-8") + "=" + URLEncoder.encode(romVersion,"UTF-8"); + data += "&"+URLEncoder.encode("rom_repository", "UTF-8") + "=" + URLEncoder.encode(romRepository,"UTF-8"); + + URL url = new URL(link); + HttpURLConnection conn; + if (url.getProtocol().toLowerCase().equals("https")) { + trustAllHosts(); + HttpsURLConnection https = (HttpsURLConnection) url.openConnection(); + https.setHostnameVerifier(DO_NOT_VERIFY); + conn = https; + } else { + conn = (HttpURLConnection) url.openConnection(); + } + conn.setFollowRedirects(true); + conn.setConnectTimeout(3000); + conn.setReadTimeout(3000); + conn.setRequestMethod("POST"); + conn.setRequestProperty("User-Agent", "ROMUpdater"); + if (!TextUtils.isEmpty(cookies)) { + conn.addRequestProperty("Cookie", cookies); + } + conn.setDoOutput(true); + PrintWriter out = new PrintWriter(conn.getOutputStream()); + out.println(data); + out.close(); + + int status = Integer.parseInt(conn.getHeaderField("ROMUpdater-status")); + if(status == 1) + return true; + + Log.e(TAG, "It was impossible to send data to the statistics server ("+conn.getHeaderField("ROMUpdater-error")+")."); + return false; + + } catch (Exception e) { + Log.e(TAG, "It was impossible to send data to the statistics server."); + Log.e(TAG, "Error: "+e.toString()); + return false; + } + } } diff --git a/src/org/elegosproject/romupdater/Downloads.java b/src/org/elegosproject/romupdater/Downloads.java index bef689f..8b1096a 100644 --- a/src/org/elegosproject/romupdater/Downloads.java +++ b/src/org/elegosproject/romupdater/Downloads.java @@ -14,6 +14,8 @@ import android.widget.ListView; public class Downloads extends ROMSuperActivity { + private static final String TAG = "RomUpdater[Downloads]"; + private ListView listOfDownloads; @Override diff --git a/src/org/elegosproject/romupdater/JSONParser.java b/src/org/elegosproject/romupdater/JSONParser.java index 4d48071..ad46590 100644 --- a/src/org/elegosproject/romupdater/JSONParser.java +++ b/src/org/elegosproject/romupdater/JSONParser.java @@ -21,6 +21,8 @@ import java.io.InputStreamReader; import java.io.Reader; import java.net.URI; +import java.util.ArrayList; +import java.util.List; import java.util.Vector; import org.apache.http.HttpResponse; @@ -37,21 +39,26 @@ import com.google.gson.Gson; +import android.os.NetworkOnMainThreadException; +import android.os.StrictMode; +import android.os.StrictMode.ThreadPolicy.Builder; +import android.text.TextUtils; import android.util.Log; public class JSONParser { - private static final String TAG = "ROM Updater (JSONParser.class)"; + private static final String TAG = "RomUpdater[JSONParser]"; public String modName = ""; public AvailableVersions parsedAvailableVersions; public ROMVersions parsedVersions; public Boolean failed = false; - + public static boolean checkRepository(String repository_url) { - if(!repository_url.startsWith("http://")) + if(!repository_url.contains("://")) repository_url = "http://"+repository_url; - if(!repository_url.endsWith("/")) - repository_url += "/"; - repository_url += "main.json"; + if(!repository_url.contains("?") && !repository_url.contains("json")) { + if (!repository_url.endsWith("/")) repository_url += "/"; + repository_url += "main.json"; + } return DownloadManager.checkHttpFile(repository_url); } @@ -74,6 +81,7 @@ public static InputStream getJSONData(String url) throws Exception { } public String getROMVersionUri(String version) { + for(ROMVersion rv : parsedVersions.getVersions()) { if(rv.getVersion().equals(version)) return rv.getUri(); @@ -81,38 +89,61 @@ public String getROMVersionUri(String version) { return ""; } - public Vector getROMVersions(){ + public Vector getROMVersions() { failed = false; - + Vector versions = new Vector(); - Gson gson = new Gson(); - Reader r; + Gson gson = new Gson(); + + StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder() + .permitNetwork().build(); + StrictMode.setThreadPolicy(policy); + try { + parsedVersions = new ROMVersions(); + SharedData shared = SharedData.getInstance(); - r = new InputStreamReader(shared.getInputStreamData()); - - parsedVersions = new ROMVersions(); - parsedVersions = gson.fromJson(r, ROMVersions.class); - - shared.setRepositoryROMName(parsedVersions.getName()); - shared.setRespositoryModel(parsedVersions.getPhoneModel()); - } catch(Exception e) { - e.printStackTrace(); - failed = true; - return new Vector(); - } - - modName = parsedVersions.getName(); - for(ROMVersion rv : parsedVersions.getVersions()){ - Log.i(TAG, "Version: " + rv.getVersion() + " - " + rv.getUri()); - Log.i(TAG, rv.getChangelog()); - versions.add(rv); - rv.getUri(); - } - - return versions; - } - + Reader r = new InputStreamReader(shared.getInputStreamData()); + + try { + parsedVersions = gson.fromJson(r, ROMVersions.class); + } catch (NetworkOnMainThreadException mte) { + Log.w(TAG, "Strict mode is activated, " + mte); + failed = true; + } + + if (!failed) { + shared.setRepositoryROMName(parsedVersions.getName()); + shared.setRespositoryModel(parsedVersions.getPhoneModel()); + } + + } catch(Exception e) { + e.printStackTrace(); + failed = true; + } + + if (failed) { + Log.w(TAG, "Failed to parse ROMVersions !"); + return versions; + } + + modName = parsedVersions.getName(); + if (TextUtils.isEmpty(modName)) { + failed = true; + Log.e(TAG, "Failed to parse ROMVersions ! (no name)"); + return versions; + } + + List lst = parsedVersions.getVersions(); + for(ROMVersion rv : lst) { + Log.i(TAG, "Version: " + rv.getVersion() + " - " + rv.getUri()); + Log.i(TAG, rv.getChangelog()); + versions.add(rv); + rv.getUri(); + } + return versions; + } + public Vector getAvailableVersions() { failed = false; @@ -128,14 +159,20 @@ public Vector getAvailableVersions() { } catch (Exception e) { e.printStackTrace(); failed = true; - return new Vector(); } - for(AvailableVersion av : parsedAvailableVersions.getAvailableVersions()) { + if (failed) { + failed = true; + Log.w(TAG, "No available version !"); + return new Vector(); + } + + List lst = parsedAvailableVersions.getAvailableVersions(); + for(AvailableVersion av : lst) { Log.i(TAG, "Version: " + av.getVersion() + " ("+av.getUri()+")"); versions.add(av); } - + return versions; } @@ -160,7 +197,7 @@ public RepoList[] getRepositoriesFromJSON() { public String getUrlForVersion(String version) { for(AvailableVersion av : parsedAvailableVersions.getAvailableVersions()) { - if(Integer.parseInt(av.getVersion()) == Integer.parseInt(version)) + if(av.getVersion().equals(version)) return av.getUri(); } return ""; diff --git a/src/org/elegosproject/romupdater/Preferences.java b/src/org/elegosproject/romupdater/Preferences.java index b9c6280..3d26bfc 100644 --- a/src/org/elegosproject/romupdater/Preferences.java +++ b/src/org/elegosproject/romupdater/Preferences.java @@ -35,81 +35,81 @@ import android.widget.Toast; public class Preferences extends PreferenceActivity { - private SharedPreferences preferences; - private static final String TAG = "ROM Updater (Preferences.class)"; - - @Override - public void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - addPreferencesFromResource(R.xml.preferences); - - preferences = PreferenceManager.getDefaultSharedPreferences(this); - - Preference barcode = findPreference("repository_url_qr"); - Preference romList = findPreference("repository_list"); - - romList.setOnPreferenceClickListener(new OnPreferenceClickListener() { - @Override - public boolean onPreferenceClick(Preference preference) { - Intent repoList = new Intent(Preferences.this, RepositoriesList.class); - startActivity(repoList); - return false; - } - }); - - barcode.setOnPreferenceClickListener(new OnPreferenceClickListener() { - public boolean onPreferenceClick(Preference preference) { - Intent scanner = new Intent("com.google.zxing.client.android.SCAN"); - scanner.putExtra("SCAN_MODE","QR_CODE_MODE"); - try { - startActivityForResult(scanner, 0); - } catch (Exception e) { - Log.e(TAG,e.toString()); - AlertDialog.Builder dialog = new AlertDialog.Builder(Preferences.this); - dialog.setMessage(getString(R.string.barcode_scanner_not_found)) - .setCancelable(false) - .setPositiveButton(getString(R.string.OK), new DialogInterface.OnClickListener() { - public void onClick(DialogInterface dialog, int which) { - dialog.dismiss(); - } - }); - AlertDialog alert = dialog.create(); - alert.show(); - } - - return false; - } - }); - } - - @Override - public void onActivityResult(int requestCode, int resultCode, Intent intent) { - if(requestCode == 0) { - try { - String url = intent.getStringExtra("SCAN_RESULT"); - if(!url.endsWith("/")) - url += "/"; - Log.i(TAG,"Repository URL found: "+url); - - Editor preferencesEditor = preferences.edit(); - preferencesEditor.putString("repository_url", url); - preferencesEditor.commit(); - - Toast t = Toast.makeText(this, getString(R.string.repository_changed_toast)+" ("+url+")",Toast.LENGTH_LONG); - t.show(); - } catch (Exception e) { - Log.e(TAG,e.toString()); - } - } - } - - @Override + private SharedPreferences preferences; + private static final String TAG = "RomUpdater[Preferences]"; + + @Override + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + addPreferencesFromResource(R.xml.preferences); + + preferences = PreferenceManager.getDefaultSharedPreferences(this); + + Preference barcode = findPreference("repository_url_qr"); + Preference romList = findPreference("repository_list"); + + romList.setOnPreferenceClickListener(new OnPreferenceClickListener() { + @Override + public boolean onPreferenceClick(Preference preference) { + Intent repoList = new Intent(Preferences.this, RepositoriesList.class); + startActivity(repoList); + return false; + } + }); + + barcode.setOnPreferenceClickListener(new OnPreferenceClickListener() { + public boolean onPreferenceClick(Preference preference) { + Intent scanner = new Intent("com.google.zxing.client.android.SCAN"); + scanner.putExtra("SCAN_MODE","QR_CODE_MODE"); + try { + startActivityForResult(scanner, 0); + } catch (Exception e) { + Log.e(TAG,e.toString()); + AlertDialog.Builder dialog = new AlertDialog.Builder(Preferences.this); + dialog.setMessage(getString(R.string.barcode_scanner_not_found)) + .setCancelable(false) + .setPositiveButton(getString(R.string.OK), new DialogInterface.OnClickListener() { + public void onClick(DialogInterface dialog, int which) { + dialog.dismiss(); + } + }); + AlertDialog alert = dialog.create(); + alert.show(); + } + + return false; + } + }); + } + + @Override + public void onActivityResult(int requestCode, int resultCode, Intent intent) { + if(requestCode == 0) { + try { + String url = intent.getStringExtra("SCAN_RESULT"); + if(!url.endsWith("/")) + url += "/"; + Log.i(TAG,"Repository URL found: "+url); + + Editor preferencesEditor = preferences.edit(); + preferencesEditor.putString("repository_url", url); + preferencesEditor.commit(); + + Toast t = Toast.makeText(this, getString(R.string.repository_changed_toast)+" ("+url+")",Toast.LENGTH_LONG); + t.show(); + } catch (Exception e) { + Log.e(TAG,e.toString()); + } + } + } + + @Override public boolean onCreateOptionsMenu(Menu menu) { MenuInflater inflater = getMenuInflater(); inflater.inflate(R.menu.menu, menu); return true; } - + @Override public boolean onOptionsItemSelected(MenuItem item) { // Handle item selection @@ -118,23 +118,23 @@ public boolean onOptionsItemSelected(MenuItem item) { finish(); return true; case R.id.menu_info: - PackageManager pm = getPackageManager(); - String version = ""; - try { - version = pm.getPackageInfo("org.elegosproject.romupdater", 0).versionName; - } catch (Exception e) { - e.printStackTrace(); - } + PackageManager pm = getPackageManager(); + String version = ""; + try { + version = pm.getPackageInfo("org.elegosproject.romupdater", 0).versionName; + } catch (Exception e) { + e.printStackTrace(); + } AlertDialog.Builder builder = new AlertDialog.Builder(Preferences.this); - builder.setIcon(R.drawable.ic_menu_info) - .setTitle(getString(R.string.app_name)+" v."+version) - .setMessage(SharedData.ABOUT_LICENCE+"\n\nPlease donate via PayPal to giacomo.furlan@fastwebnet.it.\nThanks\n\nGiacomo 'elegos' Furlan") - .setCancelable(false) - .setPositiveButton(getString(R.string.OK), new DialogInterface.OnClickListener() { - public void onClick(DialogInterface dialog, int which) { - dialog.dismiss(); - } - }); + builder.setIcon(android.R.drawable.ic_menu_help) + .setTitle(getString(R.string.app_name)+"\nv"+version) + .setMessage("\n" + SharedData.ABOUT_LICENCE) + .setCancelable(false) + .setPositiveButton(getString(R.string.OK), new DialogInterface.OnClickListener() { + public void onClick(DialogInterface dialog, int which) { + dialog.dismiss(); + } + }); AlertDialog dialog = builder.create(); dialog.show(); return true; diff --git a/src/org/elegosproject/romupdater/ROMSuperActivity.java b/src/org/elegosproject/romupdater/ROMSuperActivity.java index 3cad193..331c909 100644 --- a/src/org/elegosproject/romupdater/ROMSuperActivity.java +++ b/src/org/elegosproject/romupdater/ROMSuperActivity.java @@ -9,6 +9,7 @@ import java.net.URI; import java.net.URL; import java.net.URLConnection; +import java.lang.reflect.Field; import org.apache.http.HttpResponse; import org.apache.http.client.methods.HttpGet; @@ -20,7 +21,10 @@ import android.app.Activity; import android.app.AlertDialog; import android.app.ProgressDialog; +import android.content.Context; import android.content.DialogInterface; +import android.content.Intent; +import android.content.pm.ApplicationInfo; import android.content.pm.PackageManager; import android.os.AsyncTask; import android.os.Bundle; @@ -28,288 +32,315 @@ import android.view.MenuInflater; import android.view.MenuItem; +import android.util.Log; + public class ROMSuperActivity extends Activity { - private ProgressDialog progress; - protected AlertDialog.Builder alert; - public static final String DOWNLOAD_DIRECTORY = "/sdcard/romupdater/"; - - @Override - protected void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - progress = new ProgressDialog(this); - alert = new AlertDialog.Builder(this); - } - - @Override - public boolean onCreateOptionsMenu(Menu menu) { - MenuInflater inflater = getMenuInflater(); - inflater.inflate(R.menu.menu, menu); - return true; - } - + private final boolean DBG = false; + + private ProgressDialog progress; + protected AlertDialog.Builder alert; + public static String DOWNLOAD_DIRECTORY = "/sdcard/romupdater/"; + + public static String PackageName; + public static String Namespace; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + progress = new ProgressDialog(this); + alert = new AlertDialog.Builder(this); + PackageName = getPackageName(); + Namespace = ""; + } + + @Override + public boolean onCreateOptionsMenu(Menu menu) { + MenuInflater inflater = getMenuInflater(); + inflater.inflate(R.menu.menu, menu); + return true; + } + @Override public boolean onOptionsItemSelected(MenuItem item) { + // Handle item selection switch (item.getItemId()) { case R.id.menu_exit: finish(); return true; + case R.id.menu_settings: + Intent p = new Intent(this, Preferences.class); + startActivity(p); + return true; case R.id.menu_info: - PackageManager pm = getPackageManager(); - String version = ""; - try { - version = pm.getPackageInfo("org.elegosproject.romupdater", 0).versionName; - } catch (Exception e) { - e.printStackTrace(); - } + PackageManager pm = getPackageManager(); + String version = ""; + try { + version = pm.getPackageInfo(PackageName, 0).versionName; + } catch (Exception e) { + e.printStackTrace(); + } + AlertDialog.Builder builder = new AlertDialog.Builder(ROMSuperActivity.this); - builder.setIcon(R.drawable.ic_menu_info) - .setTitle("ROM Updater v."+version) - .setMessage(SharedData.ABOUT_LICENCE+"\n\nPlease donate via PayPal to giacomo.furlan@fastwebnet.it.\nThanks\n\nGiacomo 'elegos' Furlan") - .setCancelable(false) - .setPositiveButton(getString(R.string.OK), new DialogInterface.OnClickListener() { - public void onClick(DialogInterface dialog, int which) { - dialog.dismiss(); - } - }); + builder.setIcon(android.R.drawable.ic_menu_help) + .setTitle(getString(R.string.app_name) + "\nv"+version) + .setMessage("\n" + SharedData.ABOUT_LICENCE) + .setCancelable(false) + .setPositiveButton(getString(R.string.OK), new DialogInterface.OnClickListener() { + public void onClick(DialogInterface dialog, int which) { + dialog.dismiss(); + } + }); + AlertDialog dialog = builder.create(); dialog.show(); return true; + default: return super.onOptionsItemSelected(item); } } - + class DownloadFile extends AsyncTask { - @Override - protected void onPreExecute() { - // initialize the progress dialog - progress = new ProgressDialog(ROMSuperActivity.this); - super.onPreExecute(); - } - - @Override - protected Boolean doInBackground(String... params) { - String toDownload = params[0]; - String destination = params[1]; - - // creates the base folder, if it doesn't exist - try { - File dir = new File(destination.substring(0,destination.lastIndexOf("/"))); - dir.mkdirs(); - } catch (Exception e) { - e.printStackTrace(); - } - - String fileName = toDownload.substring(toDownload.lastIndexOf("/")+1); - - // initialize the progress dialog - progress.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL); - progress.setMessage("Downloading "+fileName+"..."); - progress.setCancelable(false); - progress.setMax(100); - publishProgress(0); - - - // File not reachable - if(!DownloadManager.checkHttpFile(toDownload)) { - alert.setMessage(getString(R.string.repository_file_not_found)) - .setCancelable(false) - .setPositiveButton(getString(R.string.OK), new DialogInterface.OnClickListener() { - @Override - public void onClick(DialogInterface dialog, int which) { - dialog.dismiss(); - finish(); - return; - } - }); - publishProgress(-1); - return false; - } - - try { - // initialize some timeouts - HttpParams httpParameters = new BasicHttpParams(); - HttpConnectionParams.setConnectionTimeout(httpParameters,3000); - - // create the connection - URL url = new URL(toDownload); - URLConnection connection = url.openConnection(); - HttpURLConnection httpConnection = (HttpURLConnection) connection; - - // connection accepted - if(httpConnection.getResponseCode() == HttpURLConnection.HTTP_OK) { - try { - File file = new File(destination); - // delete the file if exists - file.delete(); - } catch (Exception e) { - // nothing - } - - int size = connection.getContentLength(); - - int index = 0; - int current = 0; - - try { - FileOutputStream output = new FileOutputStream(destination, false); - InputStream input = connection.getInputStream(); - BufferedInputStream buffer = new BufferedInputStream(input); - byte[] bBuffer = new byte[10240]; - - while((current = buffer.read(bBuffer)) != -1) { - try { - output.write(bBuffer, 0, current); - } catch (IOException e) { - e.printStackTrace(); - } - index += current; - publishProgress(index/(size/100)); - } - output.close(); - } catch (Exception e) { - e.printStackTrace(); - return false; - } - - progress.dismiss(); - return true; - } - - // connection refused - return false; - } catch (IOException e) { - e.printStackTrace(); - return false; - } - } - - @Override - protected void onProgressUpdate(Integer... iProgress) { - switch(iProgress[0]) { - // an error occurred, popup an error - case -1: - alert.create().show(); - progress.dismiss(); - break; - // initialize the progress bar to 0 - case 0: - progress.show(); - progress.setProgress(iProgress[0]); - break; - default: - progress.setProgress(iProgress[0]); - } - super.onProgressUpdate(iProgress); - } - - @Override - protected void onPostExecute(Boolean result) { - progress.dismiss(); - super.onPostExecute(result); - onDownloadComplete(result); - } - } - + @Override + protected void onPreExecute() { + // initialize the progress dialog + progress = new ProgressDialog(ROMSuperActivity.this); + super.onPreExecute(); + } + + @Override + protected Boolean doInBackground(String... params) { + String toDownload = params[0]; + String destination = params[1]; + + // creates the base folder, if it doesn't exist + try { + File dir = new File(destination.substring(0,destination.lastIndexOf("/"))); + dir.mkdirs(); + } catch (Exception e) { + e.printStackTrace(); + } + + String fileName = toDownload.substring(toDownload.lastIndexOf("/")+1); + + // for dynamic json, only show filename param + if (fileName.contains("f=")) { + fileName = fileName.substring(fileName.lastIndexOf("f=")+2); + } + + // initialize the progress dialog + progress.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL); + progress.setMessage(getString(R.string.downloading)+":\n" + fileName); + progress.setCancelable(false); + progress.setMax(100); + publishProgress(0); + + // File not reachable + if(!DownloadManager.checkHttpFile(toDownload)) { + alert.setMessage(getString(R.string.repository_file_not_found)) + .setCancelable(false) + .setPositiveButton(getString(R.string.OK), new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + dialog.dismiss(); + finish(); + return; + } + }); + publishProgress(-1); + return false; + } + + try { + // initialize some timeouts + HttpParams httpParameters = new BasicHttpParams(); + HttpConnectionParams.setConnectionTimeout(httpParameters,3000); + + // create the connection + URL url = new URL(toDownload); + URLConnection connection = url.openConnection(); + HttpURLConnection httpConnection = (HttpURLConnection) connection; + + // connection accepted + if(httpConnection.getResponseCode() == HttpURLConnection.HTTP_OK) { + try { + File file = new File(destination); + // delete the file if exists + file.delete(); + } catch (Exception e) { + // nothing + } + + int size = connection.getContentLength(); + + int index = 0; + int current = 0; + + try { + FileOutputStream output = new FileOutputStream(destination, false); + InputStream input = connection.getInputStream(); + BufferedInputStream buffer = new BufferedInputStream(input); + byte[] bBuffer = new byte[10240]; + + while((current = buffer.read(bBuffer)) != -1) { + try { + output.write(bBuffer, 0, current); + } catch (IOException e) { + e.printStackTrace(); + } + index += current; + publishProgress(index/(size/100)); + } + output.close(); + } catch (Exception e) { + e.printStackTrace(); + return false; + } + + progress.dismiss(); + return true; + } + + // connection refused + return false; + } catch (IOException e) { + e.printStackTrace(); + return false; + } + } + + @Override + protected void onProgressUpdate(Integer... iProgress) { + switch(iProgress[0]) { + // an error occurred, popup an error + case -1: + alert.create().show(); + progress.dismiss(); + break; + // initialize the progress bar to 0 + case 0: + progress.show(); + progress.setProgress(iProgress[0]); + break; + default: + progress.setProgress(iProgress[0]); + } + super.onProgressUpdate(iProgress); + } + + @Override + protected void onPostExecute(Boolean result) { + progress.dismiss(); + super.onPostExecute(result); + onDownloadComplete(result); + } + } // class DownloadFile + class DownloadJSON extends AsyncTask { - @Override - protected void onPreExecute() { - // initialize the progress dialog - progress = new ProgressDialog(ROMSuperActivity.this); - super.onPreExecute(); - } - - @Override - protected Boolean doInBackground(String... params) { - String url = params[0]; - - // initialize the progress dialog - progress.setProgressStyle(ProgressDialog.STYLE_SPINNER); - progress.setMessage(getString(R.string.loading)); - progress.setCancelable(false); - - // show the progress dialog - publishProgress(0); - - // File not reachable - if(!DownloadManager.checkHttpFile(url)) { - alert.setMessage(getString(R.string.error_json_not_found)) - .setCancelable(false) - .setPositiveButton(getString(R.string.OK), new DialogInterface.OnClickListener() { - @Override - public void onClick(DialogInterface dialog, int which) { - dialog.dismiss(); - finish(); - return; - } - }); - publishProgress(-1); - return false; - } - - // initialize local variables - HttpParams httpParameters = new BasicHttpParams(); - HttpConnectionParams.setConnectionTimeout(httpParameters,3000); - DefaultHttpClient httpClient = new DefaultHttpClient(); - URI uri; - InputStream data; - - try { - uri = new URI(url); - HttpGet method = new HttpGet(uri); - HttpResponse response = httpClient.execute(method); - data = response.getEntity().getContent(); - - SharedData sdata = SharedData.getInstance(); - sdata.setInputStreamData(data); - } catch (Exception e) { - alert.setMessage(getString(R.string.error_json_download)) - .setCancelable(false) - .setPositiveButton(getString(R.string.OK), new DialogInterface.OnClickListener() { - @Override - public void onClick(DialogInterface dialog, int which) { - dialog.dismiss(); - } - }); - publishProgress(-1); - e.printStackTrace(); - return false; - } - - publishProgress(100); - return true; - } - - @Override - protected void onProgressUpdate(Integer... iProgress) { - switch(iProgress[0]) { - // an error occurred, popup an error - case -1: - alert.create().show(); - progress.dismiss(); - break; - // initialize the progress bar to 0 - case 0: - progress.show(); - progress.setProgress(iProgress[0]); - break; - case 100: - progress.dismiss(); - break; - default: - progress.setProgress(iProgress[0]); - } - super.onProgressUpdate(iProgress); - } - - @Override - protected void onPostExecute(Boolean result) { - onJSONDataDownloaded(result); - super.onPostExecute(result); - } - } - + + @Override + protected void onPreExecute() { + // initialize the progress dialog + progress = new ProgressDialog(ROMSuperActivity.this); + super.onPreExecute(); + } + + @Override + protected Boolean doInBackground(String... params) { + String url = params[0]; + + // initialize the progress dialog + progress.setProgressStyle(ProgressDialog.STYLE_SPINNER); + progress.setMessage(getString(R.string.loading)); + progress.setCancelable(false); + + // show the progress dialog + publishProgress(0); + + // File not reachable + if(!DownloadManager.checkHttpFile(url)) { + alert.setMessage(getString(R.string.error_json_not_found)) + .setCancelable(false) + .setPositiveButton(getString(R.string.OK), new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + dialog.dismiss(); + finish(); + return; + } + }); + publishProgress(-1); + return false; + } + + // initialize local variables + HttpParams httpParameters = new BasicHttpParams(); + HttpConnectionParams.setConnectionTimeout(httpParameters,3000); + DefaultHttpClient httpClient = new DefaultHttpClient(); + URI uri; + InputStream data; + + try { + uri = new URI(url); + HttpGet method = new HttpGet(uri); + HttpResponse response = httpClient.execute(method); + data = response.getEntity().getContent(); + + SharedData sdata = SharedData.getInstance(); + sdata.setInputStreamData(data); + + } catch (Exception e) { + alert.setMessage(getString(R.string.error_json_download)) + .setCancelable(false) + .setPositiveButton(getString(R.string.OK), new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + dialog.dismiss(); + } + }); + publishProgress(-1); + e.printStackTrace(); + return false; + } + + publishProgress(100); + return true; + } + + @Override + protected void onProgressUpdate(Integer... iProgress) { + switch(iProgress[0]) { + // an error occurred, popup an error + case -1: + alert.create().show(); + progress.dismiss(); + break; + // initialize the progress bar to 0 + case 0: + progress.show(); + progress.setProgress(iProgress[0]); + break; + case 100: + progress.dismiss(); + break; + default: + progress.setProgress(iProgress[0]); + } + super.onProgressUpdate(iProgress); + } + + @Override + protected void onPostExecute(Boolean result) { + onJSONDataDownloaded(result); + super.onPostExecute(result); + } + + } // class DownloadJSON + void onJSONDataDownloaded(Boolean success) {} - void onDownloadComplete(Boolean success) {} -} + void onDownloadComplete(Boolean success) { + if (DBG) Log.v("SuperActivity", "onDownloadComplete "+success); + } + +} // class ROMSuperActivity diff --git a/src/org/elegosproject/romupdater/ROMUpdater.java b/src/org/elegosproject/romupdater/ROMUpdater.java index 2c934be..55c4993 100644 --- a/src/org/elegosproject/romupdater/ROMUpdater.java +++ b/src/org/elegosproject/romupdater/ROMUpdater.java @@ -35,19 +35,20 @@ import android.widget.AdapterView.OnItemClickListener; public class ROMUpdater extends ROMSuperActivity { - private static final String TAG = "ROM Updater (ROMUpdater.class)"; - - private ListView actions; - + private static final String TAG = "RomUpdater[Activity]"; + + private ListView actions; + @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); - + actions = (ListView)this.findViewById(R.id.listOfActions); - fillActionsList(); - - SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(this); + fillActionsList(); + + SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(this); +/* if(!preferences.getBoolean("anon_stats_verified", false)) { AlertDialog.Builder anonBuilder = new AlertDialog.Builder(this); anonBuilder.setCancelable(false) @@ -56,7 +57,6 @@ public void onCreate(Bundle savedInstanceState) { public void onClick(DialogInterface dialog, int which) { dialog.dismiss(); - } }) .setPositiveButton(R.string.settings, new DialogInterface.OnClickListener() { @@ -72,7 +72,7 @@ public void onClick(DialogInterface dialog, int which) { editor.putBoolean("anon_stats_verified", true); editor.commit(); } - +*/ actions.setOnItemClickListener(new OnItemClickListener() { SharedData sdata = SharedData.getInstance(); public void onItemClick(AdapterView arg0, View arg1, @@ -95,75 +95,33 @@ public void onItemClick(AdapterView arg0, View arg1, Intent preferences = new Intent(ROMUpdater.this, Preferences.class); startActivity(preferences); break; + // wipe cache case 3: AlertDialog.Builder dialog = new AlertDialog.Builder(ROMUpdater.this); - dialog.setMessage(getString(R.string.wipe_cache_message)) - .setTitle(getString(R.string.wipe_cache)) - .setCancelable(true) - .setPositiveButton(getString(R.string.wipe), new DialogInterface.OnClickListener() { + dialog.setMessage(getString(R.string.wipe_cache_message)) + .setTitle(getString(R.string.wipe_cache)) + .setCancelable(true) + .setPositiveButton(getString(R.string.wipe), new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int which) { sdata.setRecoveryOperations(2); RecoveryManager.setupExtendedCommand(); RecoveryManager.wipeCache(); - - RecoveryManager.rebootRecovery(); - } - }) - .setNegativeButton(getString(R.string.cancel), new DialogInterface.OnClickListener() { - public void onClick(DialogInterface dialog, int which) { - dialog.dismiss(); - } - }); - - AlertDialog alert = dialog.create(); - alert.show(); - break; - // wipe data and (eventually) SD-EXT - case 4: - final AlertDialog.Builder sdext = new AlertDialog.Builder(ROMUpdater.this); - sdext.setMessage(getString(R.string.wipe_sdext_too)) - .setCancelable(false) - .setPositiveButton(getString(R.string.yes), new DialogInterface.OnClickListener() { - public void onClick(DialogInterface dialog, int which) { - sdata.setRecoveryOperations(3); - RecoveryManager.setupExtendedCommand(); - RecoveryManager.wipeData(); - RecoveryManager.wipeSDExt(); - RecoveryManager.rebootRecovery(); } }) - .setNegativeButton(getString(R.string.no), new DialogInterface.OnClickListener() { - public void onClick(DialogInterface dialog, int which) { - sdata.setRecoveryOperations(2); - RecoveryManager.setupExtendedCommand(); - RecoveryManager.wipeData(); - - RecoveryManager.rebootRecovery(); - } - }); - - AlertDialog.Builder dataDialog = new AlertDialog.Builder(ROMUpdater.this); - dataDialog.setMessage(getString(R.string.wipe_data_message)) - .setTitle(getString(R.string.wipe_data)) - .setCancelable(true) - .setPositiveButton(getString(R.string.wipe), new DialogInterface.OnClickListener() { - public void onClick(DialogInterface dialog, int which) { - sdext.create().show(); - } - }) .setNegativeButton(getString(R.string.cancel), new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int which) { dialog.dismiss(); } }); - - AlertDialog dataAlert = dataDialog.create(); - dataAlert.show(); + + AlertDialog alert = dialog.create(); + alert.show(); break; + // Backup the actual system - case 5: + case 4: AlertDialog.Builder backupDialog = new AlertDialog.Builder(ROMUpdater.this); backupDialog.setMessage(getString(R.string.backup_rom_message)) .setTitle(getString(R.string.backup_rom)) @@ -187,12 +145,12 @@ public void onClick(DialogInterface dialog, int which) { backupAlert.show(); break; // Restore a backup - case 6: + case 5: Intent restore = new Intent(ROMUpdater.this, Restore.class); startActivity(restore); break; // Enter recovery mode (manual operations) - case 7: + case 6: AlertDialog.Builder recoveryDialog = new AlertDialog.Builder(ROMUpdater.this); recoveryDialog.setMessage(getString(R.string.recovery_message)) .setTitle(getString(R.string.recovery)) @@ -211,6 +169,48 @@ public void onClick(DialogInterface dialog, int which) { AlertDialog recoveryAlert = recoveryDialog.create(); recoveryAlert.show(); break; +/* + // wipe data and (eventually) SD-EXT + case 7: + final AlertDialog.Builder sdext = new AlertDialog.Builder(ROMUpdater.this); + sdext.setMessage(getString(R.string.wipe_sdext_too)) + .setCancelable(false) + .setPositiveButton(getString(R.string.yes), new DialogInterface.OnClickListener() { + public void onClick(DialogInterface dialog, int which) { + sdata.setRecoveryOperations(3); + RecoveryManager.setupExtendedCommand(); + RecoveryManager.wipeDataAndSDExt(); + RecoveryManager.rebootRecovery(); + } + }) + .setNegativeButton(getString(R.string.no), new DialogInterface.OnClickListener() { + public void onClick(DialogInterface dialog, int which) { + sdata.setRecoveryOperations(2); + RecoveryManager.setupExtendedCommand(); + RecoveryManager.wipeData(); + RecoveryManager.rebootRecovery(); + } + }); + AlertDialog.Builder dataDialog = new AlertDialog.Builder(ROMUpdater.this); + + dataDialog.setMessage(getString(R.string.wipe_data_message)) + .setTitle(getString(R.string.wipe_data)) + .setCancelable(true) + .setPositiveButton(getString(R.string.wipe), new DialogInterface.OnClickListener() { + public void onClick(DialogInterface dialog, int which) { + sdext.create().show(); + } + }) + .setNegativeButton(getString(R.string.cancel), new DialogInterface.OnClickListener() { + public void onClick(DialogInterface dialog, int which) { + dialog.dismiss(); + } + }); + + AlertDialog dataAlert = dataDialog.create(); + dataAlert.show(); + break; +*/ } } }); @@ -222,10 +222,10 @@ private void fillActionsList() { versionsList.add(getString(R.string.downloaded_files)); versionsList.add(getString(R.string.settings)); versionsList.add(getString(R.string.wipe_cache)); - versionsList.add(getString(R.string.wipe_data)); versionsList.add(getString(R.string.backup_rom)); versionsList.add(getString(R.string.restore_rom)); versionsList.add(getString(R.string.recovery)); +// versionsList.add(getString(R.string.wipe_data)); ListAdapter adapter = new ArrayAdapter(this, android.R.layout.simple_list_item_1, versionsList); actions.setAdapter(adapter); diff --git a/src/org/elegosproject/romupdater/RecoveryManager.java b/src/org/elegosproject/romupdater/RecoveryManager.java index 172cbb6..b55a0c9 100644 --- a/src/org/elegosproject/romupdater/RecoveryManager.java +++ b/src/org/elegosproject/romupdater/RecoveryManager.java @@ -27,16 +27,23 @@ import android.util.Log; public class RecoveryManager { - private static String TAG = "ROM Updater (Recovery Manager)"; - + private static String TAG = "RomUpdater[RecoveryManager]"; + public static void rebootRecovery() { SharedData sdata = SharedData.getInstance(); - + while(sdata.getRecoveryCounter() < sdata.getRecoveryOperations()) { while(sdata.getLockProcess()); } - - sdata.addRecoveryMessage("reboot recovery\n"); + + sdata.addRecoveryMessage("mkdir -p /cache/recovery\n"); + sdata.addRecoveryMessage("mkdir -p /sdcard/clockworkmod\n"); + + //put a random md5sum for sdcard marker !?! for firsts 5.0.x.x koush CWM variants + sdata.addRecoveryMessage("echo '3f42727dd8641a3bb5734fa7ee78185f' > /sdcard/clockworkmod/.salted_hash\n"); + sdata.addRecoveryMessage("echo 0 > /sdcard/clockworkmod/.recoverycheckpoint\n"); + sdata.addRecoveryMessage("cp /cache/recovery/command /cache/recovery/.last_command\n"); + sdata.addRecoveryMessage("toolbox reboot recovery\n"); try { Process p = Runtime.getRuntime().exec("su"); OutputStream os = p.getOutputStream(); @@ -45,58 +52,85 @@ public static void rebootRecovery() { } catch(Exception e) { Log.e(TAG, "Unable to reboot into recovery"); } - } - + // Extended command section - + public static void recoveryExtCommand(SharedData sdata, String msg) { + sdata.addRecoveryMessage("echo '"+ msg +"' >> /cache/recovery/extendedcommand\n"); + } + + public static void recoveryStartScript(SharedData sdata) { + sdata.addRecoveryMessage("echo '#!/sbin/sh' > /cache/recovery/.romupdater.sh\n"); + sdata.addRecoveryMessage("echo 'export PATH=/sbin:$PATH' >> /cache/recovery/.romupdater.sh\n"); + sdata.addRecoveryMessage("chmod 755 /cache/recovery/.romupdater.sh\n"); + } + + public static void recoveryEndScript(SharedData sdata) { + recoveryExtCommand(sdata, "run_program(\"/cache/recovery/.romupdater.sh\");\n"); + sdata.addRecoveryMessage("echo 'boot-recovery' > /cache/recovery/command\n"); + } + + public static void recoveryAddToScript(SharedData sdata, String msg) { + sdata.addRecoveryMessage("echo '"+ msg +"' >> /cache/recovery/.romupdater.sh\n"); + } + public static void setupExtendedCommand() { SharedData sdata = SharedData.getInstance(); - + while(sdata.getLockProcess()); sdata.setLockProcess(true); - - sdata.addRecoveryMessage("mkdir -p /cache/recovery/\n"); - sdata.addRecoveryMessage("echo 'boot-recovery' >/cache/recovery/command\n"); - sdata.addRecoveryMessage("echo 'print ROM Updater by elegos' > /cache/recovery/extendedcommand\n"); + + sdata.addRecoveryMessage("mkdir -p /sdcard/clockworkmod\n"); + sdata.addRecoveryMessage("mkdir -p /cache/recovery\n"); + + sdata.addRecoveryMessage("echo 'boot-recovery' > /cache/recovery/command\n"); + sdata.addRecoveryMessage("echo > /cache/recovery/extendedcommand\n"); + sdata.addRecoveryMessage("rm -f /cache/recovery/.romupdater.sh\n"); + + recoveryExtCommand(sdata, "ui_print(\"ROM Updater\");"); sdata.incrementRecoveryCounter(); sdata.setLockProcess(false); } - + public static void addUpdate(String file) { SharedData sdata = SharedData.getInstance(); - + while(sdata.getLockProcess()); sdata.setLockProcess(true); - - if(file.startsWith("/sdcard/")) - file = file.substring(8); - - sdata.addRecoveryMessage("print Installing file SDCARD:"+file+"\n"); - sdata.addRecoveryMessage("echo 'install_zip SDCARD:"+file+"' >> /cache/recovery/extendedcommand\n"); - + + if(file.startsWith("/mnt/")) + file = file.substring(4); + else if(!file.startsWith("/")) + file = "/sdcard/"+file; + + sdata.addRecoveryMessage("echo '--update_package="+file+"' > /cache/recovery/command\n"); + sdata.addRecoveryMessage("rm -f /cache/recovery/extendedcommand\n"); + sdata.incrementRecoveryCounter(); sdata.setLockProcess(false); } - + public static void doBackup(Context context) { SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(context); String backupFolder = "/sdcard/"+preferences.getString("backup_folder", "clockworkmod/backup"); if(!backupFolder.endsWith("/")) backupFolder += "/"; - + SharedData sdata = SharedData.getInstance(); - + while(sdata.getLockProcess()); sdata.setLockProcess(true); try { SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd-HH.mm"); Date date = new Date(); - + sdata.addRecoveryMessage("mkdir -p "+backupFolder+"\n"); - sdata.addRecoveryMessage("echo 'print Backing up the current ROM to \""+backupFolder+format.format(date)+"\"' >> /cache/recovery/extendedcommand\n"); - sdata.addRecoveryMessage("echo 'backup_rom "+backupFolder+format.format(date)+"' >> /cache/recovery/extendedcommand\n"); + recoveryExtCommand(sdata, "ui_print(\"Backing up the current ROM to " + + backupFolder + format.format(date) + "\");" + ); + recoveryExtCommand(sdata, "backup_rom(\"" + backupFolder + format.format(date)+ "\");"); + } catch (Exception e) { Log.e(TAG,"Unable to setup environment for Nandroid backup"); e.printStackTrace(); @@ -105,73 +139,80 @@ public static void doBackup(Context context) { sdata.setLockProcess(false); } } - + public static void restoreBackup(String backupDirectory) { SharedData sdata = SharedData.getInstance(); - + while(sdata.getLockProcess()); sdata.setLockProcess(true); - - sdata.addRecoveryMessage("print Restoring ROM from SDCARD:"+backupDirectory+"\n"); - sdata.addRecoveryMessage("echo 'restore_rom /sdcard/"+backupDirectory+"' >> /cache/recovery/extendedcommand\n"); - + recoveryExtCommand(sdata, "ui_print(\"Restoring ROM from SDCARD:"+backupDirectory+"\");"); + recoveryExtCommand(sdata, "restore_rom(\"" + backupDirectory + "\");"); + sdata.incrementRecoveryCounter(); sdata.setLockProcess(false); } - + public static void wipeCache() { SharedData sdata = SharedData.getInstance(); - + while(sdata.getLockProcess()); sdata.setLockProcess(true); - - sdata.addRecoveryMessage("echo 'print Wiping CACHE' >> /cache/recovery/extendedcommand\n"); - sdata.addRecoveryMessage("echo 'delete_recursive DATA:dalvik-cache' >> /cache/recovery/extendedcommand\n"); + recoveryExtCommand(sdata, "ui_print(\"Wiping CACHE\");"); + recoveryExtCommand(sdata, "mount(\"/data\");"); + + recoveryStartScript(sdata); + recoveryAddToScript(sdata, "rm -rf /cache/dalvik-cache"); + recoveryAddToScript(sdata, "rm -rf /data/dalvik-cache"); + recoveryEndScript(sdata); + + //recoveryExtCommand(sdata, "delete_recursive(\"/cache/dalvik-cache\");"); + //recoveryExtCommand(sdata, "delete_recursive(\"/data/dalvik-cache\");"); sdata.incrementRecoveryCounter(); sdata.setLockProcess(false); } - + public static void wipeData() { SharedData sdata = SharedData.getInstance(); while(sdata.getLockProcess()); - + sdata.setLockProcess(true); - sdata.addRecoveryMessage("echo 'print Wiping USER DATA' >> /cache/recovery/extendedcommand\n"); - sdata.addRecoveryMessage("echo 'delete_recursive DATA:' >> /cache/recovery/extendedcommand\n"); - + recoveryExtCommand(sdata, "ui_print(\"Wiping USER DATA\");"); + recoveryExtCommand(sdata, "mount(\"/data\");"); + + recoveryStartScript(sdata); + recoveryAddToScript(sdata, "rm -rf /data/*"); + recoveryEndScript(sdata); + + //recoveryExtCommand(sdata, "delete_recursive(\"/data\");"); + sdata.incrementRecoveryCounter(); sdata.setLockProcess(false); } - - public static void wipeSDExt() { + + public static void wipeDataAndSDExt() { SharedData sdata = SharedData.getInstance(); while(sdata.getLockProcess()); sdata.setLockProcess(true); - sdata.addRecoveryMessage("echo 'print Wiping SD-EXT' >> /cache/recovery/extendedcommand\n"); - sdata.addRecoveryMessage("echo 'delete_recursive SDEXT:app' >> /cache/recovery/extendedcommand\n"); - sdata.addRecoveryMessage("echo 'delete_recursive SDEXT:app-private' >> /cache/recovery/extendedcommand\n"); + recoveryExtCommand(sdata, "ui_print(\"Wiping Data and SD-EXT apps\");"); + recoveryExtCommand(sdata, "mount(\"/data\");"); + recoveryExtCommand(sdata, "mount(\"/sd-ext\");"); + + recoveryStartScript(sdata); + recoveryAddToScript(sdata, "rm -rf /data/*"); + recoveryAddToScript(sdata, "rm -rf /sd-ext/app"); + recoveryAddToScript(sdata, "rm -rf /sd-ext/app-private"); + recoveryEndScript(sdata); + + recoveryExtCommand(sdata, "umount(\"/sd-ext\");"); + + //recoveryExtCommand(sdata, "delete_recursive(\"/sd-ext/app\");"); + //recoveryExtCommand(sdata, "delete_recursive(\"/sd-ext/app-private\");"); sdata.incrementRecoveryCounter(); sdata.setLockProcess(false); } - - // Command section - - public static void setupCommand() { - try { - Process p = Runtime.getRuntime().exec("su"); - OutputStream os = p.getOutputStream(); - - os.write("mkdir -p /cache/recovery/\n".getBytes()); - os.write("echo 'boot-recovery' >/cache/recovery/command\n".getBytes()); - - os.flush(); - } catch (Exception e) { - Log.e(TAG,"Unable to reboot into Recovery mode for wiping cache"); - e.printStackTrace(); - } - } + } diff --git a/src/org/elegosproject/romupdater/RepositoriesList.java b/src/org/elegosproject/romupdater/RepositoriesList.java index dd54ba2..d705c41 100644 --- a/src/org/elegosproject/romupdater/RepositoriesList.java +++ b/src/org/elegosproject/romupdater/RepositoriesList.java @@ -17,7 +17,8 @@ import android.widget.Toast; public class RepositoriesList extends ROMSuperActivity { - private static final String repoUrl = "http://www.elegosproject.org/android/repositories.php"; + private static final String TAG = "RomUpdater[RepositoriesList]"; + private static String repoUrl; private RepoList[] rawList; private ExpandableListView theList; @@ -27,6 +28,8 @@ protected void onCreate(Bundle savedInstanceState) { setContentView(R.layout.repo_list); theList = (ExpandableListView) findViewById(R.id.repositoriesExpandableList); + + repoUrl = getString(R.string.all_repos_url); new DownloadJSON().execute(repoUrl); @@ -47,21 +50,19 @@ public void onClick(DialogInterface dialog, int which) { SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(RepositoriesList.this); Editor editor = prefs.edit(); String url = rawList[groupPosition].getRepositories()[childPosition].getUrl(); - // trim the last character until it finishes with "/" (HACK) - // TODO: better handling - while(!url.endsWith("/")) { - url = url.substring(0,url.length()-1); + + // trim the last character until it finishes with "/" + if (url.contains("/") && !url.contains("json") && !url.contains("?")) { + url = url.substring(0, url.lastIndexOf("/")+1); } - // push the url in the setting editor.putString("repository_url", url); editor.commit(); - + Toast t = Toast.makeText(RepositoriesList.this, getString(R.string.repository_changed_toast)+" ("+url+")",Toast.LENGTH_LONG); - t.show(); - - dialog.dismiss(); - finish(); + t.show(); + dialog.dismiss(); + finish(); } }); alert.setNegativeButton(getString(R.string.no), new DialogInterface.OnClickListener() { @@ -91,7 +92,7 @@ public void onClick(DialogInterface dialog, int which) { void onJSONDataDownloaded(Boolean success) { if(!success) return; - + /* // alert the user about the list nature AlertDialog.Builder info = new AlertDialog.Builder(this); info.setTitle(getString(R.string.important)) @@ -104,6 +105,7 @@ public void onClick(DialogInterface dialog, int which) { } }); info.create().show(); + */ JSONParser parser = new JSONParser(); rawList = parser.getRepositoriesFromJSON(); diff --git a/src/org/elegosproject/romupdater/Restore.java b/src/org/elegosproject/romupdater/Restore.java index 5af885e..428d3c3 100644 --- a/src/org/elegosproject/romupdater/Restore.java +++ b/src/org/elegosproject/romupdater/Restore.java @@ -18,6 +18,8 @@ import android.widget.ListView; public class Restore extends ROMSuperActivity { + private static final String TAG = "RomUpdater[Restore]"; + private ListView listOfRestores; @Override diff --git a/src/org/elegosproject/romupdater/SharedData.java b/src/org/elegosproject/romupdater/SharedData.java index d7b276f..a2f75ff 100644 --- a/src/org/elegosproject/romupdater/SharedData.java +++ b/src/org/elegosproject/romupdater/SharedData.java @@ -19,15 +19,20 @@ import java.io.InputStream; +import android.content.Context; +import android.content.res.Resources; +import android.os.SystemProperties; +import android.text.TextUtils; + public class SharedData { static final Object mLock = new Object(); static SharedData mInstance; public static final String LOCAL_MODEL = android.os.Build.MODEL; - public static final String LOCAL_ROMNAME = android.os.Build.DISPLAY; public static final String LOCAL_VERSION = android.os.Build.VERSION.INCREMENTAL; - - public static final String ABOUT_LICENCE = "ROM Updater Copyright (C) 2011 by elegos\nThis program comes with ABSOLUTELY NO WARRANTY;\nThis is free software, and you are welcome to redistribute it under certain conditions;"; + public static String LOCAL_ROMNAME = SystemProperties.get("ro.cm.version", SystemProperties.get("ro.modversion", android.os.Build.DISPLAY)); + + public static final String ABOUT_LICENCE = "Based on elegos version\nEnhanced for AOSP ROMs\n\nThis program comes with ABSOLUTELY NO WARRANTY\n\nThis is free software, and you are welcome to redistribute it under certain conditions"; private String repositoryModel; private String repositoryROMName; @@ -80,10 +85,13 @@ public void setDownloadVersion(String version) { } public void setRepositoryUrl(String url) { - if(!url.startsWith("http://")) - url = "http://"+url; - if(!url.endsWith("/")) - url += "/"; + if(!TextUtils.isEmpty(url)) { + if (!url.contains("://")) + url = "http://"+url; + if (!url.contains("?") && !url.contains("json") && !url.contains("php")) { + if (!url.endsWith("/")) url += "/"; + } + } repositoryUrl = url; } diff --git a/src/org/elegosproject/romupdater/VersionSelector.java b/src/org/elegosproject/romupdater/VersionSelector.java index 004b8a5..d3ca0f9 100644 --- a/src/org/elegosproject/romupdater/VersionSelector.java +++ b/src/org/elegosproject/romupdater/VersionSelector.java @@ -18,16 +18,21 @@ package org.elegosproject.romupdater; import java.io.File; +import java.io.UnsupportedEncodingException; +import java.net.URLEncoder; import java.util.Iterator; import java.util.Vector; import org.elegosproject.romupdater.types.AvailableVersion; import android.app.AlertDialog; +import android.content.Context; import android.content.DialogInterface; import android.content.SharedPreferences; +import android.os.AsyncTask; import android.os.Bundle; import android.preference.PreferenceManager; +import android.text.TextUtils; import android.view.View; import android.widget.AdapterView; import android.widget.ArrayAdapter; @@ -36,63 +41,186 @@ import android.widget.TextView; import android.widget.AdapterView.OnItemClickListener; +import android.util.Log; + public class VersionSelector extends ROMSuperActivity { + private static final String TAG = "RomUpdater[VersionSelector]"; + private SharedData shared; - + private String versionUri; + private String changeLog; private ListView versionsAvailableListView; private TextView versionsTextView; + + private TextView changelogTitle; + private TextView changelogTextView; + private Vector availableVersions; - + private JSONParser myParser = new JSONParser(); - + @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); - + shared = SharedData.getInstance(); - versionUri = getIntent().getExtras().getString("org.elegosproject.romupdater.VersionSelector.versionUri"); + versionUri = getIntent().getExtras().getString(PackageName + ".VersionSelector.versionUri"); + changeLog = getIntent().getExtras().getString(PackageName + ".VersionSelector.changeLog"); + + if (TextUtils.isEmpty(versionUri)) { + // forced repository, not compatible with original version + versionUri = getApplicationContext().getString(R.string.reposerver_url); + } setContentView(R.layout.version); - + versionsAvailableListView = (ListView)this.findViewById(R.id.availableVersions); versionsTextView = (TextView)this.findViewById(R.id.versionsTextView); - + + changelogTitle = (TextView)this.findViewById(R.id.versionChangeLog); + changelogTextView = (TextView)this.findViewById(R.id.versionChangeLog); + setVersionView(versionUri); - + versionsAvailableListView.setOnItemClickListener(new OnItemClickListener() { public void onItemClick(AdapterView arg0, View arg1, int arg2, long arg3) { String selectedDownload = arg0.getItemAtPosition(arg2).toString(); String file = ""; - if(selectedDownload.equals("Full")) + if(selectedDownload.equals(getString(R.string.start_full_download))) file = myParser.parsedAvailableVersions.getFullUri(); - else file = myParser.getUrlForVersion(SharedData.LOCAL_VERSION); - - SharedData sdata = SharedData.getInstance(); - String url = sdata.getRepositoryUrl(); - if(!url.endsWith("/")) url += "/"; - url += versionUri; - if(!url.endsWith("/")) url += "/"; - url += file; - - sdata.setDownloadedFile(DOWNLOAD_DIRECTORY+file); - + else + file = myParser.getUrlForVersion(SharedData.LOCAL_VERSION); + + Log.w(TAG, "getUrlFor("+file+")"); + String url = getUrlFor(versionUri, file); + + shared.setDownloadedFile(DOWNLOAD_DIRECTORY+file); new DownloadFile().execute(url, DOWNLOAD_DIRECTORY+file); } }); } - + + public String urlParamEncode(String param) + { + String res; + try { + res = URLEncoder.encode(param, "UTF-8"); + } + catch (UnsupportedEncodingException e) { + res = param; + } + return res; + } + + /** + * Construct Full URL, allow dynamic pages + */ + public String getUrlFor(String versionUri, String file) + { + String url = ""; + SharedData sdata = SharedData.getInstance(); + + if(!versionUri.contains("://")) { + url = sdata.getRepositoryUrl(); + } + url += versionUri; + if(!url.contains("?") && !url.contains(".php")) { + if(!url.endsWith("/")) url += "/"; + url += file; + } else { + url += sdata.getDownloadVersion(); + url += "&f=" + urlParamEncode(file); + } + return url; + } + + public String getJsonUrlFor(String uri) + { + String url = ""; + SharedData sdata = SharedData.getInstance(); + if(!uri.contains("://")) { + url = sdata.getRepositoryUrl(); + } + url += uri; + if(!url.contains("?") && !url.contains(".php")) { + if(!url.endsWith("/")) url += "/"; + url += "mod.json"; + } else { + //mod.php?v=... + url += sdata.getDownloadVersion(); + } + return url; + } + + class CheckHttpFile extends AsyncTask + { + public boolean success=false; + @Override + protected Boolean doInBackground(String... params) { + String urlToCheck = params[0]; + success = DownloadManager.checkHttpFile(urlToCheck); + Log.d(TAG, "CheckHttpFile: "+success); + return success; + } + } + + private void setVersionView(String versionUri) { + versionsTextView.setText(shared.getDownloadVersion()); + + if (!TextUtils.isEmpty(changeLog)) + changelogTextView.setText(changeLog); + else { + changelogTitle.setVisibility(View.GONE); + changelogTextView.setVisibility(View.GONE); + } + + String uri = getJsonUrlFor(versionUri); + CheckHttpFile check = new CheckHttpFile(); + try { + check.execute(uri); + check.get(); + } + catch (Exception e) { + AlertDialog.Builder notFoundBuilder = new AlertDialog.Builder(VersionSelector.this); + notFoundBuilder.setCancelable(false) + .setTitle(getString(R.string.version_descriptor_not_found_title)) + .setMessage(getString(R.string.version_descriptor_not_found_message)+ + "\n" + e.toString() + ) + .setPositiveButton(getString(R.string.OK), new DialogInterface.OnClickListener() { + public void onClick(DialogInterface dialog, int which) { + dialog.dismiss(); + finish(); + } + }); + AlertDialog dialog = notFoundBuilder.create(); + dialog.show(); + return; + } + if (!check.success) { + // http header check failed + Log.w(TAG, "CheckHttpFile reported a failure !"); + return; + } + new DownloadJSON().execute(uri); + } + @Override void onDownloadComplete(Boolean success) { + super.onDownloadComplete(success); + Log.v(TAG, "DownloadComplete success="+success); + // download exit with true -> success if(success) { // the ROM name is different from the // actual one, ask to wipe or backup and wipe before final SharedData sdata = SharedData.getInstance(); - AlertDialog.Builder alert = new AlertDialog.Builder(this); - - if(!sdata.getRepositoryROMName().equals(SharedData.LOCAL_ROMNAME)) { + AlertDialog.Builder alert = new AlertDialog.Builder(VersionSelector.this); + + if(!SharedData.LOCAL_ROMNAME.contains(shared.getRepositoryROMName())) { + alert.setMessage(getString(R.string.ask_backup_wipe)); alert.setPositiveButton(getString(R.string.backup_and_wipe), new DialogInterface.OnClickListener() { @Override @@ -115,7 +243,7 @@ public void onClick(DialogInterface dialog, int which) { RecoveryManager.rebootRecovery(); } }); - alert.setNegativeButton(getString(R.string.no), new DialogInterface.OnClickListener() { + alert.setNegativeButton(getString(R.string.install), new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { // Just update @@ -147,16 +275,21 @@ public void onClick(DialogInterface dialog, int which) { }); } SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(VersionSelector.this); - // send anonymous data (if accepted) - if(preferences.getBoolean("anon_stats", false)) - DownloadManager.sendAnonymousData(); + // create and show the dialog alert.create().show(); + + // send anonymous data (if accepted) + if(preferences.getBoolean("anon_stats", false)) { + DownloadManager dm = new DownloadManager(); + dm.sendAnonymousData(getApplicationContext()); + } + } else { // download failed // alert the user and delete the file - AlertDialog.Builder error = new AlertDialog.Builder(this); + AlertDialog.Builder error = new AlertDialog.Builder(VersionSelector.this); error.setMessage(getString(R.string.error_download_file)) .setCancelable(false) .setPositiveButton(getString(R.string.OK), new DialogInterface.OnClickListener() { @@ -166,38 +299,17 @@ public void onClick(DialogInterface dialog, int which) { // delete the corrupted file, if any File toDelete = new File(sdata.getDownloadedFile()); toDelete.delete(); - + // dismiss dialog.dismiss(); } }); - + // create and show the dialog error.create().show(); } } - private void setVersionView(String versionUri) { - versionsTextView.setText(getString(R.string.capital_version)+" "+shared.getDownloadVersion()); - if(!DownloadManager.checkHttpFile(shared.getRepositoryUrl()+versionUri+"/mod.json")) { - AlertDialog.Builder notFoundBuilder = new AlertDialog.Builder(VersionSelector.this); - notFoundBuilder.setCancelable(false) - .setTitle(getString(R.string.version_descriptor_not_found_title)) - .setMessage(getString(R.string.version_descriptor_not_found_message)) - .setPositiveButton(getString(R.string.OK), new DialogInterface.OnClickListener() { - public void onClick(DialogInterface dialog, int which) { - dialog.dismiss(); - finish(); - } - }); - AlertDialog dialog = notFoundBuilder.create(); - dialog.show(); - return; - } - - new DownloadJSON().execute(shared.getRepositoryUrl()+versionUri+"/mod.json"); - } - @Override void onJSONDataDownloaded(Boolean success) { super.onJSONDataDownloaded(success); @@ -205,9 +317,9 @@ void onJSONDataDownloaded(Boolean success) { // and finishes the activity, so just return if(!success) return; - + availableVersions = myParser.getAvailableVersions(); - + // JSON parse failed, alert and return if(myParser.failed){ AlertDialog.Builder error = new AlertDialog.Builder(VersionSelector.this); @@ -221,22 +333,33 @@ public void onClick(DialogInterface dialog, int which) { error.create().show(); finish(); } - + VectorversionsList = new Vector(); Iterator versionsIterator = availableVersions.iterator(); String iteratorVersion = ""; - + // The "Full" element is always present - versionsList.add("Full"); + versionsList.add(getString(R.string.start_full_download)); // Search for an incremental update, in case add it to the list - if(SharedData.LOCAL_ROMNAME.equals(shared.getRepositoryROMName())) + if (SharedData.LOCAL_ROMNAME != null && + SharedData.LOCAL_ROMNAME.contains(shared.getRepositoryROMName())) + { while(versionsIterator.hasNext()) { iteratorVersion = versionsIterator.next().getVersion(); - if(Integer.parseInt(SharedData.LOCAL_VERSION) == Integer.parseInt(iteratorVersion)) { - versionsList.add("Incremental"); + try { + if (SharedData.LOCAL_VERSION != null && + SharedData.LOCAL_VERSION.equals(iteratorVersion)) + { + versionsList.add("Incremental"); + Log.w(TAG, "adding incremental "+iteratorVersion); + break; + } + } catch (NumberFormatException e) { + Log.w(TAG, "ignoring incremental "+iteratorVersion); break; } } + } ListAdapter adapter = new ArrayAdapter(this, android.R.layout.simple_list_item_1, versionsList); versionsAvailableListView.setAdapter(adapter); diff --git a/src/org/elegosproject/romupdater/VersionsList.java b/src/org/elegosproject/romupdater/VersionsList.java index 967f350..801977a 100644 --- a/src/org/elegosproject/romupdater/VersionsList.java +++ b/src/org/elegosproject/romupdater/VersionsList.java @@ -30,6 +30,7 @@ import android.content.SharedPreferences; import android.os.Bundle; import android.preference.PreferenceManager; +import android.text.TextUtils; import android.util.Log; import android.view.View; import android.widget.AdapterView; @@ -41,7 +42,7 @@ import android.widget.AdapterView.OnItemLongClickListener; public class VersionsList extends ROMSuperActivity { - private static final String TAG = "ROM Updater (VersionsList.class)"; + private static final String TAG = "RomUpdater[VersionsList]"; private SharedPreferences preferences; private SharedData shared; @@ -59,16 +60,16 @@ public void onCreate(Bundle savedInstanceState) { preferences = PreferenceManager.getDefaultSharedPreferences(this); shared = SharedData.getInstance(); - String prefRepo = preferences.getString("repository_url", ""); - if(!prefRepo.equals("")) + String prefRepo = preferences.getString("repository_url", getString(R.string.reposerver_url)); + if(!TextUtils.isEmpty(prefRepo)) shared.setRepositoryUrl(prefRepo); else { String buildRepo = BuildParser.parseString("ro.romupdater.repository"); shared.setRepositoryUrl(buildRepo); } - + // repository not set - if(shared.getRepositoryUrl().equals("")) { + if(TextUtils.isEmpty(shared.getRepositoryUrl())) { AlertDialog.Builder dialog = new AlertDialog.Builder(this); dialog.setMessage(getString(R.string.error_repository_not_set)) .setCancelable(false) @@ -83,36 +84,34 @@ public void onClick(DialogInterface dialog, int which) { alert.show(); return; } + + Log.i(TAG, "Repository set to " + shared.getRepositoryUrl()); versionsListView = (ListView)this.findViewById(R.id.versionsList); - Toast t = Toast.makeText(this, getString(R.string.changelog_toast),Toast.LENGTH_LONG); - t.show(); + //Toast t = Toast.makeText(this, getString(R.string.changelog_toast),Toast.LENGTH_LONG); + //t.show(); setMainView(); - + versionsListView.setOnItemLongClickListener(new OnItemLongClickListener() { public boolean onItemLongClick(AdapterView parent, View view, int position, long id) { String selectedItem = parent.getItemAtPosition(position).toString(); Log.i(TAG,"ITEM: "+selectedItem); - String version = selectedItem.substring(selectedItem.lastIndexOf(" ")+1); - String changelog = ""; - ROMVersion currentVersion = new ROMVersion(); - Iterator iVersion = modVersions.iterator(); - - while(iVersion.hasNext()) { - currentVersion = iVersion.next(); - if(currentVersion.getVersion().equals(version)) { - changelog = currentVersion.getChangelog(); - break; - } - } - + String version; + if (selectedItem.lastIndexOf(" ") > 0) + version = selectedItem.substring(selectedItem.lastIndexOf(" ")+1); + else + version = selectedItem; + + String changelog = getChangeLog(version); + AlertDialog.Builder dialog = new AlertDialog.Builder(VersionsList.this); dialog.setMessage(selectedItem+" changelog:\n\n"+changelog) .setCancelable(false) .setPositiveButton(getString(R.string.OK), new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int which) { dialog.dismiss(); + dialog = null; } }); AlertDialog alert = dialog.create(); @@ -125,24 +124,39 @@ public void onClick(DialogInterface dialog, int which) { versionsListView.setOnItemClickListener(new OnItemClickListener() { public void onItemClick(AdapterView arg0, View arg1, int arg2, long arg3) { + String selectedVersion = arg0.getItemAtPosition(arg2).toString(); Log.i(TAG,"Item selected: "+selectedVersion); - String ver = shared.getRepositoryROMName()+" "; - - shared.setDownloadVersion(selectedVersion.substring(ver.length())); - + shared.setDownloadVersion(selectedVersion); + Intent selector = new Intent(VersionsList.this, VersionSelector.class); - selector.putExtra("org.elegosproject.romupdater.VersionSelector.versionUri", myParser.getROMVersionUri(shared.getDownloadVersion())); + String dlVersion = myParser.getROMVersionUri(shared.getDownloadVersion()); + selector.putExtra(PackageName + ".VersionSelector.versionUri", dlVersion); + selector.putExtra(PackageName + ".VersionSelector.changeLog", getChangeLog(selectedVersion)); startActivity(selector); } }); } - + + private String getChangeLog(String version) { + String changelog = ""; + ROMVersion currentVersion = new ROMVersion(); + Iterator iVersion = modVersions.iterator(); + while(iVersion.hasNext()) { + currentVersion = iVersion.next(); + if(currentVersion.getVersion().equals(version)) { + changelog = currentVersion.getChangelog(); + break; + } + } + return changelog; + } + private void setMainView() { String repositoryUrl = shared.getRepositoryUrl(); // repository URL is void -> must set it before, finish - if(repositoryUrl.equals("")) { + if(TextUtils.isEmpty(repositoryUrl)) { AlertDialog.Builder error = new AlertDialog.Builder(VersionsList.this); error.setMessage(getString(R.string.error_repository_not_set)) .setCancelable(false) @@ -156,8 +170,10 @@ public void onClick(DialogInterface dialog, int which) { error.create().show(); finish(); } - - new DownloadJSON().execute(repositoryUrl+"main.json"); + if (!repositoryUrl.contains("json") && !repositoryUrl.contains("php") && !repositoryUrl.contains("?")) + new DownloadJSON().execute(repositoryUrl+"main.json"); + else + new DownloadJSON().execute(repositoryUrl); } @Override void onJSONDataDownloaded(Boolean success) { @@ -168,7 +184,7 @@ void onJSONDataDownloaded(Boolean success) { if(!success) { return; } - + modVersions = myParser.getROMVersions(); // JSON parse failed, alert and return @@ -179,24 +195,27 @@ void onJSONDataDownloaded(Boolean success) { @Override public void onClick(DialogInterface dialog, int which) { dialog.dismiss(); + dialog = null; + finish(); } }); error.create().show(); - finish(); + return; } /* Global variables */ shared.setRespositoryModel(myParser.parsedVersions.getPhoneModel()); shared.setRepositoryROMName(myParser.parsedVersions.getName()); - - // the repository is not for the current model - if(!shared.getRepositoryModel().equals(SharedData.LOCAL_MODEL)) { + + // the repository is not for the current model (and not empty for common stuff) + if(!shared.getRepositoryModel().equals(SharedData.LOCAL_MODEL) && !TextUtils.isEmpty(shared.getRepositoryModel())) { AlertDialog.Builder modelAlert = new AlertDialog.Builder(this); modelAlert.setCancelable(false) .setMessage(getString(R.string.error_model_mismatch)) .setPositiveButton(getString(R.string.cancel), new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int which) { dialog.dismiss(); + dialog = null; finish(); } }); @@ -206,7 +225,7 @@ public void onClick(DialogInterface dialog, int which) { // Vector of versions, one per line VectorversionsList = new Vector(); - + Iterator versionsIterator = modVersions.iterator(); // 2. insert the versions in a vector String iteratorVersion = ""; @@ -215,24 +234,32 @@ public void onClick(DialogInterface dialog, int which) { iteratorVersion = versionsIterator.next().getVersion(); // if same ROM name and greater version // or different ROM name, add the update to the vector - if(!SharedData.LOCAL_ROMNAME.equals(shared.getRepositoryROMName()) || - (SharedData.LOCAL_ROMNAME.equals(shared.getRepositoryROMName()) && Integer.parseInt(SharedData.LOCAL_VERSION) < Integer.parseInt(iteratorVersion))) - versionsList.add(myParser.modName+" "+iteratorVersion); + try { + if(!SharedData.LOCAL_ROMNAME.contains(shared.getRepositoryROMName()) || + (SharedData.LOCAL_ROMNAME.contains(shared.getRepositoryROMName()) && Integer.parseInt(SharedData.LOCAL_VERSION) < Integer.parseInt(iteratorVersion))) + versionsList.add(iteratorVersion); + } catch (NumberFormatException e) { + versionsList.add(iteratorVersion); + } } - + // sort the vector Comparator r = Collections.reverseOrder(); Collections.sort(versionsList,r); - + // ROM name differs between the local and the remote one // alert the user he'll only be able to download FULL versions - if(!SharedData.LOCAL_ROMNAME.equals(shared.getRepositoryROMName())) { + if(!SharedData.LOCAL_ROMNAME.contains(shared.getRepositoryROMName()) && !versionsList.isEmpty()) { AlertDialog.Builder builder = new AlertDialog.Builder(VersionsList.this); builder.setCancelable(true) - .setMessage(getString(R.string.modname_mismatch)) + .setMessage(getString(R.string.modname_mismatch) + "\n\n" + + "Local:" + SharedData.LOCAL_ROMNAME + "\n" + + "Server:" + shared.getRepositoryROMName() + ) .setPositiveButton(getString(R.string.OK), new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int which) { dialog.dismiss(); + dialog = null; } }); AlertDialog dialog = builder.create(); @@ -243,10 +270,11 @@ public void onClick(DialogInterface dialog, int which) { if(versionsList.isEmpty()) { AlertDialog.Builder updatedBuilder = new AlertDialog.Builder(VersionsList.this); updatedBuilder.setCancelable(true) - .setMessage(getString(R.string.rom_is_updated)) + .setMessage(getString(R.string.versionlist_is_empty)) .setPositiveButton(getString(R.string.OK), new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int which) { dialog.dismiss(); + dialog = null; finish(); } }); @@ -254,7 +282,7 @@ public void onClick(DialogInterface dialog, int which) { upToDateDialog.show(); return; } - + // 3. set the versions list ListAdapter adapter = new ArrayAdapter(this, android.R.layout.simple_list_item_1, versionsList); versionsListView.setAdapter(adapter); diff --git a/src/org/elegosproject/romupdater/types/AvailableVersions.java b/src/org/elegosproject/romupdater/types/AvailableVersions.java index 4d9fa57..487d479 100644 --- a/src/org/elegosproject/romupdater/types/AvailableVersions.java +++ b/src/org/elegosproject/romupdater/types/AvailableVersions.java @@ -17,12 +17,13 @@ package org.elegosproject.romupdater.types; +import java.util.ArrayList; import java.util.List; public class AvailableVersions { private String full; private List fromVersion; - + public String getFullUri() { return full; } @@ -34,9 +35,14 @@ public void setFullUri(String u) { public List getAvailableVersions() { return fromVersion; } - + public void setAvailableVersions(List VersionsList) { fromVersion = VersionsList; + try { + boolean isEmpty = fromVersion.isEmpty(); + } catch (Exception e) { + fromVersion = new ArrayList(); + } } public String getVersionFileName(String version) { @@ -46,4 +52,4 @@ public String getVersionFileName(String version) { } return ""; } -} \ No newline at end of file +} diff --git a/src/org/elegosproject/romupdater/types/ROMVersion.java b/src/org/elegosproject/romupdater/types/ROMVersion.java index 7e8b32b..6415dc8 100644 --- a/src/org/elegosproject/romupdater/types/ROMVersion.java +++ b/src/org/elegosproject/romupdater/types/ROMVersion.java @@ -17,6 +17,8 @@ package org.elegosproject.romupdater.types; +import android.text.TextUtils; + public class ROMVersion { private String changelog; private String version; @@ -30,7 +32,7 @@ public String getChangelog() { logs += log.substring(0,pipe)+"\n"; log = log.substring(pipe+1); } - if(!log.equals("")) logs += log+"\n"; + if(!TextUtils.isEmpty(log)) logs += log+"\n"; return logs; } public void setChangelog(String c) { diff --git a/src/org/elegosproject/romupdater/types/ROMVersions.java b/src/org/elegosproject/romupdater/types/ROMVersions.java index 6121635..2971d88 100644 --- a/src/org/elegosproject/romupdater/types/ROMVersions.java +++ b/src/org/elegosproject/romupdater/types/ROMVersions.java @@ -17,6 +17,7 @@ package org.elegosproject.romupdater.types; +import java.util.ArrayList; import java.util.List; public class ROMVersions { @@ -24,7 +25,7 @@ public class ROMVersions { private List versions; private String phoneModel; private List mirrorList; - + public ROMVersions() { name = ""; phoneModel = ""; @@ -33,23 +34,28 @@ public ROMVersions() { public String getName() { return name; } - + public void setName(String sName) { name = sName; } - + public List getVersions() { return versions; } - + public void setVersions(List ROMList) { versions = ROMList; + try { + boolean isEmpty = versions.isEmpty(); + } catch (Exception e) { + versions = new ArrayList(); + } } - + public String getPhoneModel() { return phoneModel; } - + public List getMirrorList() { return mirrorList; } diff --git a/systemproperties.jar b/systemproperties.jar new file mode 100644 index 0000000..2ccb945 Binary files /dev/null and b/systemproperties.jar differ diff --git a/tools/json.php b/tools/json.php new file mode 100644 index 0000000..94647fb --- /dev/null +++ b/tools/json.php @@ -0,0 +1,60 @@ +name = "CyanogenMod"; +$JSON->phoneModel = $device; +$JSON->versions = array(); +$JSON->mirrorList = array(); + +if (strpos($agent,"MB525") !== false || (strpos($agent,"Apache-HttpClient") !== false && $device == "MB525")) { + + $JSON->versions = json_decode( <<versions as $v) { + $v->uri = "http://".$_SERVER['SERVER_NAME']."/romupdater/mb525.php?v="; + } + + echo json_encode($JSON)."\n"; + @ file_put_contents("main.json", json_encode($JSON)); + +} elseif (strpos($agent,"MB526") !== false || strpos($agent,"Apache-HttpClient") !== false) { + + // you can create a db or list files from your server here... + + $JSON->versions = json_decode( <<versions as $v) { + $v->uri = "http://".$_SERVER['SERVER_NAME']."/romupdater/mb526.php?v="; + } + + echo json_encode($JSON)."\n"; + + // cache generated file, debug purpose... + @ file_put_contents("MB526.json", json_encode($JSON)); + +} else { + echo "nothing here for you $agent\n"; +} +?> diff --git a/tools/mb526.php b/tools/mb526.php new file mode 100644 index 0000000..b74af59 --- /dev/null +++ b/tools/mb526.php @@ -0,0 +1,29 @@ + +{ + "full": "-Defy+.zip", + "fromVersion": [ + { "version":"7.1.0", "uri": "-Defy+.zip" } + ] +} +