Bug 827347 - Allow force-downloading and installing of updates from about:firefox. r=snorp,blassey

This commit is contained in:
Kartikaya Gupta 2013-03-13 15:47:38 +00:00
Родитель 1c55925879
Коммит d976ddfc04
8 изменённых файлов: 95 добавлений и 35 удалений

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

@ -852,6 +852,10 @@ abstract public class GeckoApp
handleClearHistory();
} else if (event.equals("Update:Check")) {
startService(new Intent(UpdateServiceHelper.ACTION_CHECK_FOR_UPDATE, null, this, UpdateService.class));
} else if (event.equals("Update:Download")) {
startService(new Intent(UpdateServiceHelper.ACTION_DOWNLOAD_UPDATE, null, this, UpdateService.class));
} else if (event.equals("Update:Install")) {
startService(new Intent(UpdateServiceHelper.ACTION_APPLY_UPDATE, null, this, UpdateService.class));
} else if (event.equals("PrivateBrowsing:Data")) {
// null strings return "null" (http://code.google.com/p/android/issues/detail?id=13830)
if (message.isNull("session")) {
@ -1676,6 +1680,8 @@ abstract public class GeckoApp
registerEventListener("Wallpaper:Set");
registerEventListener("Sanitize:ClearHistory");
registerEventListener("Update:Check");
registerEventListener("Update:Download");
registerEventListener("Update:Install");
registerEventListener("PrivateBrowsing:Data");
if (SmsManager.getInstance() != null) {
@ -2066,6 +2072,8 @@ abstract public class GeckoApp
unregisterEventListener("Wallpaper:Set");
unregisterEventListener("Sanitize:ClearHistory");
unregisterEventListener("Update:Check");
unregisterEventListener("Update:Download");
unregisterEventListener("Update:Install");
unregisterEventListener("PrivateBrowsing:Data");
deleteTempFiles();
@ -2440,8 +2448,8 @@ abstract public class GeckoApp
}
}
public void notifyCheckUpdateResult(boolean result) {
GeckoAppShell.sendEventToGecko(GeckoEvent.createBroadcastEvent("Update:CheckResult", result ? "true" : "false"));
public void notifyCheckUpdateResult(String result) {
GeckoAppShell.sendEventToGecko(GeckoEvent.createBroadcastEvent("Update:CheckResult", result));
}
protected void connectGeckoLayerClient() {

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

@ -2155,11 +2155,6 @@ public class GeckoAppShell
((SurfaceTexture)surfaceTexture).setOnFrameAvailableListener(null);
}
public static void notifyCheckUpdateResult(boolean result) {
if (GeckoApp.mAppContext != null)
GeckoApp.mAppContext.notifyCheckUpdateResult(result);
}
public static boolean unlockProfile() {
// Try to kill any zombie Fennec's that might be running
GeckoAppShell.killAnyZombies();

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

@ -15,7 +15,10 @@ public class GeckoUpdateReceiver
@Override
public void onReceive(Context context, Intent intent) {
if (UpdateServiceHelper.ACTION_CHECK_UPDATE_RESULT.equals(intent.getAction())) {
GeckoAppShell.notifyCheckUpdateResult(intent.getBooleanExtra("result", false));
String result = intent.getStringExtra("result");
if (GeckoApp.mAppContext != null && result != null) {
GeckoApp.mAppContext.notifyCheckUpdateResult(result);
}
}
}
}

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

@ -62,6 +62,7 @@ public class UpdateService extends IntentService {
private static final String KEY_LAST_BUILDID = "UpdateService.lastBuildID";
private static final String KEY_LAST_HASH_FUNCTION = "UpdateService.lastHashFunction";
private static final String KEY_LAST_HASH_VALUE = "UpdateService.lastHashValue";
private static final String KEY_LAST_FILE_NAME = "UpdateService.lastFileName";
private static final String KEY_LAST_ATTEMPT_DATE = "UpdateService.lastAttemptDate";
private static final String KEY_AUTODOWNLOAD_POLICY = "UpdateService.autoDownloadPolicy";
@ -126,9 +127,9 @@ public class UpdateService extends IntentService {
return (flags & flag) == flag;
}
private void sendCheckUpdateResult(boolean result) {
private void sendCheckUpdateResult(UpdateServiceHelper.CheckUpdateResult result) {
Intent resultIntent = new Intent(UpdateServiceHelper.ACTION_CHECK_UPDATE_RESULT);
resultIntent.putExtra("result", result);
resultIntent.putExtra("result", result.toString());
sendBroadcast(resultIntent);
}
@ -180,7 +181,7 @@ public class UpdateService extends IntentService {
if (netInfo == null || !netInfo.isConnected()) {
Log.i(LOGTAG, "not connected to the network");
registerForUpdates(true);
sendCheckUpdateResult(false);
sendCheckUpdateResult(UpdateServiceHelper.CheckUpdateResult.NOT_AVAILABLE);
return;
}
@ -188,10 +189,10 @@ public class UpdateService extends IntentService {
UpdateInfo info = findUpdate(hasFlag(flags, UpdateServiceHelper.FLAG_REINSTALL));
boolean haveUpdate = (info != null);
sendCheckUpdateResult(haveUpdate);
if (!haveUpdate) {
Log.i(LOGTAG, "no update available");
sendCheckUpdateResult(UpdateServiceHelper.CheckUpdateResult.NOT_AVAILABLE);
return;
}
@ -215,6 +216,7 @@ public class UpdateService extends IntentService {
if (!shouldStartDownload) {
Log.i(LOGTAG, "not initiating automatic update download due to policy " + autoDownloadPolicy);
sendCheckUpdateResult(UpdateServiceHelper.CheckUpdateResult.AVAILABLE);
// We aren't autodownloading here, so prompt to start the update
Notification notification = new Notification(R.drawable.ic_status_logo, null, System.currentTimeMillis());
@ -235,12 +237,15 @@ public class UpdateService extends IntentService {
}
File pkg = downloadUpdatePackage(info, hasFlag(flags, UpdateServiceHelper.FLAG_OVERWRITE_EXISTING));
if (pkg == null)
if (pkg == null) {
sendCheckUpdateResult(UpdateServiceHelper.CheckUpdateResult.NOT_AVAILABLE);
return;
}
Log.i(LOGTAG, "have update package at " + pkg);
saveUpdateInfo(info);
saveUpdateInfo(info, pkg);
sendCheckUpdateResult(UpdateServiceHelper.CheckUpdateResult.DOWNLOADED);
if (mApplyImmediately) {
applyUpdate(pkg);
@ -409,6 +414,7 @@ public class UpdateService extends IntentService {
}
Log.i(LOGTAG, "downloading update package");
sendCheckUpdateResult(UpdateServiceHelper.CheckUpdateResult.DOWNLOADING);
OutputStream output = null;
InputStream input = null;
@ -495,6 +501,9 @@ public class UpdateService extends IntentService {
}
private void applyUpdate(String updatePath) {
if (updatePath == null) {
updatePath = mPrefs.getString(KEY_LAST_FILE_NAME, null);
}
applyUpdate(new File(updatePath));
}
@ -555,11 +564,12 @@ public class UpdateService extends IntentService {
editor.commit();
}
private void saveUpdateInfo(UpdateInfo info) {
private void saveUpdateInfo(UpdateInfo info, File downloaded) {
SharedPreferences.Editor editor = mPrefs.edit();
editor.putString(KEY_LAST_BUILDID, info.buildID);
editor.putString(KEY_LAST_HASH_FUNCTION, info.hashFunction);
editor.putString(KEY_LAST_HASH_VALUE, info.hashValue);
editor.putString(KEY_LAST_FILE_NAME, downloaded.toString());
editor.commit();
}

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

@ -61,6 +61,14 @@ public class UpdateServiceHelper {
private static final String UPDATE_URL = "https://aus2.mozilla.org/update/4/@MOZ_APP_BASENAME@/@MOZ_APP_VERSION@/%BUILDID%/Android_@MOZ_APP_ABI@/%LOCALE%/@MOZ_UPDATE_CHANNEL@/%OS_VERSION%/default/default/@MOZ_APP_VERSION@/update.xml";
#endif
public enum CheckUpdateResult {
// Keep these in sync with mobile/android/chrome/content/about.xhtml
NOT_AVAILABLE,
AVAILABLE,
DOWNLOADING,
DOWNLOADED
}
public static URL getUpdateUrl(Context context, boolean force) {
PackageManager pm = context.getPackageManager();

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

@ -34,7 +34,9 @@
<a id="updateLink" href="" onclick="checkForUpdates();">&aboutPage.checkForUpdates.link;</a>
<span id="update-message-checking">&aboutPage.checkForUpdates.checking;</span>
<span id="update-message-none">&aboutPage.checkForUpdates.none;</span>
<span id="update-message-found">&aboutPage.checkForUpdates.found;</span>
<span id="update-message-found" onclick="downloadUpdate()">&aboutPage.checkForUpdates.found;</span>
<span id="update-message-downloading">&aboutPage.checkForUpdates.downloading;</span>
<span id="update-message-downloaded" onclick="installUpdate()">&aboutPage.checkForUpdates.downloaded;</span>
</div>
#endif
@ -125,7 +127,6 @@
#ifdef MOZ_UPDATER
let Updater = {
isChecking: false,
update: null,
init: function() {
@ -134,7 +135,7 @@
observe: function(aSubject, aTopic, aData) {
if (aTopic == "Update:CheckResult") {
showUpdateMessage(aData == "true");
showUpdateMessage(aData);
}
},
};
@ -142,42 +143,73 @@
Updater.init();
function checkForUpdates() {
Updater.isChecking = true;
showCheckingMessage();
let bridge = Cc["@mozilla.org/android/bridge;1"].getService(Ci.nsIAndroidBridge);
bridge.handleGeckoMessage(JSON.stringify({ type: "Update:Check" }));
}
function downloadUpdate() {
let bridge = Cc["@mozilla.org/android/bridge;1"].getService(Ci.nsIAndroidBridge);
bridge.handleGeckoMessage(JSON.stringify({ type: "Update:Download" }));
}
function installUpdate() {
showCheckAction();
let bridge = Cc["@mozilla.org/android/bridge;1"].getService(Ci.nsIAndroidBridge);
bridge.handleGeckoMessage(JSON.stringify({ type: "Update:Install" }));
}
let updateLink = document.getElementById("updateLink");
let checkingSpan = document.getElementById("update-message-checking");
let noneSpan = document.getElementById("update-message-none");
let foundSpan = document.getElementById("update-message-found");
let downloadingSpan = document.getElementById("update-message-downloading");
let downloadedSpan = document.getElementById("update-message-downloaded");
function showCheckAction() {
checkingSpan.style.display = "none";
noneSpan.style.display = "none";
foundSpan.style.display = "none";
downloadingSpan.style.display = "none";
downloadedSpan.style.display = "none";
updateLink.style.display = "block";
}
function showCheckingMessage() {
updateLink.style.display = "none";
noneSpan.style.display = "none";
foundSpan.style.display = "none";
downloadingSpan.style.display = "none";
downloadedSpan.style.display = "none";
checkingSpan.style.display = "block";
}
function showUpdateMessage(aHasUpdate) {
function showUpdateMessage(aResult) {
updateLink.style.display = "none";
checkingSpan.style.display = "none";
if (aHasUpdate) {
noneSpan.style.display = "none";
foundSpan.style.display = "block";
} else {
foundSpan.style.display = "none";
noneSpan.style.display = "block";
}
noneSpan.style.display = "none";
foundSpan.style.display = "none";
downloadingSpan.style.display = "none";
downloadedSpan.style.display = "none";
setTimeout(function() {
noneSpan.style.display = "none";
foundSpan.style.display = "none";
checkingSpan.style.display = "none";
updateLink.style.display = "block";
}, 2000);
// the aResult values come from mobile/android/base/UpdateServiceHelper.java
switch (aResult) {
case "NOT_AVAILABLE":
noneSpan.style.display = "block";
setTimeout(showCheckAction, 2000);
break;
case "AVAILABLE":
foundSpan.style.display = "block";
break;
case "DOWNLOADING":
downloadingSpan.style.display = "block";
break;
case "DOWNLOADED":
downloadedSpan.style.display = "block";
break;
}
}
#endif
]]></script>

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

@ -9,7 +9,9 @@
<!ENTITY aboutPage.checkForUpdates.link "Check for Updates »">
<!ENTITY aboutPage.checkForUpdates.checking "Looking for updates…">
<!ENTITY aboutPage.checkForUpdates.none "No updates available">
<!ENTITY aboutPage.checkForUpdates.found "Update available">
<!ENTITY aboutPage.checkForUpdates.found "Update available; click to download">
<!ENTITY aboutPage.checkForUpdates.downloading "Downloading update…">
<!ENTITY aboutPage.checkForUpdates.downloaded "Update downloaded; click to install">
<!ENTITY aboutPage.faq.label "FAQ">
<!ENTITY aboutPage.support.label "Support">
<!ENTITY aboutPage.privacyPolicy.label "Privacy Policy">

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

@ -59,7 +59,9 @@ body {
#update-message-checking,
#update-message-none,
#update-message-found {
#update-message-found,
#update-message-downloading,
#update-message-downloaded {
display: none;
}