Java tutorial
/* Copyright Statement: * * This software/firmware and related documentation ("MediaTek Software") are * protected under relevant copyright laws. The information contained herein * is confidential and proprietary to MediaTek Inc. and/or its licensors. * Without the prior written permission of MediaTek inc. and/or its licensors, * any reproduction, modification, use or disclosure of MediaTek Software, * and information contained herein, in whole or in part, shall be strictly prohibited. * * MediaTek Inc. (C) 2010. All rights reserved. * * BY OPENING THIS FILE, RECEIVER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES * THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE") * RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO RECEIVER ON * AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT. * NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE * SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR * SUPPLIED WITH THE MEDIATEK SOFTWARE, AND RECEIVER AGREES TO LOOK ONLY TO SUCH * THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. RECEIVER EXPRESSLY ACKNOWLEDGES * THAT IT IS RECEIVER'S SOLE RESPONSIBILITY TO OBTAIN FROM ANY THIRD PARTY ALL PROPER LICENSES * CONTAINED IN MEDIATEK SOFTWARE. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE FOR ANY MEDIATEK * SOFTWARE RELEASES MADE TO RECEIVER'S SPECIFICATION OR TO CONFORM TO A PARTICULAR * STANDARD OR OPEN FORUM. RECEIVER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND * CUMULATIVE LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE, * AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE, * OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY RECEIVER TO * MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE. * * The following software/firmware and/or related documentation ("MediaTek Software") * have been modified by MediaTek Inc. All revisions are subject to any receiver's * applicable license agreements with MediaTek Inc. */ package com.mediatek.systemupdate; import android.app.AlarmManager; import android.content.ComponentName; import android.content.Context; import android.content.Intent; import android.content.ServiceConnection; import android.net.Uri; import android.os.Bundle; import android.os.Handler; import android.os.IBinder; import android.os.Looper; import android.os.Message; import android.os.Messenger; import android.os.RemoteException; import android.os.SystemProperties; import android.widget.Toast; import com.mediatek.systemupdate.Util.DeviceInfo; import com.mediatek.xlog.Xlog; import org.apache.http.HttpEntity; import org.apache.http.HttpHost; import org.apache.http.HttpResponse; import org.apache.http.HttpStatus; import org.apache.http.StatusLine; import org.apache.http.client.CookieStore; import org.apache.http.client.entity.UrlEncodedFormEntity; import org.apache.http.client.methods.HttpPost; import org.apache.http.client.protocol.ClientContext; import org.apache.http.conn.ClientConnectionManager; import org.apache.http.conn.ConnectTimeoutException; import org.apache.http.conn.params.ConnManagerParams; import org.apache.http.conn.params.ConnPerRoute; import org.apache.http.conn.routing.HttpRoute; import org.apache.http.conn.scheme.PlainSocketFactory; import org.apache.http.conn.scheme.Scheme; import org.apache.http.conn.scheme.SchemeRegistry; import org.apache.http.conn.ssl.SSLSocketFactory; import org.apache.http.cookie.Cookie; import org.apache.http.impl.client.DefaultHttpClient; import org.apache.http.impl.conn.tsccm.ThreadSafeClientConnManager; import org.apache.http.impl.cookie.BasicClientCookie; import org.apache.http.message.BasicNameValuePair; import org.apache.http.params.BasicHttpParams; import org.apache.http.params.HttpConnectionParams; import org.apache.http.params.HttpParams; import org.apache.http.protocol.BasicHttpContext; import org.apache.http.protocol.HttpContext; import org.json.JSONException; import org.json.JSONObject; import java.io.ByteArrayOutputStream; import java.io.File; import java.io.IOException; import java.io.InputStream; import java.io.RandomAccessFile; import java.io.UnsupportedEncodingException; import java.net.SocketTimeoutException; import java.net.URLEncoder; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Calendar; import java.util.Date; import java.util.Map; /** * This is used to interact with server. */ final class HttpManager { private static final String TAG = "SystemUpdate/HttpManager"; private static final String FINGER_PRINT_NAME = "ro.build.fingerprint"; private static final String BUILD_TYPE_NAME = "ro.build.type"; private static final String ENG_LOAD_TAG = "eng"; private static final int SERVER_VERSION_REQUIRED = 1; private static HttpManager sHttpManager; private static SimpleDateFormat sDateFormat = new SimpleDateFormat(Util.DATE_FORMAT); private static final String NETTYPE_WIFI = "WIFI"; private static final String COOKIE_TAG = "PHPRAND"; private static final String COMMAND_FILE = "/cache/recovery/command"; private static final String COMMAND_PART2 = "COMMANDPART2"; private static final String OTA_PATH_IN_RECOVERY = "/sdcard/system_update/update.zip"; private static final String SYS_OPER_INTENT = "com.mediatek.intent.systemupdate.SysOperService"; private static final String WRITE_COMMAND_INTENT = "com.mediatek.intent.systemupdate.WriteCommandService"; private CookieStore mCookies = null; // to-do: handle Intent.ACTION_MEDIA_EJECT // private static boolean mEjectFlag = false; private static final long AUTO_DL_TIME = 3 * 60 * 60 * 1000; private static final int HTTP_RESPONSE_SUCCESS = 1000; private static final int HTTP_RESPONSE_AUTHEN_ERROR = 1002; private static final int HTTP_RESPONSE_ILLEGAL_ACCESS = 1004; private static final int HTTP_RESPONSE_TOKEN_REQUIRE = 1005; private static final int HTTP_RESPONSE_TOKEN_INVALID = 1006; private static final int HTTP_RESPONSE_SN_LOST = 1008; private static final int HTTP_RESPONSE_VERSION_REQUIRE = 1009; private static final int HTTP_RESPONSE_NO_NEW_VERSION = 1010; private static final int HTTP_RESPONSE_DATABASE_ERROR = 1103; private static final int HTTP_RESPONSE_PARAM_ERROR = 1104; private static final int HTTP_RESPONSE_VERSION_ILLEGAL = 1105; private static final int HTTP_RESPONSE_VERSION_DELETE = 1106; private static final int HTTP_RESPONSE_NETWORK_ERROR = 1201; private static final int HTTP_RESPONSE_REQUEST_TOO_LONG = 1202; private static final int HTTP_RESPONSE_DELTA_DELETE = 1900; private static final int HTTP_DETECTED_SDCARD_CRASH_OR_UNMOUNT = 1901; private static final int HTTP_DETECTED_SDCARD_ERROR = 1902; private static final int HTTP_DETECTED_SDCARD_INSUFFICENT = 1903; private static final int HTTP_FILE_NOT_EXIST = 1904; private static final int HTTP_UNKNOWN_ERROR = 2000; private static final int HTTP_SERVER_VERSION_ERROR = 2001; private static final int HTTP_RESPONSE_UNZIP_ERROR = 2002; private static final int HTTP_RESPONSE_UNZIP_CKSUM = 2003; private static final int PORT_NUMBER = 443; private static final int TIME_OUT = 30000; private static final int FAULT_TOLERANT_BUFFER = 1024; private static final int BUFFER_SIZE = 1024; private static final int NETWORK_ERROR_TOAST = 0; private static final int SERVER_VERSION_ERROR_TOAST = 1; private static final int MAX_SOCKET_CONNECTION = 20; private boolean mIsDownloading = false; private Handler mHandler; private Handler mToastHandler; private Context mContext = null; private DownloadInfo mDownloadInfo = null; private int mErrorCode = HTTP_RESPONSE_SUCCESS; private NotifyManager mNotification; private HttpParams mHttpParam; private ClientConnectionManager mHttpConnMgr; static HttpManager getInstance(Context context) { Xlog.i(TAG, "sHttpManager = " + sHttpManager); if (sHttpManager == null) { sHttpManager = new HttpManager(context); } return sHttpManager; } private HttpManager(Context context) { mContext = context; mDownloadInfo = DownloadInfo.getInstance(mContext); mNotification = new NotifyManager(mContext); initHttpParam(); initHttpClientMgr(); new Thread() { public void run() { Xlog.v(TAG, "thread run " + Thread.currentThread().getName()); Looper.prepare(); mToastHandler = new Handler(Looper.myLooper()) { @Override public void handleMessage(Message msg) { switch (msg.what) { case NETWORK_ERROR_TOAST: Toast.makeText(mContext, R.string.network_error, Toast.LENGTH_SHORT).show(); break; case SERVER_VERSION_ERROR_TOAST: Toast.makeText(mContext, R.string.server_version_error, Toast.LENGTH_LONG).show(); break; default: break; } } }; Looper.loop(); } }.start(); } void setMessageHandler(Handler handler) { mHandler = handler; Xlog.i(TAG, "setMessageHandler, mHandler = " + mHandler); } void resetMessageHandler(Handler handler) { Xlog.i(TAG, "resetMessageHandler"); if (mHandler == handler) { mHandler = null; Xlog.i(TAG, "resetMessageHandler"); } } void queryNewVersion() { mNotification.clearNotification(NotifyManager.NOTIFY_NEW_VERSION); if (!Util.isNetWorkAvailable(mContext, "")) { mErrorCode = HTTP_RESPONSE_NETWORK_ERROR; mDownloadInfo.setIfNeedRefresh(true); sendErrorMessage(); return; } resetDescriptionInfo(); mDownloadInfo.setQueryDate(sDateFormat.format(new Date())); if (!handsakeAuthentication()) { mDownloadInfo.setIfNeedRefresh(true); sendErrorMessage(); return; } if (!checkNewVersion()) { mDownloadInfo.setIfNeedRefresh(true); sendErrorMessage(); return; } Xlog.i(TAG, "onQueryNewVersion, hasNewVersion"); notifyNewVersion(); } void notifyNewVersion() { if (Util.getUpdateType() == Util.UPDATE_TYPES.OTA_UPDATE_ONLY) { mDownloadInfo.setIfNeedRefresh(false); mDownloadInfo.setIfNeedRefreshMenu(true); Util.setAlarm(mContext, AlarmManager.RTC_WAKEUP, Calendar.getInstance().getTimeInMillis() + Util.REFRESHTIME, Util.Action.ACTION_REFRESH_TIME_OUT); if (mHandler != null) { mHandler.sendMessage(mHandler.obtainMessage(SystemUpdateService.MSG_NOTIFY_QUERY_DONE)); Xlog.i(TAG, "onQueryNewVersion, Send new version founded message."); } else { mNotification.showNewVersionNotification(); } } } void resetDescriptionInfo() { Xlog.i(TAG, "resetDescriptionInfo"); resetDownloadFile(); mDownloadInfo.resetDownloadInfo(); } void resetDownloadFile() { if (doBindService(mContext)) { notifySysoper(MSG_DELETE_COMMANDFILE); } Util.deleteFile(Util.getPackagePathName(mContext)); } private boolean handsakeAuthentication() { String url = ServerAddrReader.getInstance().getLoginAddress(); if (url == null) { url = mContext.getResources().getString(R.string.address_login); } mCookies = null; DeviceInfo deviceInfo = Util.getDeviceInfo(mContext); if (deviceInfo == null) { Xlog.i(TAG, "onHandsakeAuthentication, deviceInfo is null"); return false; } Xlog.i(TAG, "onHandsakeAuthentication, imei = " + deviceInfo.mImei + ", sn = " + deviceInfo.mSnNumber + ", sim = " + deviceInfo.mSim + ", operator = " + deviceInfo.mOperator); BasicNameValuePair imei = new BasicNameValuePair("imei", deviceInfo.mImei); // BasicNameValuePair sn = new BasicNameValuePair("sn", deviceInfo.sn); BasicNameValuePair sim = new BasicNameValuePair("sim", deviceInfo.mSim); BasicNameValuePair operator = new BasicNameValuePair("operator", deviceInfo.mOperator); BasicNameValuePair sn = new BasicNameValuePair("sn", "15811375356"); ArrayList<BasicNameValuePair> bnvpa = new ArrayList<BasicNameValuePair>(); bnvpa.add(imei); bnvpa.add(sn); bnvpa.add(sim); bnvpa.add(operator); HttpResponse response = doPost(url, null, bnvpa); if (response == null) { mErrorCode = HTTP_UNKNOWN_ERROR; Xlog.i(TAG, "onHandsakeAuthentication, response = null"); return false; } StatusLine status = response.getStatusLine(); if (status.getStatusCode() != HttpStatus.SC_OK) { Xlog.i(TAG, "onHandsakeAuthentication, ReasonPhrase = " + status.getReasonPhrase()); mErrorCode = HTTP_RESPONSE_AUTHEN_ERROR; return false; } try { String content = getChunkedContent(response.getEntity()); Xlog.i(TAG, "onHandsakeAuthentication, response content = " + content); HttpResponseContent res = parseAuthenInfo(content); if (res == null) { return false; } BasicClientCookie cookie = new BasicClientCookie("PHPRAND", String.valueOf(res.mRand)); if (mCookies == null) { Xlog.e(TAG, "onHandsakeAuthentication: mCookies = null"); mErrorCode = HTTP_RESPONSE_NETWORK_ERROR; return false; } mCookies.addCookie(cookie); Xlog.i(TAG, "mCookies size = " + mCookies.getCookies().size()); Xlog.i(TAG, "onHandsakeAuthentication, rand = " + res.mRand + ", sessionId = " + res.mSessionId); } catch (IOException e) { e.printStackTrace(); return false; } return true; } private boolean checkNewVersion() { Xlog.i(TAG, "checkNewVersion"); String url = ServerAddrReader.getInstance().getCheckVersionAddress(); if (url == null) { url = mContext.getResources().getString(R.string.address_check_version); } try { String tokenCode = getToken(); if (tokenCode == null) { mErrorCode = HTTP_RESPONSE_AUTHEN_ERROR; return false; } BasicNameValuePair token = new BasicNameValuePair("token", URLEncoder.encode(tokenCode)); BasicNameValuePair version = new BasicNameValuePair("version", Util.getDeviceVersionInfo(mContext)); ArrayList<BasicNameValuePair> bnvpa = new ArrayList<BasicNameValuePair>(); bnvpa.add(version); bnvpa.add(token); HttpResponse response = doPost(url, null, bnvpa); if (response == null) { Xlog.i(TAG, "onCheckNewVersion: response = null"); mErrorCode = HTTP_UNKNOWN_ERROR; return false; } StatusLine status = response.getStatusLine(); if (status.getStatusCode() != HttpStatus.SC_OK) { Xlog.i(TAG, "onCheckNewVersion, ReasonPhrase = " + status.getReasonPhrase()); mCookies = null; mErrorCode = HTTP_RESPONSE_AUTHEN_ERROR; return false; } String content = getChunkedContent(response.getEntity()); Xlog.i(TAG, "onCheckNewVersion, response content = " + content); HttpResponseContent res = parseCheckVersionInfo(content); if (res == null) { return false; } if (res.mFileSize <= 0 || res.mPkgId < 0) { mErrorCode = HTTP_RESPONSE_NO_NEW_VERSION; Xlog.i(TAG, "onCheckNewVersion, fileSize = " + res.mFileSize + ", deltaId = " + res.mPkgId); return false; } if ((!res.mIsFullPkg) && (!checkFingerPrint(res.mFingerprint))) { mErrorCode = HTTP_RESPONSE_NO_NEW_VERSION; return false; } mDownloadInfo.setDLSessionDeltaId(res.mPkgId); mDownloadInfo.setFullPkgFlag(res.mIsFullPkg); mDownloadInfo.setUpdateImageSize(res.mFileSize); mDownloadInfo.setVersionNote(res.mReleaseNote); mDownloadInfo.setVerNum(res.mVersionName); mDownloadInfo.setAndroidNum(res.mAndroidNum); mDownloadInfo.setDLSessionStatus(DownloadInfo.STATE_NEWVERSION_READY); return true; } catch (IOException e) { e.printStackTrace(); mErrorCode = HTTP_RESPONSE_AUTHEN_ERROR; return false; } } private boolean checkFingerPrint(String fingerPrintPkg) { if (fingerPrintPkg != null) { fingerPrintPkg = fingerPrintPkg.trim(); } Xlog.i(TAG, "fingerPrintPkg = " + fingerPrintPkg); String fingerPrintLocal = SystemProperties.get(FINGER_PRINT_NAME); if (fingerPrintLocal != null) { fingerPrintLocal = fingerPrintLocal.trim(); Xlog.i(TAG, "fingerPrintLocal = " + fingerPrintLocal); return fingerPrintLocal.equals(fingerPrintPkg); } return false; } private void initHttpParam() { mHttpParam = new BasicHttpParams(); HttpConnectionParams.setConnectionTimeout(mHttpParam, TIME_OUT); HttpConnectionParams.setSoTimeout(mHttpParam, TIME_OUT); /** The default maximum number of connections allowed per host */ Xlog.d(TAG, " -----------set the max socket connect number 20--------------"); ConnPerRoute connPerRoute = new ConnPerRoute() { @Override public int getMaxForRoute(HttpRoute route) { return MAX_SOCKET_CONNECTION; } }; ConnManagerParams.setMaxConnectionsPerRoute(mHttpParam, connPerRoute); } private void initHttpClientMgr() { SchemeRegistry schemeRegistry = new SchemeRegistry(); schemeRegistry.register(new Scheme("http", PlainSocketFactory.getSocketFactory(), 80)); schemeRegistry.register(new Scheme("https", SSLSocketFactory.getSocketFactory(), 443)); mHttpConnMgr = new ThreadSafeClientConnManager(mHttpParam, schemeRegistry); } private HttpResponse doPost(String url, Map<String, String> headers, ArrayList<BasicNameValuePair> bnvpa) { Xlog.i(TAG, "doPost, url = " + url + ", mCookies = " + mCookies); HttpContext localcontext = new BasicHttpContext(); if (mCookies != null) { localcontext.setAttribute(ClientContext.COOKIE_STORE, mCookies); } HttpResponse response = null; try { HttpHost host = null; HttpPost httpPost = null; if (url.contains("https")) { Uri uri = Uri.parse(url); host = new HttpHost(uri.getHost(), PORT_NUMBER, uri.getScheme()); httpPost = new HttpPost(uri.getPath()); } else { httpPost = new HttpPost(url); } if (headers != null) { for (Map.Entry<String, String> entry : headers.entrySet()) { httpPost.addHeader(entry.getKey(), entry.getValue()); } } if (bnvpa != null) { httpPost.setEntity(new UrlEncodedFormEntity(bnvpa)); } DefaultHttpClient httpClient = new DefaultHttpClient(mHttpConnMgr, mHttpParam); try { if (url.contains("https")) { Xlog.i(TAG, "doPost, https"); response = httpClient.execute(host, httpPost); } else { Xlog.i(TAG, "doPost, http"); Xlog.i(TAG, "mHttpClient =" + httpClient + "httpPost = " + httpPost + "localcontext = " + localcontext); response = httpClient.execute(httpPost, localcontext); } if (mCookies == null) { mCookies = httpClient.getCookieStore(); Xlog.i(TAG, "mCookies size = " + mCookies.getCookies().size()); } return response; } catch (ConnectTimeoutException e) { e.printStackTrace(); mErrorCode = HTTP_RESPONSE_NETWORK_ERROR; } } catch (UnsupportedEncodingException e) { e.printStackTrace(); mErrorCode = HTTP_RESPONSE_NETWORK_ERROR; } catch (IOException e) { e.printStackTrace(); mErrorCode = HTTP_RESPONSE_NETWORK_ERROR; } return response; } private String getChunkedContent(HttpEntity entity) throws IOException { Xlog.i(TAG, "getChunkedContent, isChunked = " + Boolean.valueOf(entity.isChunked()).toString()); InputStream in = entity.getContent(); ByteArrayOutputStream swapStream = new ByteArrayOutputStream(); int rCount = 0; byte[] buff = new byte[BUFFER_SIZE]; try { while ((rCount = in.read(buff, 0, BUFFER_SIZE)) > 0) { swapStream.write(buff, 0, rCount); } return new String(swapStream.toByteArray()); } catch (IOException e) { e.printStackTrace(); onShutdownConn(); if (mDownloadInfo.getDLSessionStatus() == DownloadInfo.STATE_DOWNLOADING) { mDownloadInfo.setDLSessionStatus(DownloadInfo.STATE_PAUSEDOWNLOAD); Xlog.e(TAG, "getChunkedContent, exception to set pause state"); } mErrorCode = HTTP_RESPONSE_NETWORK_ERROR; return null; } } private HttpResponseContent parseAuthenInfo(String result) { if (result == null) { mErrorCode = HTTP_RESPONSE_AUTHEN_ERROR; Xlog.e(TAG, "parseAuthenInfo error: param is null"); return null; } try { JSONObject jo = new JSONObject(result); HttpResponseContent res = new HttpResponseContent(); if (jo.getInt("status") == HTTP_RESPONSE_SUCCESS) { // if (jo.has("server_version") // && (jo.getInt("server_version") >= SERVER_VERSION_REQUIRED)) { if (true) {//modify by wzb not check server version for ngm 20150924 res.mRand = jo.getInt("rand"); res.mSessionId = jo.getString("sessionId"); mErrorCode = HTTP_RESPONSE_SUCCESS; return res; } else { mErrorCode = HTTP_SERVER_VERSION_ERROR; return null; } } else { String info = jo.getString("info"); mErrorCode = jo.getInt("status"); Xlog.e(TAG, "parseAuthenInfo, error info = " + info); return null; } } catch (JSONException ex) { ex.printStackTrace(); onShutdownConn(); mErrorCode = HTTP_RESPONSE_NETWORK_ERROR; return null; } } private HttpResponseContent parseCheckVersionInfo(String result) { Xlog.i(TAG, "parseCheckVersionInfo"); try { JSONObject jo = new JSONObject(result); HttpResponseContent res = new HttpResponseContent(); if (jo.getInt("status") == HTTP_RESPONSE_SUCCESS) { Xlog.i(TAG, "HTTP_RESPONSE_SUCCESS"); res.mVersionName = jo.getString("name"); Xlog.i(TAG, "res.mVersionName = " + res.mVersionName); res.mFileSize = jo.getLong("size"); Xlog.i(TAG, "res.fileSize = " + res.mFileSize); res.mReleaseNote = jo.getString("release_notes"); Xlog.i(TAG, "res.releaseNote = " + res.mReleaseNote); if (jo.has("versionId")) { res.mPkgId = jo.getInt("versionId"); res.mIsFullPkg = true; Xlog.i(TAG, "full package: res.packageId = " + res.mPkgId); } else if (jo.has("deltaId")) { res.mPkgId = jo.getInt("deltaId"); res.mIsFullPkg = false; Xlog.i(TAG, "delta package: res.packageId = " + res.mPkgId); res.mFingerprint = jo.getString("fingerprint"); } Xlog.i(TAG, "res.packageId = " + res.mPkgId + "res.isFullPkg = " + res.mIsFullPkg); res.mAndroidNum = "Android " + jo.getString("android_version"); Xlog.i(TAG, "res.mAndroidNum = " + res.mAndroidNum); mErrorCode = HTTP_RESPONSE_SUCCESS; return res; } else { mErrorCode = jo.getInt("status"); return null; } } catch (JSONException e) { e.printStackTrace(); onShutdownConn(); mErrorCode = HTTP_RESPONSE_NETWORK_ERROR; return null; } } private String getRandCookieStr() { String strCookie = null; if (mCookies != null) { int nSize = mCookies.getCookies().size(); Cookie cookieRand = null; for (int n = 0; n < nSize; n++) { Cookie cookie = mCookies.getCookies().get(n); Xlog.i(TAG, "index:" + n + "cookieRand.getName = " + cookie.getName()); if ((cookie != null) && (COOKIE_TAG.equals(cookie.getName()))) { cookieRand = cookie; Xlog.i(TAG, "cookieRand = " + cookieRand); } } if (cookieRand != null) { Xlog.i(TAG, "cookieRand getName = " + cookieRand.getName()); strCookie = "15811375356" + cookieRand.getValue(); Xlog.i(TAG, "getToken, strCookie = " + strCookie); } } Xlog.i(TAG, "strCookie = " + strCookie); return strCookie; } private String getToken() { Xlog.i(TAG, "getToken"); StringBuffer buf = new StringBuffer(); try { if (mCookies == null) { handsakeAuthentication(); } String strCookie = getRandCookieStr(); if (strCookie == null) { handsakeAuthentication(); } strCookie = getRandCookieStr(); if (strCookie == null) { Xlog.i(TAG, "could not get cookie value"); return null; } MessageDigest md5 = MessageDigest.getInstance("MD5"); md5.update(strCookie.getBytes()); byte[] bytes = md5.digest(); for (int i = 0; i < bytes.length; i++) { String s = Integer.toHexString(bytes[i] & UpgradePkgManager.MD5_MASK); if (s.length() == 1) { buf.append("0"); } buf.append(s); } } catch (NoSuchAlgorithmException e) { e.printStackTrace(); return null; } return buf.toString(); } /* * void setEjectFlag(Boolean flag) { synchronized (this) { mEjectFlag = * flag; } * * * } */ int writeFile(HttpResponse response, long currSize) { Xlog.i(TAG, "writeFile"); if (mDownloadInfo.getDLSessionStatus() != DownloadInfo.STATE_QUERYNEWVERSION) { //mNotification.clearNotification(NotifyManager.NOTIFY_DOWNLOADING); mNotification.showDownloadingNotificaton(mDownloadInfo.getVerNum(), (int) (((double) Util.getFileSize(Util.getPackageFileName(mContext)) / (double) mDownloadInfo.getUpdateImageSize()) * 100), true); } Util.cancelAlarm(mContext, Util.Action.ACTION_AUTO_DL_TIME_OUT); mDownloadInfo.setOtaAutoDlStatus(false); mDownloadInfo.setIfPauseWithinTime(false); try { // response.getParams().setIntParameter(CoreConnectionPNames.CONNECTION_TIMEOUT, // 10000); InputStream in = response.getEntity().getContent(); File ifolder = new File(Util.getPackagePathName(mContext)); if (!ifolder.exists()) { ifolder.mkdirs(); } RandomAccessFile out = null; String pkgFile = Util.getPackageFileName(mContext); if (pkgFile == null) { Xlog.e(TAG, "pkgFile is null"); mErrorCode = HTTP_DETECTED_SDCARD_CRASH_OR_UNMOUNT; return mErrorCode; } try { out = new RandomAccessFile(pkgFile, "rws"); out.seek(currSize); } catch (IOException e) { e.printStackTrace(); onShutdownConn(); mErrorCode = HTTP_DETECTED_SDCARD_CRASH_OR_UNMOUNT; return mErrorCode; } byte[] buff = new byte[4096]; int rc = 0; int i = 0; int j = 0; boolean rightnow = false; boolean finish = false; File fPkg = new File(pkgFile); if (fPkg == null) { out.close(); mErrorCode = HTTP_DETECTED_SDCARD_CRASH_OR_UNMOUNT; return mErrorCode; } while ((rc = in.read(buff, 0, 4096)) > 0) { // to-do: handle Intent.ACTION_MEDIA_EJECT /* * synchronized (this) { if (mEjectFlag) { try { out.close(); } * catch (IOException e) { e.printStackTrace(); } * onShutdownConn(); return mErrorCode = * HTTP_DETECTED_SDCARD_CRASH_OR_UNMOUNT; } } */ try { if (fPkg.exists()) { out.write(buff, 0, rc); } else { Xlog.e(TAG, "file not exist during downloading "); setPauseState(); out.close(); onShutdownConn(); mErrorCode = HTTP_FILE_NOT_EXIST; sendErrorMessage(); return mErrorCode; } } catch (IOException e) { e.printStackTrace(); out.close(); onShutdownConn(); mErrorCode = HTTP_DETECTED_SDCARD_CRASH_OR_UNMOUNT; return mErrorCode; } i++; int status = mDownloadInfo.getDLSessionStatus(); if (status == DownloadInfo.STATE_PAUSEDOWNLOAD || status == DownloadInfo.STATE_QUERYNEWVERSION) { Xlog.i(TAG, "writeFile, DownloadInfo = " + status); mCookies = null; finish = false; out.close(); onShutdownConn(); return 0; } if (mHandler == null) { if (rightnow) { i = 200; rightnow = false; } if (i == 200) { onDownloadProcessUpdate(); i = 0; } } else { if (!rightnow) { i = 18; rightnow = true; } if (i == 20) { i = 0; onDownloadProcessUpdate(); } } j++; if (j == 20) { onTransferRatio(); j = 0; } finish = true; } Xlog.i(TAG, "writeFile, finish, rc = " + rc + "bytes" + ". finish = " + finish); if (finish) { onTransferRatio(); onDownloadProcessUpdate(); } long curSize = Util.getFileSize(Util.getPackageFileName(mContext)); Xlog.i(TAG, "curSize = " + curSize + " mNewVersionInfo.mSize = " + mDownloadInfo.getUpdateImageSize()); out.close(); if (curSize >= mDownloadInfo.getUpdateImageSize()) { onShutdownConn(); return 0; } } catch (SocketTimeoutException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } showNoNetworkToast(); if (mDownloadInfo.getDLSessionStatus() == DownloadInfo.STATE_DOWNLOADING) { setPauseState(); Xlog.e(TAG, "writeFile, exception to set pause state"); mDownloadInfo.setOtaAutoDlStatus(true); mDownloadInfo.setIfPauseWithinTime(true); Util.setAlarm(mContext, AlarmManager.RTC, Calendar.getInstance().getTimeInMillis() + AUTO_DL_TIME, Util.Action.ACTION_AUTO_DL_TIME_OUT); } onShutdownConn(); mErrorCode = HTTP_RESPONSE_NETWORK_ERROR; sendErrorMessage(); return mErrorCode; } private void onTransferRatio() { long totalSize = mDownloadInfo.getUpdateImageSize(); long currSize = Util.getFileSize(Util.getPackageFileName(mContext)); if (currSize < 0) { currSize = 0; } if (totalSize == 0) { totalSize = -1; } if (totalSize < 0) { return; } int ratio = (int) (((double) currSize / (double) totalSize) * 100); if (ratio > Util.MAX_PERCENT) { ratio = Util.MAX_PERCENT; currSize = totalSize; } mDownloadInfo.setDownLoadPercent(ratio); } void onDownloadProcessUpdate() { mNotification.showDownloadingNotificaton(mDownloadInfo.getVerNum(), (int) (((double) Util.getFileSize(Util.getPackageFileName(mContext)) / (double) mDownloadInfo.getUpdateImageSize()) * 100), true); if (mHandler != null) { mHandler.sendMessage(mHandler.obtainMessage(SystemUpdateService.MSG_DLPKGUPGRADE)); } } /** * http response content. */ private class HttpResponseContent { int mRand = -1; String mSessionId = null; String mAndroidNum = null; String mVersionName = null; long mFileSize = -1; String mReleaseNote = null; int mPkgId = -1; boolean mIsFullPkg = false; String mFingerprint = null; } private void sendErrorMessage() { Xlog.i(TAG, "sendErrorMessage, mErrorCode = " + mErrorCode); if ((mErrorCode == HTTP_RESPONSE_NETWORK_ERROR) || (mErrorCode == HTTP_UNKNOWN_ERROR) || (mErrorCode == HTTP_RESPONSE_AUTHEN_ERROR)) { showNoNetworkToast(); } else if ((mErrorCode == HTTP_SERVER_VERSION_ERROR) && (ENG_LOAD_TAG.equalsIgnoreCase(SystemProperties.get(BUILD_TYPE_NAME)))) { showServerVersionErrorToast(); } if (mHandler != null) { switch (mErrorCode) { case HTTP_SERVER_VERSION_ERROR: case HTTP_RESPONSE_NO_NEW_VERSION: case HTTP_RESPONSE_VERSION_REQUIRE: case HTTP_UNKNOWN_ERROR: case HTTP_RESPONSE_AUTHEN_ERROR: case HTTP_RESPONSE_VERSION_ILLEGAL: case HTTP_RESPONSE_VERSION_DELETE: mHandler.sendMessage(mHandler.obtainMessage(SystemUpdateService.MSG_NOTIFY_QUERY_DONE)); break; case HTTP_RESPONSE_NETWORK_ERROR: if (mDownloadInfo.getDLSessionStatus() != DownloadInfo.STATE_QUERYNEWVERSION) { mHandler.sendMessage(mHandler.obtainMessage(SystemUpdateService.MSG_NETWORKERROR)); } else { mHandler.sendMessage(mHandler.obtainMessage(SystemUpdateService.MSG_NOTIFY_QUERY_DONE)); } break; case HTTP_RESPONSE_REQUEST_TOO_LONG: mHandler.sendMessage(mHandler.obtainMessage(SystemUpdateService.MSG_LARGEPKG)); break; case HTTP_RESPONSE_DELTA_DELETE: mHandler.sendMessage(mHandler.obtainMessage(SystemUpdateService.MSG_DELTADELETED)); break; case HTTP_DETECTED_SDCARD_ERROR: mHandler.sendMessage(mHandler.obtainMessage(SystemUpdateService.MSG_SDCARDUNKNOWNERROR)); break; case HTTP_DETECTED_SDCARD_INSUFFICENT: mHandler.sendMessage(mHandler.obtainMessage(SystemUpdateService.MSG_SDCARDINSUFFICENT)); break; case HTTP_DETECTED_SDCARD_CRASH_OR_UNMOUNT: mNotification.clearNotification(NotifyManager.NOTIFY_DOWNLOADING); // mHandler.sendMessage(mHandler // .obtainMessage(SystemUpdateService.MSG_SDCARDCRASHORUNMOUNT)); break; case HTTP_RESPONSE_UNZIP_ERROR: case HTTP_RESPONSE_UNZIP_CKSUM: mHandler.sendMessage(mHandler.obtainMessage(SystemUpdateService.MSG_UNZIP_ERROR)); break; case HTTP_FILE_NOT_EXIST: mHandler.sendMessage(mHandler.obtainMessage(SystemUpdateService.MSG_FILE_NOT_EXIST)); break; default: mHandler.sendMessage(mHandler.obtainMessage(SystemUpdateService.MSG_UNKNOWERROR)); } } } void clearNotification(int type) { mNotification.clearNotification(type); } void onDownloadImage() { Xlog.i(TAG, "onDownloadImage"); //no need to clear,otherwise,icon will flash //mNotification.clearNotification(NotifyManager.NOTIFY_DOWNLOADING); mNotification.showDownloadingNotificaton(mDownloadInfo.getVerNum(), (int) (((double) Util.getFileSize(Util.getPackageFileName(mContext)) / (double) mDownloadInfo.getUpdateImageSize()) * 100), true); if (mIsDownloading) { return; } mIsDownloading = true; notifyDlStarted(); boolean isunzip = mDownloadInfo.getDLSessionUnzipState(); boolean isren = mDownloadInfo.getDLSessionRenameState(); if (isren && isunzip) { setNotDownload(); UpgradePkgManager.deleteCrashPkgFile(Util.getPackagePathName(mContext)); onDownloadPackageUnzipAndCheck(); return; } mDownloadInfo.setDLSessionStatus(DownloadInfo.STATE_DOWNLOADING); String strNetWorkType = mDownloadInfo.getIfWifiDLOnly() ? NETTYPE_WIFI : ""; if (!Util.isNetWorkAvailable(mContext, strNetWorkType)) { mErrorCode = HTTP_RESPONSE_NETWORK_ERROR; sendErrorMessage(); setPauseState(); setNotDownload(); return; } // to-do: handle Intent.ACTION_MEDIA_EJECT // setEjectFlag(false); String url = ServerAddrReader.getInstance().getDownloadDeltaAddress(); if (url == null) { url = mContext.getResources().getString(R.string.address_download_delta); } String tokenCode = getToken(); if (tokenCode == null) { mErrorCode = HTTP_RESPONSE_AUTHEN_ERROR; sendErrorMessage(); setPauseState(); setNotDownload(); return; } BasicNameValuePair token = new BasicNameValuePair("token", tokenCode); int packageid = mDownloadInfo.getDLSessionDeltaId(); BasicNameValuePair deltaId = new BasicNameValuePair( mDownloadInfo.getFullPkgFlag() ? "versionId" : "deltaId", String.valueOf(packageid)); Xlog.i(TAG, "onDownloadImage pkgid = " + packageid); ArrayList<BasicNameValuePair> bnvpa = new ArrayList<BasicNameValuePair>(); bnvpa.add(token); bnvpa.add(deltaId); long currentSize = Util.getFileSize(Util.getPackageFileName(mContext)); currentSize -= FAULT_TOLERANT_BUFFER; if (currentSize < 0) { currentSize = 0; } BasicNameValuePair sizePar = new BasicNameValuePair("HTTP_RANGE", String.valueOf(currentSize)); bnvpa.add(sizePar); if (mDownloadInfo.getFullPkgFlag()) { BasicNameValuePair version = new BasicNameValuePair("version", mDownloadInfo.getVerNum()); bnvpa.add(version); url = ServerAddrReader.getInstance().getDownloadFullAddress(); if (url == null) { url = mContext.getResources().getString(R.string.address_download_full); } Xlog.v(TAG, "download full url = " + url); } HttpResponse response = doPost(url, null, bnvpa); if (mDownloadInfo.getDLSessionStatus() != DownloadInfo.STATE_DOWNLOADING) { Xlog.i(TAG, "onDownloadImage: status not right"); setNotDownload(); return; } if (response == null) { Xlog.i(TAG, "onDownloadImage: response = null"); mErrorCode = HTTP_UNKNOWN_ERROR; sendErrorMessage(); setPauseState(); setNotDownload(); return; } StatusLine status = response.getStatusLine(); if (status.getStatusCode() != HttpStatus.SC_OK && status.getStatusCode() != HttpStatus.SC_PARTIAL_CONTENT) { Xlog.i(TAG, "onDownloadImage, ReasonPhrase = " + status.getReasonPhrase() + ", status.getStatusCode() = " + status.getStatusCode()); mCookies = null; if (status.getStatusCode() == HttpStatus.SC_NOT_FOUND) { resetDescriptionInfo(); mErrorCode = HTTP_RESPONSE_DELTA_DELETE; } else if (status.getStatusCode() == HttpStatus.SC_REQUEST_TOO_LONG) { mErrorCode = HTTP_RESPONSE_REQUEST_TOO_LONG; } else { mErrorCode = HTTP_RESPONSE_AUTHEN_ERROR; } sendErrorMessage(); setPauseState(); setNotDownload(); return; } // Thread.currentThread().setPriority(Thread.MIN_PRIORITY); Intent service = new Intent(mContext, SystemUpdateService.class); service.setAction(Util.Action.ACTION_LCA_PROTECT); mContext.startService(service); int ret = writeFile(response, currentSize); mContext.stopService(service); // Thread.currentThread().setPriority(Thread.NORM_PRIORITY); Xlog.i(TAG, "onDownloadImage, download result = " + ret); if (ret == 0) { int downloadStatus = mDownloadInfo.getDLSessionStatus(); if (downloadStatus == DownloadInfo.STATE_PAUSEDOWNLOAD || downloadStatus == DownloadInfo.STATE_QUERYNEWVERSION) { setNotDownload(); return; } } if (ret == HTTP_DETECTED_SDCARD_CRASH_OR_UNMOUNT) { // resetDescriptionInfo(); resetDownloadFile(); sendErrorMessage(); setNotDownload(); return; } if (ret == HTTP_RESPONSE_NETWORK_ERROR) { setNotDownload(); checkIfAutoDl(); return; } if (ret == HTTP_FILE_NOT_EXIST) { setNotDownload(); return; } onDownloadPackageUnzipAndCheck(); mIsDownloading = false; } private void checkIfAutoDl() { Xlog.i(TAG, "checkIfAutoDl again "); Util.NETWORK_STATUS networkStatus = Util.getNetworkType(mContext); Xlog.i(TAG, "networkStatus = " + networkStatus); if (networkStatus == Util.NETWORK_STATUS.STATE_NONE_NETWORK) { return; } int status = mDownloadInfo.getDLSessionStatus(); Xlog.i(TAG, "status = " + status); if ((status == DownloadInfo.STATE_PAUSEDOWNLOAD) && (mDownloadInfo.getOtaAutoDlStatus())) { if ((networkStatus == Util.NETWORK_STATUS.STATE_WIFI) && mDownloadInfo.getIfPauseWithinTime()) { onDownloadImage(); return; } else { Xlog.i(TAG, "showDlReminderNotification"); //mNotification.clearNotification(NotifyManager.NOTIFY_DOWNLOADING); mNotification.showDownloadingNotificaton(mDownloadInfo.getVerNum(), (int) (((double) Util.getFileSize(Util.getPackageFileName(mContext)) / (double) mDownloadInfo.getUpdateImageSize()) * 100), false); return; } } return; } private void onShutdownConn() { Xlog.i(TAG, "onShutdownConn"); /* * if (mHttpClient != null) { * mHttpClient.getConnectionManager().shutdown(); } mHttpClient = null; */ mCookies = null; } private void onDownloadPackageUnzipAndCheck() { onPackageUnzipping(); // onDownloadPause(); mDownloadInfo.setDLSessionUnzipState(true); if (!mDownloadInfo.getDLSessionRenameState()) { if (!UpgradePkgManager.renameOtaPkg(mContext)) { mErrorCode = HTTP_RESPONSE_UNZIP_ERROR; sendErrorMessage(); return; } mDownloadInfo.setDLSessionRenameState(true); } long unzipSize = UpgradePkgManager.getSpaceForUnzipOtaPkg(mContext); Util.SDCARD_STATUS sdstat = Util.checkSdcardState(mContext, unzipSize); switch (sdstat) { case STATE_INSUFFICIENT: mErrorCode = HTTP_DETECTED_SDCARD_INSUFFICENT; sendErrorMessage(); return; case STATE_LOST: case STATE_UNMOUNT: mErrorCode = HTTP_DETECTED_SDCARD_ERROR; sendErrorMessage(); return; default: break; } int result = UpgradePkgManager.unzipUpgradePkg(UpgradePkgManager.getTempOtaPackage(mContext), null); if (result == UpgradePkgManager.UNZIP_SUCCESS) { onDownloadComplete(); mDownloadInfo.setDLSessionUnzipState(false); mDownloadInfo.setDLSessionRenameState(false); UpgradePkgManager.deleteUnusedOtaFile(Util.getPackagePathName(mContext)); return; } else { mErrorCode = (result == UpgradePkgManager.CKSUM_ERROR) ? HTTP_RESPONSE_UNZIP_CKSUM : HTTP_RESPONSE_UNZIP_ERROR; sendErrorMessage(); return; } } void onPackageUnzipping() { mDownloadInfo.setDLSessionStatus(mDownloadInfo.STATE_PACKAGEUNZIPPING); if (mHandler != null) { mHandler.sendMessage(mHandler.obtainMessage(SystemUpdateService.MSG_UNZIP_LODING)); } } void onDownloadComplete() { Xlog.i(TAG, "onDownloadComplete"); mDownloadInfo.setDLSessionStatus(DownloadInfo.STATE_DLPKGCOMPLETE); mNotification.clearNotification(NotifyManager.NOTIFY_DOWNLOADING); mNotification.showDownloadCompletedNotification(); if (!Util.checkIfTopActivity(mContext, OtaPkgManagerActivity.CLASS_NAME)) { Intent reminder = new Intent(mContext, ForegroundDialogService.class); reminder.putExtra(ForegroundDialogService.DLG_ID, ForegroundDialogService.DIALOG_INSTALL_REMINDER); mContext.startService(reminder); } if (mHandler != null) { mHandler.sendMessage(mHandler.obtainMessage(SystemUpdateService.MSG_DLPKGCOMPLETE)); } // mNewVersionInfo.version = null; mDownloadInfo.setDLSessionDeltaId(-1); // mDownloadInfo.setVersionNote(null); mDownloadInfo.setUpdateImageSize(-1); mDownloadInfo.setDownLoadPercent(Util.MAX_PERCENT); } void setPauseState() { if (mDownloadInfo.getDLSessionStatus() == DownloadInfo.STATE_DOWNLOADING) { mDownloadInfo.setDLSessionStatus(DownloadInfo.STATE_PAUSEDOWNLOAD); } } void setDownloadState() { mDownloadInfo.setDLSessionStatus(DownloadInfo.STATE_DOWNLOADING); } void setNotDownload() { mIsDownloading = false; if (mNotification != null) { int dlStatus = mDownloadInfo.getDLSessionStatus(); if ((dlStatus == DownloadInfo.STATE_DOWNLOADING) || (dlStatus == DownloadInfo.STATE_PAUSEDOWNLOAD)) { //mNotification.clearNotification(NotifyManager.NOTIFY_DOWNLOADING); mNotification.showDownloadingNotificaton(mDownloadInfo.getVerNum(), (int) (((double) Util.getFileSize(Util.getPackageFileName(mContext)) / (double) mDownloadInfo.getUpdateImageSize()) * 100), false); } } } /** * ******************system operator service start****************** **/ /** * These constant flag must be the same as that defined in * SysOperService.java, please follow them. **/ private static final int MSG_NONE = 0; private static final int MSG_DELETE_COMMANDFILE = 1; private static final String CMD_FILE_KEY = "COMMANDFILE"; private final Messenger mMessenger = new Messenger(new IncomingHandler()); private Messenger mService = null; private boolean mIsBound = false; private int mNeedServiceDo = MSG_NONE; /** * handler. */ class IncomingHandler extends Handler { @Override public void handleMessage(Message msg) { Xlog.i(TAG, "handleMessage, msg.what=" + msg.what); switch (msg.what) { case MSG_DELETE_COMMANDFILE: Xlog.i(TAG, "MSG_DELETE_COMMANDFILE: arg1=" + msg.arg1); break; default: super.handleMessage(msg); } } } private ServiceConnection mConnection = new ServiceConnection() { public void onServiceConnected(ComponentName className, IBinder service) { Xlog.i(TAG, "onServiceConnected"); mService = new Messenger(service); } public void onServiceDisconnected(ComponentName className) { mService = null; } }; private void notifySysoper(int actionType) { try { switch (actionType) { case MSG_DELETE_COMMANDFILE: Message msg = Message.obtain(null, MSG_DELETE_COMMANDFILE); msg.replyTo = mMessenger; Bundle data = new Bundle(); if (data == null) { return; } data.putString(CMD_FILE_KEY, COMMAND_FILE); msg.setData(data); if (mService != null) { mService.send(msg); } break; default: break; } } catch (RemoteException e) { e.printStackTrace(); } } private boolean doBindService(Context context) { if (context != null) { // mIsBound = context.bindService(new Intent(SYS_OPER_INTENT), // mConnection, Context.BIND_AUTO_CREATE); Intent intent = new Intent(); intent.setComponent(new ComponentName("com.mediatek.systemupdate.sysoper", "com.mediatek.systemupdate.sysoper.SysOperService")); mIsBound = context.bindService(intent, mConnection, Context.BIND_AUTO_CREATE); } Xlog.i(TAG, "dobindService, isbound=" + mIsBound); return mIsBound; } private void doUnbindService(Context context) { Xlog.i(TAG, "doUnbindService"); if (mIsBound) { mService = null; if (context != null) { context.unbindService(mConnection); } mIsBound = false; } } /** * ******************system operator service stop******************. **/ private void showNoNetworkToast() { if (mToastHandler != null) { mToastHandler.sendEmptyMessage(NETWORK_ERROR_TOAST); } } private void showServerVersionErrorToast() { if (mToastHandler != null) { mToastHandler.sendEmptyMessage(SERVER_VERSION_ERROR_TOAST); } } void notifyDlStarted() { if (mHandler != null) { mHandler.sendMessage(mHandler.obtainMessage(SystemUpdateService.MSG_DL_STARTED)); } } }