/*-
* Copyright 2010 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.
*/
package com.google.authenticator.blackberry;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.Reader;
import javax.microedition.io.Connector;
import javax.microedition.io.HttpConnection;
import net.rim.device.api.i18n.Locale;
import net.rim.device.api.system.Application;
import net.rim.device.api.system.ApplicationDescriptor;
import net.rim.device.api.system.ApplicationManager;
import net.rim.device.api.system.Branding;
import net.rim.device.api.system.DeviceInfo;
/**
* Checks for software updates and invokes a callback if one is found.
*/
public class UpdateTask extends Thread {
private static String getApplicationVersion() {
ApplicationDescriptor app = ApplicationDescriptor
.currentApplicationDescriptor();
return app.getVersion();
}
private static String getPlatformVersion() {
ApplicationManager manager = ApplicationManager.getApplicationManager();
ApplicationDescriptor[] applications = manager.getVisibleApplications();
for (int i = 0; i < applications.length; i++) {
ApplicationDescriptor application = applications[i];
String moduleName = application.getModuleName();
if (moduleName.equals("net_rim_bb_ribbon_app")) {
return application.getVersion();
}
}
return null;
}
private static String getUserAgent() {
String deviceName = DeviceInfo.getDeviceName();
String version = getPlatformVersion();
String profile = System.getProperty("microedition.profiles");
String configuration = System.getProperty("microedition.configuration");
String applicationVersion = getApplicationVersion();
int vendorId = Branding.getVendorId();
return "BlackBerry" + deviceName + "/" + version + " Profile/" + profile
+ " Configuration/" + configuration + " VendorID/" + vendorId
+ " Application/" + applicationVersion;
}
private static String getLanguage() {
Locale locale = Locale.getDefault();
return locale.getLanguage();
}
private static String getEncoding(HttpConnection c) throws IOException {
String enc = "ISO-8859-1";
String contentType = c.getHeaderField("Content-Type");
if (contentType != null) {
String prefix = "charset=";
int beginIndex = contentType.indexOf(prefix);
if (beginIndex != -1) {
beginIndex += prefix.length();
int endIndex = contentType.indexOf(';', beginIndex);
if (endIndex != -1) {
enc = contentType.substring(beginIndex, endIndex);
} else {
enc = contentType.substring(beginIndex);
}
}
}
return enc.trim();
}
private static HttpConnection connect(String url) throws IOException {
if (DeviceInfo.isSimulator()) {
url += ";deviceside=true";
} else {
url += ";deviceside=false;ConnectionType=mds-public";
}
return (HttpConnection) Connector.open(url);
}
private final UpdateCallback mCallback;
public UpdateTask(UpdateCallback callback) {
if (callback == null) {
throw new NullPointerException();
}
mCallback = callback;
}
private String getMIDletVersion(Reader reader) throws IOException {
BufferedReader r = new BufferedReader(reader);
String prefix = "MIDlet-Version:";
for (String line = r.readLine(); line != null; line = r.readLine()) {
if (line.startsWith(prefix)) {
int beginIndex = prefix.length();
String value = line.substring(beginIndex);
return value.trim();
}
}
return null;
}
/**
* {@inheritDoc}
*/
public void run() {
try {
// Visit the original download URL and read the JAD;
// if the MIDlet-Version has changed, invoke the callback.
String url = Build.DOWNLOAD_URL;
String applicationVersion = getApplicationVersion();
String userAgent = getUserAgent();
String language = getLanguage();
for (int redirectCount = 0; redirectCount < 10; redirectCount++) {
HttpConnection c = null;
InputStream s = null;
try {
c = connect(url);
c.setRequestMethod(HttpConnection.GET);
c.setRequestProperty("User-Agent", userAgent);
c.setRequestProperty("Accept-Language", language);
int responseCode = c.getResponseCode();
if (responseCode == HttpConnection.HTTP_MOVED_PERM
|| responseCode == HttpConnection.HTTP_MOVED_TEMP) {
String location = c.getHeaderField("Location");
if (location != null) {
url = location;
continue;
} else {
throw new IOException("Location header missing");
}
} else if (responseCode != HttpConnection.HTTP_OK) {
throw new IOException("Unexpected response code: " + responseCode);
}
s = c.openInputStream();
String enc = getEncoding(c);
Reader reader = new InputStreamReader(s, enc);
final String version = getMIDletVersion(reader);
if (version == null) {
throw new IOException("MIDlet-Version not found");
} else if (!version.equals(applicationVersion)) {
Application application = Application.getApplication();
application.invokeLater(new Runnable() {
public void run() {
mCallback.onUpdate(version);
}
});
} else {
// Already running latest version
}
} finally {
if (s != null) {
s.close();
}
if (c != null) {
c.close();
}
}
}
} catch (Exception e) {
System.out.println(e);
}
}
}