/* * Copyright (c) 2015 [1076559197@qq.com | tchen0707@gmail.com] * * 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.youku.service.acc; import java.io.File; import android.content.Context; import android.content.Intent; import android.os.Build; import android.os.Environment; import android.text.TextUtils; import com.baseproject.image.Utils; import com.baseproject.utils.Logger; import com.comscore.utils.FileUtils; public class AcceleraterServiceManager { private static final String TAG = "Accelerater_Service_Manager"; public static String ACC_PORT = ""; public static final String RESTRICTBY = "restrictby"; public static final String SUCCSTARTP2P = "succStartP2p"; private int mCurrentStatus = AcceleraterStatus.INIT; public static final String FROM_ACC = "from_acc"; public static final String ACTION_START_SUCCESS = "com.youku.acc.ACTION_START_SUCCESS"; public static final String ACTION_START_FAILURE = "com.youku.acc.ACTION_START_FAILURE"; private static AcceleraterServiceManager mInstance = new AcceleraterServiceManager(); private AcceleraterServiceManager() { } public static AcceleraterServiceManager getInstance() { return mInstance; } /** * 启动acc * * @param context * @return 成功返回0, 失败返回-1或错误码 */ public int startAcc(Context context) { Logger.d(TAG, "startAcc()"); int flag = 0; int port; if (mCurrentStatus != AcceleraterStatus.INIT) { Logger.e(TAG, "startAcc() error : mCurrentStatus = " + mCurrentStatus); return -1; } String cachePath = getDefauleSDCardPath(); if (cachePath != null && TextUtils.getTrimmedLength(cachePath) > 0) { File f = new File(cachePath + "/youku/"); boolean success = true; if (!f.exists()) { success = f.mkdirs(); } if (success) { int i = start("--mobile-data-path=" + cachePath + " --mobile-meta-path=" + cachePath + "/youku" + " --android-version=android_" + android.os.Build.VERSION.RELEASE); if (i == 0) { port = getHttpProxyPort(); if (port != -1) { ACC_PORT = "&myp=" + port; mCurrentStatus = AcceleraterStatus.STARTED; Logger.d(TAG, "ACC启动成功/PORT地址:" + ACC_PORT); } else { Logger.d(TAG, "ACC启动失败/Accstub.getHttpProxyPort()==-1"); ACC_PORT = ""; sFailReason = "6-获取端口号失败"; flag = -1; } } else { Logger.d(TAG, "ACC启动失败/Accstub.start()==" + i); ACC_PORT = ""; flag = i; sFailReason = "11-其他因素失败:" + i; } } else { flag = -1; sFailReason = "10-无youkudisk文件夹"; } } else { Logger.d(TAG, "ACC启动失败 /cachePath:" + cachePath); sFailReason = "7-获取缓存路径失败:" + cachePath; flag = -1; } Intent intent = new Intent("android.intent.action.DOWNLOAD_TRACKER"); intent.putExtra("from", FROM_ACC); if (flag != 0) { intent.putExtra(RESTRICTBY, sFailReason); context.sendBroadcast(intent); Logger.d(TAG, "统计失败原因"); } else { intent.putExtra(SUCCSTARTP2P, "0-加速器启动成功"); context.sendBroadcast(intent); Logger.d(TAG, "统计启动成功"); } return flag; } /*public int startAcc(Context context) { Logger.d(TAG, "startAcc()"); int flag = 0; switch (isAvailable()) { case 1: int port = getHttpProxyPort(); if (port != -1) { Logger.d(TAG, "ACC已启动"); ACC_PORT = "&myp=" + port; } else { Logger.d(TAG, "ACC启动失败/进入重新启动"); ACC_PORT = ""; startAcc(context); } break; case 0: flag = resume(); break; case -1: if (!isACCEnable()) { Logger.d(TAG, "ACC启动失败/手机不满足ACC运行条件"); flag = -1; } else { String cachePath = getDefauleSDCardPath(); if (cachePath != null && TextUtils.getTrimmedLength(cachePath) > 0) { File f = new File(cachePath + "/youku/"); if (!f.exists()) f.mkdirs(); int i = start("--mobile-data-path=" + cachePath + " --mobile-meta-path=" + cachePath + "/youku" + " --android-version=android_" + android.os.Build.VERSION.RELEASE); if (i == 0) {// 需要延迟1秒后获取端口 port = getHttpProxyPort(); if (port != -1) { ACC_PORT = "&myp=" + port; Logger.d(TAG, "ACC启动成功/PORT地址:" + ACC_PORT); } else { Logger.d(TAG, "ACC启动失败/Accstub.getHttpProxyPort()==-1"); ACC_PORT = ""; } } else { Logger.d(TAG, "ACC启动失败/Accstub.start()==" + i); ACC_PORT = ""; flag = i; } } else { Logger.d(TAG, "ACC启动失败 /cachePath:" + cachePath); flag = -1; } } break; default: break; } return flag; }*/ public int pauseAcc() { Logger.d(TAG, "pauseAcc()"); if (mCurrentStatus != AcceleraterStatus.STARTED) { Logger.e(TAG, "pauseAcc() error : mCurrentStatus = " + mCurrentStatus); return -1; } if (pause() == -1) { Logger.e(TAG, "pause() == -1"); return -1; } mCurrentStatus = AcceleraterStatus.PAUSED; Logger.d(TAG, "pauseAcc() success!"); return 0; } public int resumeAcc() { Logger.d(TAG, "resumeAcc()"); if (mCurrentStatus != AcceleraterStatus.PAUSED) { Logger.e(TAG, "resumeAcc() error : mCurrentStatus = " + mCurrentStatus); return -1; } if (resume() == -1) { Logger.e(TAG, "resume() == -1"); return -1; } mCurrentStatus = AcceleraterStatus.STARTED; Logger.d(TAG, "resumeAcc() success!"); return 0; } public void stopAcc() { Logger.d(TAG, "stopAcc()"); ACC_PORT = ""; stop(); mCurrentStatus = AcceleraterStatus.STOPED; } public int getCurrentStatus() { return mCurrentStatus; } public int isAccAvailable() { Logger.d(TAG, "isAccAvailable()"); if (!isACCEnable()) { return -1; } return isAvailable(); } public static String getAccVersionName() { Logger.d(TAG, "getAccVersionName()"); return getVersionName(); } public static int getAccVersionCode() { Logger.d(TAG, "getAccVersionCode()"); return getVersionCode(); } public int getAccHttpProxyPort() { Logger.d(TAG, "getAccHttpProxyPort()"); return getHttpProxyPort(); } public static String sFailReason; public static boolean isACCEnable() { Logger.d(TAG, "isACCEnable()"); Context context = com.baseproject.utils.Profile.mContext; Logger.e(TAG, "p2pSwitch = " + AccInitData.getP2pSwitch(context)); switch (AccInitData.getP2pSwitch(context)) { case 0: Logger.e(TAG, "2-P2P开关获取成功,但开关状态为关闭"); sFailReason = "2-P2P开关获取成功,但开关状态为关闭"; return false; case -1: Logger.e(TAG, "5-P2P开关获取失败"); sFailReason = "5-P2P开关获取失败"; return false; default: break; } if (Build.VERSION.SDK_INT < AccInitData.getAndroidVersionRestrict(context)) { Logger.e(TAG, "4-Andriod版本低于"); sFailReason = "4-Andriod版本低于" + AccInitData.getAndroidVersionRestrict(context); return false; } if (Utils.getMemoryClass(context) < AccInitData.getMemoryRestrict(context)) { Logger.e(TAG, "0-内存<" + AccInitData.getMemoryRestrict(context) + "M"); sFailReason = "0-内存<" + AccInitData.getMemoryRestrict(context) + "M"; return false; } if (!hasSDCard()) { Logger.e(TAG, "3-没sd卡"); sFailReason = "3-没sd卡"; return false; } if (!AccInitData.isUplayerSupported(AccInitData.getCpuRestrict(context))) { Logger.e(TAG, "1-CPU未满足软解要求" + ", abi = " + android.os.Build.CPU_ABI + ", hasNeon = " + AccInitData.sHasNeon + ", freq = " + AccInitData.getCpuRestrict(context)); sFailReason = "1-CPU未满足软解要求" + ", abi = " + android.os.Build.CPU_ABI + ", hasNeon = " + AccInitData.sHasNeon + ", freq = " + AccInitData.sCpuFreq; return false; } /*if (Build.VERSION.SDK_INT >= 9 && MediaPlayerProxy.isUplayerSupported() && Utils.getMemoryClass(com.baseproject.utils.Profile.mContext) >= 47 && hasSDCard()) { //AnalyticsWrapper.trackExtendCustomEvent(context, name, page, target, userID, extend); return true; }*/ Logger.e(TAG, "p2p启动的条件全部满足"); return true; } /** Returns 是否有SD卡 */ public static boolean hasSDCard() { Logger.d(TAG, "hasSDCard()"); return Environment.getExternalStorageState().equals( android.os.Environment.MEDIA_MOUNTED); } public static String getDefauleSDCardPath() { Logger.d(TAG, "getDefauleSDCardPath()"); return hasSDCard() ? Environment.getExternalStorageDirectory() .getAbsolutePath() : ""; } /** * @brief 启动加速器 * @return 成功启动返回0,否则返回相应的错误号 */ private native int start(final String command); /** * @brief 停止Iku加速器 */ private native void stop(); /** * @return -1代表未成功获取 */ private native int getHttpProxyPort(); /** * 暂停加速(要求在调用start成功或resume(isAvailablie返回1)成功之后调用该接口函数) * * @return 0成功;-1失败 */ private native int pause(); /** * 恢复运行加速器(要求在调用pause成功(isAvailablie返回0)之后调用该接口函数) * * @return 0成功;-1失败 */ private native int resume(); /** * 判断加速器是否可用,当前运行状态 * * @return -1不可用;0处于暂停;1可用 */ private native int isAvailable(); /** * 获取加速去版本号 */ private static native String getVersionName(); private static native int getVersionCode(); public static void postEventFromNative(int what, int arg1, int arg2, Object obj) { Logger.e(TAG, "postEventFromNative : what = " + what); } static { // String accPath = SoUpgradeStatics.getAccSo(com.baseproject.utils.Profile.mContext); // // if (FileUtils.isFileExist(accPath)) { // Logger.d(SoUpgradeService.TAG, "System.load(" + accPath + ")"); // System.load(accPath); // } else { // Logger.d(SoUpgradeService.TAG, "System.loadLibrary(accstub)"); System.loadLibrary("accstub"); // } } }