Bug 922694 - Part 2: expose distribution ID. r=margaret

This commit is contained in:
Richard Newman 2013-10-16 18:56:26 -07:00
Родитель a1fdb51981
Коммит 87f9bb7a83
1 изменённых файлов: 110 добавлений и 15 удалений

Просмотреть файл

@ -9,6 +9,7 @@ import org.mozilla.gecko.util.ThreadUtils;
import org.json.JSONArray; import org.json.JSONArray;
import org.json.JSONException; import org.json.JSONException;
import org.json.JSONObject;
import android.app.Activity; import android.app.Activity;
import android.content.Context; import android.content.Context;
@ -20,8 +21,12 @@ import java.io.FileOutputStream;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.io.OutputStream; import java.io.OutputStream;
import java.util.Scanner; import java.util.Collections;
import java.util.Enumeration; import java.util.Enumeration;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Scanner;
import java.util.zip.ZipEntry; import java.util.zip.ZipEntry;
import java.util.zip.ZipFile; import java.util.zip.ZipFile;
@ -32,6 +37,48 @@ public final class Distribution {
private static final int STATE_NONE = 1; private static final int STATE_NONE = 1;
private static final int STATE_SET = 2; private static final int STATE_SET = 2;
public static class DistributionDescriptor {
public final boolean valid;
public final String id;
public final String version; // Example uses a float, but that's a crazy idea.
// Default UI-visible description of the distribution.
public final String about;
// Each distribution file can include multiple localized versions of
// the 'about' string. These are represented as, e.g., "about.en-US"
// keys in the Global object.
// Here we map locale to description.
public final Map<String, String> localizedAbout;
@SuppressWarnings("unchecked")
public DistributionDescriptor(JSONObject obj) {
this.id = obj.optString("id");
this.version = obj.optString("version");
this.about = obj.optString("about");
Map<String, String> loc = new HashMap<String, String>();
try {
Iterator<String> keys = obj.keys();
while (keys.hasNext()) {
String key = keys.next();
if (key.startsWith("about.")) {
String locale = key.substring(6);
if (!obj.isNull(locale)) {
loc.put(locale, obj.getString(key));
}
}
}
} catch (JSONException ex) {
Log.w(LOGTAG, "Unable to completely process distribution JSON.", ex);
}
this.localizedAbout = Collections.unmodifiableMap(loc);
this.valid = (null != this.id) &&
(null != this.version) &&
(null != this.about);
}
}
/** /**
* Initializes distribution if it hasn't already been initalized. Sends * Initializes distribution if it hasn't already been initalized. Sends
* messages to Gecko as appropriate. * messages to Gecko as appropriate.
@ -217,9 +264,18 @@ public final class Distribution {
return null; return null;
} }
public JSONArray getBookmarks() { /**
* Helper to grab a file in the distribution directory.
*
* Returns null if there is no distribution directory or the file
* doesn't exist. Ensures init first.
*/
private File getDistributionFile(String name) {
Log.i(LOGTAG, "Getting file from distribution.");
if (this.state == STATE_UNKNOWN) { if (this.state == STATE_UNKNOWN) {
this.doInit(); if (!this.doInit()) {
return null;
}
} }
File dist = ensureDistributionDir(); File dist = ensureDistributionDir();
@ -227,24 +283,50 @@ public final class Distribution {
return null; return null;
} }
File bookmarks = new File(dist, "bookmarks.json"); File descFile = new File(dist, name);
if (!bookmarks.exists()) { if (!descFile.exists()) {
Log.e(LOGTAG, "Distribution directory exists, but no file named " + name);
return null;
}
return descFile;
}
public DistributionDescriptor getDescriptor() {
File descFile = getDistributionFile("preferences.json");
if (descFile == null) {
// Logging and existence checks are handled in getDistributionFile.
return null; return null;
} }
// Shortcut to slurp a file without messing around with streams.
try { try {
Scanner scanner = null; JSONObject all = new JSONObject(getFileContents(descFile));
try {
scanner = new Scanner(bookmarks, "UTF-8"); if (!all.has("Global")) {
final String contents = scanner.useDelimiter("\\A").next(); Log.e(LOGTAG, "Distribution preferences.json has no Global entry!");
return new JSONArray(contents); return null;
} finally {
if (scanner != null) {
scanner.close();
}
} }
return new DistributionDescriptor(all.getJSONObject("Global"));
} catch (IOException e) {
Log.e(LOGTAG, "Error getting distribution descriptor file.", e);
return null;
} catch (JSONException e) {
Log.e(LOGTAG, "Error parsing preferences.json", e);
return null;
}
}
public JSONArray getBookmarks() {
File bookmarks = getDistributionFile("bookmarks.json");
if (bookmarks == null) {
// Logging and existence checks are handled in getDistributionFile.
return null;
}
try {
return new JSONArray(getFileContents(bookmarks));
} catch (IOException e) { } catch (IOException e) {
Log.e(LOGTAG, "Error getting bookmarks", e); Log.e(LOGTAG, "Error getting bookmarks", e);
} catch (JSONException e) { } catch (JSONException e) {
@ -254,6 +336,19 @@ public final class Distribution {
return null; return null;
} }
// Shortcut to slurp a file without messing around with streams.
private String getFileContents(File file) throws IOException {
Scanner scanner = null;
try {
scanner = new Scanner(file, "UTF-8");
return scanner.useDelimiter("\\A").next();
} finally {
if (scanner != null) {
scanner.close();
}
}
}
private String getDataDir() { private String getDataDir() {
return context.getApplicationInfo().dataDir; return context.getApplicationInfo().dataDir;
} }