/* * Copyright (C) 2013 Fairphone Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.fairphone.updater; import org.xmlpull.v1.XmlPullParser; import org.xmlpull.v1.XmlPullParserException; import org.xmlpull.v1.XmlPullParserFactory; import android.content.Context; import android.os.Environment; import android.util.Log; import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.util.NoSuchElementException; import java.util.Scanner; public class VersionParserHelper { private static final String TAG = VersionParserHelper.class.getSimpleName(); public static final String RECOVERY_PATH = "sdcard"; public static final String UPDATER_FOLDER = "/updater/"; private static final String CURRENT_FAIRPHONE_VERSION_NAME = "fairphone.ota.version.name"; private static final String CURRENT_FAIRPHONE_VERSION = "fairphone.ota.version"; private static final String CURRENT_ANDROID_VERSION = "fairphone.ota.android"; public static String getNameFromVersion(Version version) { return "fp_update_" + version.getNumber() + ".zip"; } public static Version getDeviceVersion(Context context) { Version version = new Version(); version.setNumber(getSystemData(context, CURRENT_FAIRPHONE_VERSION)); version.setName(getSystemData(context, CURRENT_FAIRPHONE_VERSION_NAME)); version.setAndroid(getSystemData(context, CURRENT_ANDROID_VERSION)); return version; } public static String getSystemData(Context context, String property) { if (property.equals(CURRENT_FAIRPHONE_VERSION)){ return getprop(CURRENT_FAIRPHONE_VERSION, context.getResources().getString(R.string.defaultVersionNumber)); } if (property.equals(CURRENT_FAIRPHONE_VERSION_NAME)){ return getprop(CURRENT_FAIRPHONE_VERSION_NAME, context.getResources().getString(R.string.defaultVersionName)); } if (property.equals(CURRENT_ANDROID_VERSION)){ return getprop(CURRENT_ANDROID_VERSION, context.getResources().getString(R.string.defaultAndroidVersionNumber)); } return null; } public static void removeLatestVersionFile(Context context){ File file = new File(Environment.getExternalStorageDirectory() + UPDATER_FOLDER + context.getResources().getString(R.string.versionFilename)); if(file.exists()){ file.delete(); } } public static Version getLastestVersion(Context context) { Version latest = Version.getVersionFromSharedPreferences(context); if(latest == null){ String filePath = Environment.getExternalStorageDirectory() + VersionParserHelper.UPDATER_FOLDER + context.getResources().getString(R.string.versionFilename); // check the /storage/sdcard0/updater/latest.xml File file = new File(filePath + context.getResources().getString(R.string.versionFilename_xml)); if (file.exists()) { try { latest = parseLatestXML(context, file); } catch (XmlPullParserException e) { Log.e(TAG, "Could not start the XML parser", e); } catch (IOException e) { Log.e(TAG, "Invalid data in File", e); // remove the files removeFiles(context); } } } return latest; } private static Version parseLatestXML(Context context, File latestFile) throws XmlPullParserException, IOException { Version version = null; XmlPullParserFactory factory = XmlPullParserFactory.newInstance(); factory.setNamespaceAware(true); FileInputStream fis = new FileInputStream(latestFile); XmlPullParser xpp = factory.newPullParser(); xpp.setInput(new InputStreamReader(fis)); int eventType = xpp.getEventType(); while (eventType != XmlPullParser.END_DOCUMENT) { String tagName = null; switch (eventType) { case XmlPullParser.START_DOCUMENT: break; case XmlPullParser.START_TAG: tagName = xpp.getName(); if (tagName.equalsIgnoreCase("version")) { version = new Version(); version.setNumber(xpp.getAttributeValue(0)); } else if (version != null) { if (tagName.equalsIgnoreCase("name")) { version.setName(xpp.nextText()); } else if (tagName.equalsIgnoreCase("android")) { version.setAndroid(xpp.nextText()); } else if (tagName.equalsIgnoreCase("md5sum")) { version.setMd5Sum(xpp.nextText()); } else if (tagName.equalsIgnoreCase("link")) { version.setDownloadLink(xpp.nextText()); } } break; } eventType = xpp.next(); } if (version == null || version.getNumber() == null || version.getName() == null || version.getAndroid() == null || version.getDownloadLink() == null) { Log.i(TAG, "Invalid data in version file"); version = null; }else { version.saveToSharedPreferences(context); } return version; } private static String getprop(String name, String defaultValue) { ProcessBuilder pb = new ProcessBuilder("/system/bin/getprop", name); pb.redirectErrorStream(true); Process p = null; InputStream is = null; try { p = pb.start(); is = p.getInputStream(); Scanner scan = new Scanner(is); scan.useDelimiter("\n"); String prop = scan.next(); if (prop.length() == 0) { return defaultValue; } return prop; } catch (NoSuchElementException e) { return defaultValue; } catch (Exception e) { e.printStackTrace(); } finally { if (is != null) { try { is.close(); } catch (Exception e) { } } } return defaultValue; } public static void removeFiles(Context context) { String filePath = Environment.getExternalStorageDirectory() + VersionParserHelper.UPDATER_FOLDER + context.getResources().getString(R.string.versionFilename); removeFile(filePath + context.getResources().getString(R.string.versionFilename_zip)); removeFile(filePath + context.getResources().getString(R.string.versionFilename_xml)); removeFile(filePath + context.getResources().getString(R.string.versionFilename_sig)); } private static void removeFile(String filePath) { File file = new File(filePath); if(file.exists()){ file.delete(); } } }