/** * Returns the update source matching a specific name. Generally used with a source name stored in * the apps table. * * @param name The name of the source to retrieve. * @return The requested source, or null if it doesn't exist. */ public static UpdateSource get_source(String name) { if (get_update_sources() == null) { return null; } for (UpdateSource s : get_update_sources()) { if (name.equals(s.get_name())) { return s; } } return null; }
/** * Returns the name of all the update sources available for a given package. * * @param app The app we want to check against. * @return A list of names for UpdateSources that can be used to check the application's version. */ public static String[] get_sources(InstalledApp app) { ArrayList<String> res = new ArrayList<String>(); if (get_update_sources() == null) { return new String[] {}; } for (UpdateSource s : get_update_sources()) { if (s.is_applicable(app)) { res.add(s.get_name()); } } String[] retval = new String[res.size()]; res.toArray(retval); return retval; }
/** * Returns the update source set for an app, or the first applicable one. * * @param app The target application. * @return An update source that can be used for this application, or null if no source could be * found. */ public static UpdateSource get_source(InstalledApp app) { if (get_update_sources() == null) { return null; } // Return the stored update source first, if available. if (app.get_update_source() != null) { UpdateSource s = get_source(app.get_update_source()); if (s != null) { // False if the source has been removed from assets.json return s; } } // Find the first applicable source. for (UpdateSource s : get_update_sources()) { if (s.is_applicable(app)) { return s; } } return null; }
/** * This method tries to guess the best update source for a given app based on its signature. * * @param pi The PackageInfo object returned by the PackageManager * @return An adequate update source for the app, or null if auto-disvocery must take place. */ public static UpdateSource guess_update_source(PackageInfo pi) { android.content.pm.Signature[] signs = pi.signatures; for (Signature sign : signs) { X509Certificate cert; try { cert = (X509Certificate) CertificateFactory.getInstance("X509") .generateCertificate(new ByteArrayInputStream(sign.toByteArray())); } catch (CertificateException e) { Log.v(MainActivity.TAG, "Error while reading " + pi.packageName + "'s certificate."); return null; } String[] details = cert.getSubjectDN().getName().split(","); for (UpdateSource us : get_update_sources()) { if (us.test_autoselection(pi.packageName, Arrays.asList(details))) { return us; } } } return null; }
/** * Initializes the update sources by reading the ones available in sources.json. They are kept in * memory in order to avoid looking them up in the assets every time. * * @param ctx The context of the application. */ public static void initialize_update_sources(Context ctx) { if (_SOURCES != null) { return; } _SOURCES = new ArrayList<UpdateSource>(); Log.v(MainActivity.TAG, "Reading update sources..."); try { InputStream is = ctx.getAssets().open("sources.json"); StringBuilder buffer = new StringBuilder(); BufferedReader br = new BufferedReader(new InputStreamReader(is, "UTF-8")); String s; while ((s = br.readLine()) != null) { buffer.append(s); } JSONArray sources = new JSONArray(buffer.toString()); for (int i = 0; i < sources.length(); ++i) { String name = sources.getJSONObject(i).getString("name"); Log.v(MainActivity.TAG, "Reading " + name); String url = sources.getJSONObject(i).getString("url"); // Get the list of regular expressions and URLs for each supported package name. JSONObject packages = sources.getJSONObject(i).optJSONObject("packages"); if (packages == null || packages.length() == 0) { throw new JSONException("packages missing or empty for " + name); } ArrayList<UpdateSourceEntry> entries = new ArrayList<UpdateSourceEntry>(); Iterator<String> it = packages.keys(); while (it.hasNext()) { String applicable_packages = it.next(); JSONObject entry = packages.getJSONObject(applicable_packages); UpdateSourceEntry use = new UpdateSourceEntry(applicable_packages); use.set_version_regexp(entry.getString("version")); try { use.set_download_regexp(entry.getString("download_regexp")); } catch (JSONException ignored) { } try { use.set_download_url(entry.getString("download")); } catch (JSONException ignored) { } try { use.set_changelog_regexp(entry.getString("changelog")); } catch (JSONException ignored) { } entries.add(use); } UpdateSource us = new UpdateSource(name, url, entries); // Get autoselection conditions if available: JSONArray conditions = sources.getJSONObject(i).optJSONArray("autoselect_if"); if (conditions != null) { List<String> autoselect_conditions = new ArrayList<String>(); for (int j = 0; j < conditions.length(); ++j) { autoselect_conditions.add(conditions.getString(j)); } if (autoselect_conditions.size() > 0) { us.set_autoselect_conditions(autoselect_conditions); } } // Get optional request delay (in milliseconds) int delay = sources.getJSONObject(i).optInt("request_delay", 0); if (delay > 0) { us.set_request_delay(delay); } _SOURCES.add(us); } } catch (IOException e) { Log.e(MainActivity.TAG, "Could not open sources.json!", e); } catch (JSONException e) { Log.e(MainActivity.TAG, "sources.json seems to be malformed!", e); } }