/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the Common Development
* and Distribution License (the "License").
* You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at
* src/com/vodafone360/people/VODAFONE.LICENSE.txt or
* http://github.com/360/360-Engine-for-Android
* See the License for the specific language governing permissions and
* limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each file and
* include the License file at src/com/vodafone360/people/VODAFONE.LICENSE.txt.
* If applicable, add the following below this CDDL HEADER, with the fields
* enclosed by brackets "[]" replaced with your own identifying information:
* Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*
* Copyright 2010 Vodafone Sales & Services Ltd. All rights reserved.
* Use is subject to license terms.
*/
package com.vodafone360.people.engine.upgrade;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;
import android.content.Context;
import com.vodafone360.people.Settings;
import com.vodafone360.people.SettingsManager;
import com.vodafone360.people.engine.BaseEngine;
import com.vodafone360.people.engine.IEngineEventCallback;
import com.vodafone360.people.engine.EngineManager.EngineId;
import com.vodafone360.people.service.ServiceStatus;
import com.vodafone360.people.service.ServiceUiRequest;
import com.vodafone360.people.service.agent.NetworkAgent;
import com.vodafone360.people.service.agent.NetworkAgent.AgentState;
import com.vodafone360.people.service.io.ResponseQueue.DecodedResponse;
import com.vodafone360.people.utils.CloseUtils;
import com.vodafone360.people.utils.LogUtils;
import com.vodafone360.people.utils.VersionUtils;
/**
* Checks Settings.UPGRADE_CHECK_URL for information on a software upgrade .
* Triggers a dialog in the UI when a newer application version is available
* Throttles UI events
*/
public class UpgradeEngine extends BaseEngine {
private Context mContext;
private UpgradeStatus mUpgradeStatus;
private long mCheckFrequencyMillis;
private long mNextRunTime = 0; // Run once
private boolean mForceOnce = false;
private boolean mActivated = false;
private UpgradeEngineNetworkThread mUpgradeEngineNetworkThread;
/**
* Constructor.
*
* @param context - the context to use
* @param eventCallback - the engine event client to use
*/
public UpgradeEngine(Context context, IEngineEventCallback eventCallback) {
super(eventCallback);
mActivated = SettingsManager.getProperty(Settings.UPGRADE_CHECK_URL_KEY) != null;
mEngineId = EngineId.UPGRADE_ENGINE;
mContext = context;
mCheckFrequencyMillis = UpgradeUtils.getCheckFrequency(context);
}
/**
* Return the mNextRunTime value if the feature is enabled.
*
* @return the mNextRunTime value if the feature is enabled.
*/
@Override
public long getNextRunTime() {
if (!mActivated) {
LogUtils.logV("UpgradeEngine.getNextRunTime() Not currently activated");
return -1;
}
if (isUiRequestOutstanding()) {
return 0;
}
if (NetworkAgent.getAgentState() != AgentState.CONNECTED) {
LogUtils.logD("UpgradeEngine.getNextRunTime() Not currently connected");
return -1;
}
if (mForceOnce) {
LogUtils.logD("UpgradeEngine.getNextRunTime() Engine forced to run");
return 0;
} else if (mCheckFrequencyMillis == -1) {
LogUtils.logD("UpgradeEngine.getNextRunTime() Upgrade feature disabled");
return -1;
} else {
// LogUtils.logV("UpgradeEngine.getNextRunTime() Returning [" +
// mNextRunTime + "] or in ["+(mNextRunTime -
// System.currentTimeMillis())+"ms]");
return mNextRunTime;
}
}
/**
* Trigger the UpgradeEngineNetworkThread if the feature is enabled.
*/
@Override
public void run() {
if (!mActivated) {
LogUtils.logE("UpgradeEngine.getNextRunTime() Not currently activated");
return;
}
if (NetworkAgent.getAgentState() != AgentState.CONNECTED) {
LogUtils.logE("UpgradeEngine.getNextRunTime() Not currently connected");
return;
}
if (isUiRequestOutstanding() && processUiQueue()) {
return;
}
if (!mForceOnce && mCheckFrequencyMillis == -1) {
LogUtils.logD("UpgradeEngine.run() Upgrade feature disabled");
return;
} else {
if (mUpgradeEngineNetworkThread == null || !mUpgradeEngineNetworkThread.isRunning()) {
// LogUtils.logV("UpgradeEngine.run() Start the UpgradeEngineNetworkThread mForceOnce["
// + mForceOnce + "]");
mUpgradeEngineNetworkThread = new UpgradeEngineNetworkThread();
mUpgradeEngineNetworkThread.start();
} else {
LogUtils.logD("UpgradeEngine.run() UpgradeEngineNetworkThread already running["
+ mForceOnce + "]");
}
}
setNextRuntime();
}
private void setNextRuntime() {
mForceOnce = false;
if (mCheckFrequencyMillis != -1) {
mNextRunTime = System.currentTimeMillis() + mCheckFrequencyMillis;
// LogUtils.logV("UpgradeEngine.setNextRuntime() Run again at [" +
// mNextRunTime + "] or in ["+(mNextRunTime -
// System.currentTimeMillis())+"ms], mCheckFrequencyMillis["+mCheckFrequencyMillis+"ms]");
} else {
LogUtils.logV("UpgradeEngine.setNextRuntime() mCheckFrequencyMillis["
+ mCheckFrequencyMillis + "] so return -1");
mNextRunTime = -1;
}
}
/**
* Thread for running an upgrade check without blocking the WorkerThread.
*/
private class UpgradeEngineNetworkThread extends Thread {
private static final String UPGRADE_THREAD_NAME = "UpgradeThread";
private boolean mRunning = true;
public UpgradeEngineNetworkThread() {
setName(UPGRADE_THREAD_NAME);
}
/**
* Check the Settings.UPGRADE_CHECK_URL file for information on a new
* software upgrade.
*/
@Override
public void run() {
LogUtils.logI("UpgradeEngine.UpgradeEngineNetworkThread.run() [Start Thread]");
mUpgradeStatus = new UpgradeStatus();
BufferedReader mBufferedReader = null;
try {
URL mUrl = new URL(SettingsManager.getProperty(Settings.UPGRADE_CHECK_URL_KEY)
+ "?currentversion=" + VersionUtils.getPackageVersionCode(mContext));
LogUtils.logV("UpgradeEngine.UpgradeEngineNetworkThread.run() Checking URL ["
+ mUrl + "]");
URLConnection mURLConnection = mUrl.openConnection();
mBufferedReader = new BufferedReader(new InputStreamReader(mURLConnection
.getInputStream(), "UTF-8"));
String mLine;
while ((mLine = mBufferedReader.readLine()) != null) {
mUpgradeStatus.addSetting(mLine);
}
mBufferedReader.close();
if (mUpgradeStatus.getLatestVersion() > VersionUtils.getPackageVersionCode(mContext)) {
// Show upgrade dialog
LogUtils.logD("UpgradeEngine.UpgradeEngineNetworkThread.run() New Version ["
+ mUpgradeStatus.getLatestVersion() + "] better than current ["
+ VersionUtils.getPackageVersionCode(mContext) + "]");
} else {
// Do nothing
LogUtils.logV("UpgradeEngine.UpgradeEngineNetworkThread.run() New Version ["
+ mUpgradeStatus.getLatestVersion() + "] is not better than current ["
+ VersionUtils.getPackageVersionCode(mContext) + "]");
mUpgradeStatus = null;
}
UpgradeUtils.cacheUpdate(mContext, mUpgradeStatus);
// Request to update the UI
completeUiRequest(ServiceStatus.SUCCESS, null);
if (mUpgradeStatus != null) {
mEventCallback.getUiAgent().sendUnsolicitedUiEvent(
ServiceUiRequest.UNSOLICITED_DIALOG_UPGRADE, null);
}
} catch (MalformedURLException e) {
LogUtils.logE(
"UpgradeEngine.UpgradeEngineNetworkThread.run() MalformedURLException", e);
} catch (IOException e) {
LogUtils.logE("UpgradeEngine.UpgradeEngineNetworkThread.run() IOException", e);
} finally {
CloseUtils.close(mBufferedReader);
}
mRunning = false;
LogUtils.logI("UpgradeEngine.UpgradeEngineNetworkThread.run() [Stop Thread]");
}
public boolean isRunning() {
return mRunning;
}
}
@Override
protected void processUiRequest(ServiceUiRequest requestId, Object data) {
switch (requestId) {
case UPGRADE_CHECK_NOW:
// Ensure that the UpgradeEngine will run the next time the
// WorkerThread is kicked
LogUtils.logW("UpgradeEngine.processUiRequest() UPGRADE_CHECK_NOW");
mForceOnce = true;
break;
case UPGRADE_CHANGE_FREQUENCY:
mCheckFrequencyMillis = UpgradeUtils.getCheckFrequency(mContext);
mNextRunTime = System.currentTimeMillis() + mCheckFrequencyMillis;
LogUtils.logW("UpgradeEngine.processUiRequest() mCheckFrequencyMillis["
+ mCheckFrequencyMillis + "] mNextRunTime[" + mNextRunTime + "]");
break;
default:
// Do nothing.
break;
}
}
@Override
public void onCreate() {
// Do nothing
}
@Override
public void onDestroy() {
// Do nothing
}
@Override
protected void onRequestComplete() {
// Do nothing
}
@Override
protected void onTimeoutEvent() {
// Do nothing
}
@Override
protected void processCommsResponse(DecodedResponse resp) {
// Do nothing
}
/**
* Sets a new value for the frequency with which to check for application
* updates.
*/
public void setNewUpdateFrequency() {
LogUtils.logD("UpgradeEngine.setNewUpdateFrequency()");
addUiRequestToQueue(ServiceUiRequest.UPGRADE_CHANGE_FREQUENCY, null);
}
/**
* Add request to check for application update.
*/
public void checkForUpdates() {
LogUtils.logD("UpgradeEngine.checkForUpdates()");
addUiRequestToQueue(ServiceUiRequest.UPGRADE_CHECK_NOW, null);
}
}