com.ubiLive.GameCloud.Browser.WebBrowser.java Source code

Java tutorial

Introduction

Here is the source code for com.ubiLive.GameCloud.Browser.WebBrowser.java

Source

package com.ubiLive.GameCloud.Browser;

import java.io.UnsupportedEncodingException;
import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
import java.security.NoSuchAlgorithmException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Calendar;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import android.app.Activity;
import android.app.DatePickerDialog;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.SharedPreferences;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.net.Uri;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.provider.Settings;
import android.telephony.TelephonyManager;
import android.util.Base64;
import android.view.Gravity;
import android.view.View;
import android.webkit.WebView;
import android.widget.DatePicker;
import android.widget.LinearLayout;

import com.google.android.gms.cast.CastDevice;
import com.ubiLive.GameCloud.CloudGamePlayer;
import com.ubiLive.GameCloud.Constants;
import com.ubiLive.GameCloud.DebugLog;
import com.ubiLive.GameCloud.GameInfo;
import com.ubiLive.GameCloud.NotifyManagement;
import com.ubiLive.GameCloud.PreferenceManager;
import com.ubiLive.GameCloud.Utils;
import com.ubiLive.GameCloud.VersionAutoUpdate;
import com.ubiLive.GameCloud.Browser.ChildBrowser.ClildBrowserListener;
import com.ubiLive.GameCloud.activity.GameActivity;
import com.ubiLive.GameCloud.activity.LoadWebJsActivity;
import com.ubiLive.GameCloud.cast.v2.ChromecastUtil;
import com.ubiLive.GameCloud.cast.v2.DeviceSelectionDialog;
import com.ubiLive.GameCloud.payment.BillingActivity;
import com.ubiLive.GameCloud.payment.GoogleBillingActivity;
import com.ubiLive.GameCloud.payment.PayPal;
import com.ubiLive.GameCloud.ui.GCApplication;
import com.ubiLive.GameCloud.ui.GCToastControl;
import com.ubiLive.GameCloud.ui.GameActivityRes;
import com.ubiLive.GameCloud.ui.SignalView;
import com.ubiLive.GameCloud.Browser.WebBrowserFB;

public class WebBrowser {

    protected final static String JS_INTERFACE_OBJECT = "player";
    protected final static String TAG = WebBrowser.class.getName();
    private LinearLayout mRootView;
    private WebView mWebView;
    private Context mContext;
    private String mUniqueId;
    private boolean mBProbeDone = false;
    private boolean mBProbeDoing = false;
    private String mPlayGameUrl = null; // save play game url if bProbeDone is false
    private String mPlayId = null;
    private String mCastId = null;
    private String mPurchaseUrl;
    private Activity mWebviewActivity;
    private CloudGamePlayer mPlayer;
    public static boolean gBNotifyDisplayExit = false;
    public static String gNotifyDisplayText;
    private List<View> mChildViewList = new ArrayList<View>();
    private List<WebView> mChildWebviewLst = new ArrayList<WebView>();
    private boolean mbNetworIsConnect = true;

    private static final int HANDLE_OPEN_NEW_WINDOW = 1;
    //private static final int HANDLE_SHOW_WAIT_PROBE_DIALOG = 2;
    private static final int HANDLE_GET_BANDWIDTH_PROBING_URI = 3;
    private static final int HANDLE_RECEIVE_ANNOUNCE_901 = 4;
    private static final int HANDLE_RECEIVE_ANNOUNCE_902 = 5;
    private static final int HANDLE_RECEIVE_ANNOUNCE_700_710_1001 = 10;
    private static final int HANDLE_CLOSE_CHILD_BROWSER = 6;
    //private static final int HANDLE_NOTIFY_PROBING_COMPLETED = 7;
    private static final int HANDLE_PROHIBIT_PLAY = 8;
    private static final int HANDLE_POORPROBINGRESULT = 9;
    private static final int HANDLE_CHECKAVAILABLENETWORK_LTE = 11;
    private static final int HANDLE_PROHIBIT_CHECKAVAILABLENETWORK = 12;
    private static final int ANNOUNCEMESSAGE_PRESENTMODE_DIALOG = 1;
    private static final int ANNOUNCEMESSAGE_PRESENTMODE_TWINKLE = 2;
    public static int sGameExitStatus = 0; //0 normal exit; -1 recover failure exit;
    private int mBillingStatus = Constants.BILLING_STATUS_INIT;
    public static boolean sIsBillingTriggered = false;
    private boolean mPoorProbingresultFlag = false;
    private HashMap<String, String> mReceiptMap = new HashMap<String, String>();
    private HashMap<String, String> mCheckLicenseMap = new HashMap<String, String>();
    public static boolean sBCurrentActivityStatus = true;
    private final static String MULTI_TAB_WIN_MAIN = "main";
    private List<String> mLstOpenWin;
    private final Object mLock = new Object();
    public static boolean haveCastDevice = false;
    public ChromecastUtil chromecast = null;
    private ToolbarListener mToolbarListener;
    private PayPal mPayPal;
    public static GCToastControl sCtrToast;

    private static final String UBIGCPLAYERINVOKE_FUNCTION[] = { "purchaseInApp", "getClientCapability",
            "updateSoftware", "saveAccountAndPassword", "getAccountAndPassword", "checkInApp", "clearUserCookies",
            "announceMessage", "openWindow", "putClientProfile", "checkParentalCode", "getEbookInitialData",
            "goBack", "exitApp", "enableToolbar", "disableToolbar", "updateUserProfile", "notifyURLRoute",
            "launchNativeUI", "notifyUserLogined", "paypalPayment", "paypalPaymentDone", "openConfigurationPage",
            "detectHttpBandwidth" };

    protected Class<?> checkUbiGCPlayerInvokeFunForJava(String functionName) {
        for (int i = 0; i < UBIGCPLAYERINVOKE_FUNCTION.length; i++) {
            if (UBIGCPLAYERINVOKE_FUNCTION[i].equalsIgnoreCase(functionName)) {
                return WebBrowser.class;
            }
        }
        return null;
    }

    public static WebBrowser getNewInstance(WebView webview, Activity activity, View view) {
        WebBrowser browser = new WebBrowserFB(webview, activity, view);
        return browser;
    }

    public WebBrowser(WebView webView, Activity activity, View rootView) {
        this.mRootView = (LinearLayout) rootView;
        this.mWebView = webView;
        this.mWebviewActivity = activity;
        this.mContext = activity;
        this.mPlayer = GameActivity.m_player;
        WebBrowser.sGameExitStatus = 0;

        registerBoradcast();
        mUniqueId = Settings.Secure.getString(mContext.getContentResolver(), Settings.Secure.ANDROID_ID);
        VersionAutoUpdate.delTempDownloadFile(activity);
        mChildViewList.add(0, mWebView);
        if (1 == mPlayer.useUbGcWeb()) {
            DebugLog.e(TAG, "using WebBrowser useUbGcWeb native");
            CloudGamePlayer.sWebBrowser = this;
        }
        GameActivity.m_player.setClientVersionNumber(Utils.getAppVerNumber(mContext));
        mBillingStatus = Constants.BILLING_STATUS_INIT;
        chromecast = new ChromecastUtil(activity);
        chromecast.startScanCastDevice();

        mPayPal = new PayPal(activity, this);
    }

    public boolean getNetworIsConnect() {
        return mbNetworIsConnect;
    }

    /**
     * web Javascript call client
     * @param functionName
     * @param jsonData
     * @return
     */
    public void ubiGCPlayerInvoke(String functionName, String jsonData) {
        DebugLog.v(TAG,
                "ubiGCPlayerInvoke() functionName = " + functionName + ",jsonData = " + jsonData + "---------");
        DebugLog.v(TAG, "ubiGCPlayerInvoke() useUbGcWeb = " + mPlayer.useUbGcWeb());
        DebugLog.v(TAG, "ubiGCPlayerInvoke() checkUbiGCPlayerInvokeFunForJava(functionName) = "
                + checkUbiGCPlayerInvokeFunForJava(functionName));

        final boolean isShowdialog = !"disableToolbar".equalsIgnoreCase(functionName)
                && !"getClientCapability".equalsIgnoreCase(functionName);
        ((LoadWebJsActivity) mWebviewActivity).setWebProgressBarVisibility(isShowdialog ? View.VISIBLE : View.GONE);

        if (Constants.sEnable_networkType_workflow) {
            if (functionName.equals("checkAvailableNetwork")) {
                DebugLog.d(TAG, "getNetworkType = " + Utils.getNetworkType());
                Utils.readStoredLteCfgStatus(mContext);
                if (Constants.sIsEnableNetworkLte) {
                    GameActivity.m_player.setAllowLteFlag(1);
                } else {
                    GameActivity.m_player.setAllowLteFlag(0);
                }

                WebBrowser.sGameExitStatus = 0;

                if (Constants.NETWORKTYPE_3G == Utils.getNetworkType()) {
                    DebugLog.d(TAG, "====prohibit 3G network type====");
                    //Only allow LTE/WIFI to play game
                    Message msg = new Message();
                    msg.what = HANDLE_PROHIBIT_CHECKAVAILABLENETWORK;
                    msg.obj = jsonData;
                    if (mHandler != null)
                        mHandler.sendMessage(msg);
                    return;
                }

                if (Constants.NETWORKTYPE_LTE == Utils.getNetworkType()) {
                    readStoredAcceptUseLteCfgStatus();
                    if (!Constants.sIsEnableNetworkLte || !Constants.sIsAcceptLteUsage) {
                        Message msg = new Message();
                        msg.what = HANDLE_CHECKAVAILABLENETWORK_LTE;
                        msg.obj = jsonData;
                        if (mHandler != null)
                            mHandler.sendMessage(msg);
                        return;
                    }
                }

                /*For temp test.
                 *  if (Constants.NETWORKTYPE_WIFI == Utils.getNetworkType()) {
                Message msg = new Message();
                msg.what = 1111;
                msg.obj = jsonData;
                if (mHandler != null)
                    mHandler.sendMessage(msg);
                return;
                    
                 }*/

            } else if (functionName.equals("play")
                    && Constants.GAMEACTIVITY_ALERT_DIALOG_TYPE_NOT_LTEWIFI == WebBrowser.sGameExitStatus) {
                notifyProhibitPlay(jsonData);
                WebBrowser.sGameExitStatus = 0;
                return;
            }
        }

        if (("playOnCast".equalsIgnoreCase(functionName)) && (isCastSet(jsonData) == true)) {

            chromecast.setChromecastWebMode(true);
            selectChromecastDevice();

        }

        if (("enableToolbar".equalsIgnoreCase(functionName))) {

            chromecast.setLoginStatus(true);
        }

        if (("disableToolbar".equalsIgnoreCase(functionName))) {

            chromecast.setLoginStatus(false);
        }

        if ("checkAvailableNetwork".equalsIgnoreCase(functionName)) {
            DebugLog.d(TAG, "ubiGCPlayerInvoke checkAvailableNetwork StartGameActivity");
            Utils.startGameActivity(mContext, mWebviewActivity, null, null, null);
        }

        Class<?> clazz = checkUbiGCPlayerInvokeFunForJava(functionName);
        if (0 == mPlayer.useUbGcWeb() || clazz != null) {
            DebugLog.i(TAG, "ubiGCPlayerInvoke used JAVA Layer json functionName = " + functionName);
            try {
                Method method = null;
                String result = null;
                if (jsonData == null || jsonData.length() == 0 || jsonData.equals("")) {
                    method = clazz.getDeclaredMethod(functionName);
                    result = (String) method.invoke(this);
                } else {
                    method = clazz.getDeclaredMethod(functionName, String.class);
                    result = (String) method.invoke(this, jsonData);
                }
            } catch (Exception e) {
                DebugLog.d(TAG, "exception = " + e.getMessage());
            }
        } else if (1 == mPlayer.useUbGcWeb()) {

            mPlayer.ubiGCPlayerInvoke(functionName, jsonData);
        }
    }

    private void selectChromecastDevice() {

        Message m = new Message();
        m.what = 1102;
        mHandler.sendMessage(m);

        synchronized (mLock) {
            try {
                DebugLog.d(TAG, "wait start");
                mLock.wait();

                if (haveCastDevice == true && chromecast.getJsActivityPauseStatus() == false) {
                    CloudGamePlayer.playToCast();
                } else {
                    chromecast.setChromecastWebMode(false);
                }
                DebugLog.d(TAG, "wait end");
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                DebugLog.d(TAG, "exception = " + e.getMessage());
            }
        }
    }

    private boolean isCastSet(String jsonData) {

        String type;
        JSONObject json;

        try {
            json = new JSONObject(jsonData);
            mCastId = json.optString("id");
            type = json.optString("type");

            if (type.equalsIgnoreCase("set") == false)
                return false;
        } catch (JSONException e) {
            // TODO Auto-generated catch block
            DebugLog.d(TAG, "exception = " + e.getMessage());
        }

        return true;
    }

    private void retPlayOnCast(String deviceId, String deviceName, String status) {

        JSONObject result;
        JSONObject device;

        result = new JSONObject();

        try {
            result.put("id", mCastId);
            result.put("type", "result");

            if (deviceName != null && chromecast.getJsActivityPauseStatus() == false) {

                if ("ok".equalsIgnoreCase(status))
                    result.put("code", "200");
                else
                    result.put("code", "500");

                device = new JSONObject();
                device.put("deviceId", deviceId);
                device.put("deviceName", deviceName);

                result.put("device", device);
            } else {
                result.put("code", "500");
                result.put("device", " ");
            }

        } catch (JSONException e) {
            // TODO Auto-generated catch block
            DebugLog.d(TAG, "exception = " + e.getMessage());
        }

        ubiGCPlayerCallback("playOnCast", result.toString());
    }

    private Handler mUbiGCPlayerCallbackHandler = new Handler() {

        @Override
        public void handleMessage(Message msg) {
            // TODO Auto-generated method stub
            super.handleMessage(msg);
            mWebView.loadUrl("javascript:ubiGCPlayerCallback('" + msg.getData().getString("functionName") + "','"
                    + msg.getData().getString("jsonData") + "')");
        }

    };

    public void ubiGCPlayerCallback(final String functionName, final String jsonData) {
        DebugLog.d(TAG, "ubiGCPlayerCallback() functionName = " + functionName + ",jsonData = " + jsonData);
        if (!"updateCastStatus".equalsIgnoreCase(functionName) && !"disableToolbar".equalsIgnoreCase(functionName)
                && !"getClientCapability".equalsIgnoreCase(functionName)) {
            ((LoadWebJsActivity) mWebviewActivity).setWebProgressBarVisibility(View.GONE);
        }
        if (1 == mPlayer.useUbGcWeb()) {
            ((Activity) mContext).runOnUiThread(new Runnable() {

                @Override
                public void run() {
                    // TODO Auto-generated method stub
                    mWebView.loadUrl("javascript:ubiGCPlayerCallback('" + functionName + "','" + jsonData + "')");
                }

            });
            if (SignalView.JOYSTICK_ACTION_CONNECTED.equalsIgnoreCase(functionName)) {
                DebugLog.d(TAG,
                        "notifyUpdateJoystickAction  joystickConnected() jsonData = " + jsonData.toString());
                try {
                    JSONObject data = new JSONObject(jsonData);
                    String joystickID = data.getString("joystickID");
                    NotifyManagement.notifyUpdateJoystickAction(SignalView.JOYSTICK_ACTION_CONNECTED,
                            Integer.parseInt(joystickID.substring(joystickID.length() - 1)));
                } catch (Exception e) {
                    DebugLog.d(TAG, "exception = " + e.getMessage());
                }
            } else if (SignalView.JOYSTICK_ACTION_DISCONNECTED.equalsIgnoreCase(functionName)) {
                DebugLog.d(TAG,
                        "notifyUpdateJoystickAction  joystickDisconnected() jsonData = " + jsonData.toString());
                try {
                    JSONObject data = new JSONObject(jsonData);
                    String joystickID = data.getString("joystickID");
                    NotifyManagement.notifyUpdateJoystickAction(SignalView.JOYSTICK_ACTION_DISCONNECTED,
                            Integer.parseInt(joystickID.substring(joystickID.length() - 1)));
                } catch (Exception e) {
                    DebugLog.d(TAG, "exception = " + e.getMessage());
                }
            }
        } else {
            mWebView.loadUrl("javascript:ubiGCPlayerCallback('" + functionName + "','" + jsonData + "')");
        }
    }

    public void ubiGCPlayerKeyCode(final int keycode) {
        DebugLog.d(TAG, "ubiGCPlayerKeyCode() keycode = " + keycode);
        // TODO Auto-generated method stub
        mWebView.loadUrl("javascript:ubiGCPlayerKeyCode(" + keycode + ")");

    }

    public void ubiGCPlayerInit() {
        DebugLog.d(TAG, "ubiGCPlayerInit jsonData");
    }

    public void ubiGCPlayerFini() {
        DebugLog.d(TAG, "ubiGCPlayerFini jsonData");
    }

    public void fini() {

        ((Activity) mContext).runOnUiThread(new Runnable() {

            @Override
            public void run() {
                // TODO Auto-generated method stub
                stopHttpConnect();
                mContext.unregisterReceiver(boradcastListener);
                //mWebView.removeJavascriptInterface(JS_INTERFACE_OBJECT);
            }

        });

    }

    public void stopHttpConnect() {
        // TODO Auto-generated method stub
        //mWebView.loadUrl("javascript:$.gamecloud.logout()");
        callJsHandleWebSession(false);
    }

    public void startHttpConnect() {
        // TODO Auto-generated method stub
        //mWebView.loadUrl("javascript:$.gamecloud.logout()");
        callJsHandleWebSession(true);
    }

    /** notify probe completed*/
    private void notifyProbingCompleted(boolean bSuccess) {
        DebugLog.d(TAG, "call notifyProbingCompleted() bSuccess = " + bSuccess);
        String request;

        if (bSuccess) {
            mBProbeDone = true;
            request = "{\"id\": \"" + mPlayId + "\",\"code\": \"" + Constants.RESPONSE_200
                    + "\",\"message\": \"bandwidth probing successfully\"}";
        } else {
            mBProbeDone = false;
            request = "{\"id\": \"" + mPlayId + "\",\"code\": \"" + Constants.RESPONSE_530
                    + "\",\"message\": \"bandwidth probing failed\"}";
        }

        DebugLog.d(TAG, "javascript:playerNotification.probingCompleted. request = " + request);

        ubiGCPlayerCallback("probingCompleted", request);
        notifyClosePlayerWebJS();

        mBProbeDoing = false;
        if (mPlayGameUrl != null) {
            // play game
            DebugLog.d(TAG, "start Game");
            ((Activity) mContext).runOnUiThread(new Runnable() {
                @Override
                public void run() {
                    // TODO Auto-generated method stub
                    Utils.startGameActivity(mContext, mWebviewActivity, "", mPlayGameUrl, mPurchaseUrl);
                }

            });
            mPlayGameUrl = null;
        }
    }

    public void notifyClosePlayer() {
        DebugLog.d(TAG, "call notifyClosePlayer() playId = " + mPlayId);
        notifyClosePlayerWebJS();
        if (WebBrowser.sGameExitStatus == Constants.GAMEACTIVITY_ALERT_DIALOG_TYPE_RECOVER_FAIL
                || WebBrowser.sGameExitStatus == Constants.GAMEACTIVITY_ALERT_DIALOG_TYPE_RECOVER_FAIL_3G
                || WebBrowser.sGameExitStatus == Constants.GAMEACTIVITY_ALERT_DIALOG_TYPE_RECOVER_FAIL_NOT_ALLOW_LTE) {
            callJsUpdateStatus(Constants.RESPONSE_303);
            WebBrowser.sGameExitStatus = 0;
        } else if (WebBrowser.sGameExitStatus == Constants.GAMEACTIVITY_ALERT_DIALOG_TYPE_HIGH_LATENCY) {
            callJsUpdateStatus(Constants.RESPONSE_304);
            WebBrowser.sGameExitStatus = 0;
        } else {
            callJsUpdateStatus(Constants.RESPONSE_302);
        }
    }

    private void notifyClosePlayerWebJS() {
        if (mPlayId != null) {
            String request = "{" + "\"id\": \"" + mPlayId + "\"," + "\"type\": \"set\"" + "}";
            ubiGCPlayerCallback("close", request);
        }
    }

    public void callJsUpdateStatus(String code) {
        DebugLog.d(TAG, "call callJsUpdateStatus() code = " + code);
        String request = null;
        if (Constants.RESPONSE_200.equals(code)) {
            request = "{\"id\": \"" + mUniqueId + "\",\"code\": \"" + Constants.RESPONSE_200
                    + "\",\"message\": \"player started\"}";
        } else if (Constants.RESPONSE_302.equals(code)) {
            request = "{\"id\": \"" + mUniqueId + "\",\"code\": \"" + Constants.RESPONSE_302
                    + "\",\"message\": \"player closed in expectation\"}";
        } else if (Constants.RESPONSE_303.equals(code)) {
            request = "{\"id\": \"" + mUniqueId + "\",\"code\": \"" + Constants.RESPONSE_303
                    + "\",\"message\": \"game crashed accidentally\"}";
        } else if (Constants.RESPONSE_304.equals(code)) {
            request = "{\"id\": \"" + mUniqueId + "\",\"code\": \"" + Constants.RESPONSE_304
                    + "\",\"message\": \"game closed due to high latency\"}";
        }

        if (request != null) {
            ubiGCPlayerCallback("updateStatus", request);
        }
    }

    private String play(final String url) {
        DebugLog.d(TAG, "webview call play()  json = " + url);

        JSONObject json;
        String dynamicUrl;
        String strMaxbitrate = null;
        String result = null;
        int maxbitrate = 0;
        try {
            json = new JSONObject(url);
            mPlayId = json.optString("id");
            String type = json.optString("type");
            String appType = json.optString("appType");
            String mToken = json.optString("token");
            String mPlayUrl = json.optString("playUrl");
            // new server
            strMaxbitrate = json.optString("maxBitrate");
            DebugLog.d(TAG, "--- id != null ---strMaxbitrate=" + strMaxbitrate);
            if (null != strMaxbitrate && !"".equals(strMaxbitrate)) {
                try {
                    maxbitrate = Integer.parseInt(strMaxbitrate);
                } catch (Exception e) {
                    DebugLog.d(TAG, "exception = " + e.getMessage());
                    maxbitrate = 0;
                }
                if (0 < maxbitrate) {
                    GameActivity.m_player.setMaxBitrate(maxbitrate);
                }
            }
            dynamicUrl = json.optString("dynamicUrl");
            if (appType.equals("probing")) {
                // start probe thread
                mPoorProbingresultFlag = false;
                if (GameActivity.m_player.isProbeAfterSetup() == Constants.LOCAL_TO_DO_PROBING) {
                    new Thread(new ProbeRunnable(url)).start();
                    mBProbeDoing = true;
                }

            } else {
                // play game
                DebugLog.d(TAG, "play() bProBeDone = " + mBProbeDone);
                mPurchaseUrl = json.optString("purchaseUrl");
                //DebugLog.d(TAG, "play() purchaseUrl = " + mPurchaseUrl);
                //if (mBProbeDone) {
                startGamePlayer(url, mPurchaseUrl);
                /*}else{
                   mPlayGameUrl = url;
                }*/
            }

            result = "{" + "\"id\": \"" + mPlayId + "\"," + "\"type\": \"result\"," + "\"code\": \"200\","
                    + "\"message\": \"success\"" + "}";
        } catch (JSONException e) {
            result = "{\"code\": \"" + Constants.RESPONSE_500 + "\",\"message\": \"player internal error\"}";
            DebugLog.d(TAG, "exception = " + e.getMessage());
        }

        ubiGCPlayerCallback("play", result);
        return result;
    }

    public void startGamePlayer(final String url, final String purchaseUrl) {
        DebugLog.d(TAG, "start Game playId = " + mPlayId);
        final LoadWebJsActivity loadWebJsActivity = (LoadWebJsActivity) mContext;
        if (loadWebJsActivity != null) {
            loadWebJsActivity.stopDetectTimeoutThread();
            LoadWebJsActivity.sGameingBgFgTimeoutExit = false;
        }
        if (null != mContext) {
            ((Activity) mContext).runOnUiThread(new Runnable() {

                @Override
                public void run() {
                    if (WebBrowser.sBCurrentActivityStatus) {
                        Utils.startGameActivity(mContext, mWebviewActivity, "", url, purchaseUrl);
                    } else {
                        Utils.notifyGameStart(mContext, "", url, purchaseUrl);
                    }
                }

            });
        }
    }

    private String getClientCapability(final String jsonData) {

        DebugLog.d(TAG, "call getClientCapability()");
        ((Activity) mContext).runOnUiThread(new Runnable() {

            @Override
            public void run() {
                // TODO Auto-generated method stub
                String result = null;
                String uniqueId = Settings.Secure.getString(mContext.getContentResolver(),
                        Settings.Secure.ANDROID_ID);
                try {
                    JSONObject json = new JSONObject(jsonData);
                    String id = json.optString("id");
                    //String type = json.optString("type");
                    String userAgent = Utils.getOS((Activity) mContext);
                    String locale = mContext.getResources().getConfiguration().locale.toString();
                    String macAddress = Utils.getLocalMacAddress(mContext);
                    boolean wirelessAccess = Utils.CheckNetworkAvailable(mContext);
                    String simcardID = Utils.getDeviceId(mContext);
                    String operatorCode = Utils.getOperatorNumeric(mContext);
                    String strNetworkType = Utils.getNetworkTypeStr();
                    result = "{" + "\"id\": \"" + id + "\", " + "\"type\": \"result\", " + "\"code\": \""
                            + Constants.RESPONSE_200 + "\", " + "\"message\": \"success\", " + "\"userAgent\": \""
                            + userAgent + "\", " + "\"locale\": \"" + locale + "\", " + "\"uniqueId\": \""
                            + uniqueId + "\", " + "\"macAddress\": \"" + macAddress + "\", "
                            + "\"wirelessAccess\": \"" + wirelessAccess + "\", " + "\"simcardId\": \"" + simcardID
                            + "\", " + "\"operatorCode\": \"" + operatorCode + "\"," + "\"networkType\": \""
                            + strNetworkType + "\"," + "\"clientVersion\": \"" + Utils.getAppVerNumber(mContext)
                            + "\"" + "}";
                } catch (Exception e) {
                    DebugLog.d(TAG, "exception = " + e.getMessage());
                    result = "{" + "\"code\": \"" + Constants.RESPONSE_500 + "\", "
                            + "\"message\": \"player internal error\" " + "}";
                }

                ubiGCPlayerCallback("getClientCapability", result);
            }

        });

        return null;
    }

    public void DebugLog(String str) {
        DebugLog.d(TAG, "_JavaScript DebugLog : " + str);
    }

    /**
     * JavaScript callBack method
     * @param parameter A JSON String, eg:{"request": {"code": "901","displayText": 
     * "Your game ticket will be expired in 10 minutes"}}
     * 
     * code -> 901 Your game ticket will be expired in 10 minutes
     * code -> 902 Your game ticket is expired
     */
    private void announceMessage(final String parameter) {
        ((Activity) mContext).runOnUiThread(new Runnable() {

            @Override
            public void run() {
                try {
                    JSONObject json;
                    String code, displayText;
                    json = new JSONObject(parameter);
                    code = json.optString("code");
                    displayText = json.optString("displayText");
                    String presentMode = json.optString("presentMode");

                    if ("".equals(code) || code == null) {
                        return;
                    }

                    Message msg = new Message();
                    msg.obj = displayText;
                    DebugLog.d(TAG, "announceMessage code = " + code);
                    if (presentMode != null) {
                        if (presentMode.equals("twinkle")) {
                            msg.arg1 = ANNOUNCEMESSAGE_PRESENTMODE_TWINKLE;
                        } else {
                            msg.arg1 = ANNOUNCEMESSAGE_PRESENTMODE_DIALOG;
                        }
                    }

                    if (Constants.RESPONSE_901.equals(code)) {
                        msg.what = HANDLE_RECEIVE_ANNOUNCE_901;
                        if (mHandler != null)
                            mHandler.sendMessage(msg);
                    } else if (Constants.RESPONSE_902.equals(code)) {

                        DebugLog.d(TAG, "announceMessage RESPONSE_902");
                        msg.what = HANDLE_RECEIVE_ANNOUNCE_902;
                        if (mHandler != null)
                            mHandler.sendMessage(msg);
                    } else {
                        if (Constants.RESPONSE_700.equals(code)) {
                            msg.arg2 = 700;
                        } else if (Constants.RESPONSE_710.equals(code)) {
                            msg.arg2 = 710;
                        }
                        msg.what = HANDLE_RECEIVE_ANNOUNCE_700_710_1001;
                        if (mHandler != null)
                            mHandler.sendMessage(msg);
                    }

                } catch (Exception e) {
                    DebugLog.d(TAG, "exception = " + e.getMessage());
                }
            }

        });

    }

    /** do probe runnable*/
    class ProbeRunnable implements Runnable {
        String m_url;

        public ProbeRunnable(String url) {
            this.m_url = url;
        }

        @Override
        public void run() {
            DebugLog.d(TAG, "bandwidth probing start");
            if (mPlayer == null) {
                DebugLog.d(TAG, "bandwidth probing mPlayer == null , so probe start fail");
                notifyProbingCompleted(false); // probe start fail
            } else {
                int probeResult = mPlayer.brandwidthWebViewProbe(m_url);
                DebugLog.d(TAG, "ProbeRunnable probeResult = " + probeResult);

                if (probeResult == -1) {
                    notifyProbingCompleted(false); // probe start fail
                    DebugLog.d(TAG, "ProbeRunnable  probing fail");
                }
            }
            DebugLog.d(TAG, "bandwidth probing thread end");
        }

    }

    /** true -> probe is doing*/
    private boolean isProbeDoing() {
        return mBProbeDoing;
    }

    private BroadcastReceiver boradcastListener;

    /** register boradcast*/
    private void registerBoradcast() {
        IntentFilter intentfilter = new IntentFilter();
        intentfilter.addAction(Constants.RECEIVER_BROADCAST);
        intentfilter.addAction(ConnectivityManager.CONNECTIVITY_ACTION);
        intentfilter.addAction(Intent.ACTION_SCREEN_OFF);
        intentfilter.addAction(Intent.ACTION_SCREEN_ON);
        boradcastListener = new BroadcastReceiver() {
            @Override
            public void onReceive(Context context, Intent intent) {

                DebugLog.d(TAG, "WebViewActivity onReceive");
                DebugLog.e(TAG, "BroadcastReceiver action = " + intent.getAction());
                if (intent.getAction().equalsIgnoreCase(Constants.RECEIVER_BROADCAST)) {
                    Bundle bundle = intent.getExtras();
                    int msgtype = bundle.getInt("msgtype");
                    String msgcontent = bundle.getString("msgcontent");
                    DebugLog.d(TAG, "handleMessage...... msgtype=" + msgtype + ", msgcontent=" + msgcontent);
                    switch (msgtype) {
                    case NotifyManagement.UP_PROBE_BAD_NETWORK:
                        //irtsp 1.12 , WebBrowser is not need to handler the UP_PROBE_BAD_NETWORK event message.
                        /*DebugLog.d(TAG, "UP_PROBE_BAD_NETWORK");
                        mPoorProbingresultFlag = true;
                        mPlayer.bitrate_stopProbe();
                        notifyProbingCompleted(true);*/
                        break;
                    case NotifyManagement.UP_PROBE_EXIT:// callback disconnectCB = 6 when bandwidth probe
                        // success. Up_ui_gc.h
                        DebugLog.d(TAG, "GameActivity.m_player.bitrate_stopProbe()");
                        //notifyProbingCompleted(true);
                        /*if(bExitWaitProbeDone){
                           new Timer().schedule(new LogoutTimer(), 100);
                        }*/
                        break;
                    case NotifyManagement.UP_PROBE_EXIT_FAIL:// callback disconnectCB = 10 when bandwidth probe
                        // fail. Up_ui_gc.h
                        DebugLog.d(TAG,
                                "WebViewActivity.onStart() probe fail, GameActivity.m_player.bitrate_stopProbe()");
                        //mPlayer.bitrate_stopProbe();
                        notifyProbingCompleted(false);
                        /*if(bExitWaitProbeDone){
                           new Timer().schedule(new LogoutTimer(), 100);
                        }*/
                        break;
                    case NotifyManagement.UP_GAME_NOTIFY_DISPLAYTEXT:
                        DebugLog.d(TAG, "notify UP_GAME_NOTIFY_DISPLAYTEXT");
                        gBNotifyDisplayExit = true;
                        gNotifyDisplayText = msgcontent;

                        break;
                    case NotifyManagement.LOCAL_BROADCAST_CALL_UPDATE_STATE_200:
                        callJsUpdateStatus(Constants.RESPONSE_200);
                        break;

                    case NotifyManagement.LOCAL_NOTIFY_WEBJS_GET_DUI:
                        String gid = bundle.getString("gid");
                        String useragent = bundle.getString("useragent");
                        DebugLog.d(TAG, "notify webview js get DUI gid=" + gid + ",useragent=" + useragent);
                        setToJsPlayMetadata(gid, useragent);
                        break;
                    case NotifyManagement.LOCAL_GAMEACTIVITY_RESULT:
                        DebugLog.d(TAG, "Constants.LOCAL_GAMEACTIVITY_RESULT");
                        ((LoadWebJsActivity) mWebviewActivity).handleGameActivityResult();
                        break;

                    case NotifyManagement.CAST_SESSION_STATUS_WEB:
                        DebugLog.d(TAG, "build session have done");

                        String deviceId;
                        String deviceName;
                        String status;

                        deviceId = bundle.getString("deviceId");
                        deviceName = bundle.getString("deviceName");
                        status = bundle.getString("status");
                        retPlayOnCast(deviceId, deviceName, status);

                        synchronized (mLock) {
                            mLock.notify();
                            DebugLog.d(TAG, "notify the thread");
                        }

                        break;
                    }
                } else if (intent.getAction().equals(ConnectivityManager.CONNECTIVITY_ACTION)) {
                    processNetworkType(intent, context);
                }

                if (intent.getAction().compareTo(Intent.ACTION_SCREEN_OFF) == 0) {
                    DebugLog.d(TAG, "POWER ACTION_SCREEN_OFF");
                    final LoadWebJsActivity loadWebJsActivity = (LoadWebJsActivity) mContext;
                    loadWebJsActivity.gBEntryPowerKeyMode = true;
                    loadWebJsActivity.gCurEntryBackgroundTime = System.currentTimeMillis();
                } else if (intent.getAction().compareTo(Intent.ACTION_SCREEN_ON) == 0) {
                    DebugLog.d(TAG, "POWER ACTION_SCREEN_ON");
                    final LoadWebJsActivity loadWebJsActivity = (LoadWebJsActivity) mContext;
                    loadWebJsActivity.gBEntryPowerKeyMode = false;
                    //   loadWebJsActivity.gCurEntryBackgroundTime = 0;

                }
            }
        };
        this.mContext.registerReceiver(boradcastListener, intentfilter);
    }

    /**
     * 
     * client -> web JS
     * @param gid
     * @param useragent
     */
    private void setToJsPlayMetadata(String gid, String useragent) {
        String request_getPlayMetadata = "{\"id\": \"" + gid + "\",\"type\": \"get\"," + "\"userAgent\": \""
                + useragent + "\"}";
        ubiGCPlayerCallback("getPlayMetadata", request_getPlayMetadata);
    }

    /**
     * 
     * @param jsonData
     */
    private void getPlayMetadata(final String jsonData) {
        ((Activity) mContext).runOnUiThread(new Runnable() {
            @Override
            public void run() {
                // TODO Auto-generated method stub
                JSONObject json = null;
                String code = null;
                String message = null;
                String id = null;
                String dynamicUrl = null;
                try {
                    json = new JSONObject(jsonData);
                    code = json.optString("code");
                    message = json.optString("message");
                    id = json.optString("id");
                    dynamicUrl = json.optString("dynamicUrl");
                    if (code.equals("200")) {
                        DebugLog.d(TAG, "getPlayMetadata success message=" + message + ",id=" + id + ",dynamicUrl="
                                + dynamicUrl);
                        mPlayer.getJsonDUI(jsonData);
                    }

                } catch (JSONException e) {
                    DebugLog.d(TAG, "exception = " + e.getMessage());
                }
            }

        });

    }

    private String quitGame(String jsonData) {
        String result = null;
        try {
            JSONObject json = new JSONObject(jsonData);
            String id = json.optString("id");
            result = "{" + "\"id\": \"" + id + "\"," + "\"type\": \"result\"," + "\"code\": \""
                    + Constants.RESPONSE_200 + "\"," + "\"message\": \"success\"" + "}";
        } catch (Exception e) {
            // TODO Auto-generated catch block
            DebugLog.d(TAG, "exception = " + e.getMessage());
            result = "{" + "\"code\": \"" + Constants.RESPONSE_500
                    + "\",\"message\": \" player internal error(500) \"}";
        }

        this.ubiGCPlayerCallback("quitGame", result);

        return result;
    }

    /**
     * WebView -> Android application
     * @param jsonData
     */
    private String putClientProfile(String jsonData) {
        String result = null;
        JSONObject json = null;
        String id = null;
        String type = null;
        String data = null;
        try {
            json = new JSONObject(jsonData);
            id = json.optString("id");
            type = json.optString("type");
            data = json.optString("data");
        } catch (Exception e) {
            // TODO Auto-generated catch block
            DebugLog.d(TAG, "exception = " + e.getMessage());
            result = "{" + "\"code\": \"" + Constants.RESPONSE_500
                    + "\",\"message\": \" player internal error(500) \"}";
            return result;
        }

        if (data != null && !"".equals(data)) {
            //get data success
            int res = mPlayer.putClientProfile(jsonData);
            if (res == 0) {
                result = "{" + "\"id\": \"" + id + "\"," + "\"type\": \"result\"," + "\"code\": \""
                        + Constants.RESPONSE_200 + "\"," + "\"message\": \"success\"" + "}";
            } else {
                result = "{\"code\": \" " + Constants.RESPONSE_500
                        + " \",\"message\":\"player internal error(500)\"}";
            }
        }
        DebugLog.e(TAG, "line 553 putClientProfile = " + jsonData);
        ubiGCPlayerCallback("putClientProfile", result);
        return result;
    }

    private String updateSoftware(String jsonData) {
        String result = null;
        try {
            JSONObject json = new JSONObject(jsonData);
            String id = json.optString("id");
            String type = json.optString("type");
            String upgradeUrl = json.optString("upgradeUrl");
            String upgradeVideo = json.optString("upgradeVideo");
            result = "{" + "\"id\": \"" + id + "\"," + "\"type\": \"result\"," + "\"code\": \""
                    + Constants.RESPONSE_200 + "\"," + "\"message\": \"success\"" + "}";

            if (upgradeUrl != null && !"".equals(upgradeUrl)) {
                final String strUpgradeUrl = upgradeUrl;
                ((Activity) this.mContext).runOnUiThread(new Runnable() {
                    @Override
                    public void run() {
                        // TODO Auto-generated method stub
                        new VersionAutoUpdate(mContext, strUpgradeUrl);
                    }
                });

                result = "{\"code\": \" " + Constants.RESPONSE_200 + " \",\"message\":\" success \" }";
            } else {
                result = "{\"code\": \" " + Constants.RESPONSE_500
                        + " \",\"message\":\" player internal error(500) \" }";
            }
        } catch (Exception e) {
            DebugLog.d(TAG, "exception = " + e.getMessage());
            result = "{" + "\"code\": \"" + Constants.RESPONSE_500
                    + "\",\"message\": \" player internal error(500) \"}";
        }
        ubiGCPlayerCallback("updateSoftware", result);
        return result;
    }

    private void handleWebSession(String jsonData) {
        DebugLog.d(TAG, "ubiGCPlayerCallback()  handleWebSession() jsonData = " + jsonData);
    }

    private void callJsHandleWebSession(boolean connect) {
        String action = null;
        if (connect) {
            action = "connect";
        } else {
            action = "disconnect";
        }
        String jsonData = "{\"id\": \"" + mUniqueId + "\", \"type\": \"set\",\"action\": \"" + action + "\"}";
        ubiGCPlayerCallback("handleWebSession", jsonData);
    }

    /**
     * JavaScript callBack method 
     * JSON Data Example 
     * { 
     * "id": "dsfdh34576dfgg76",
     * "type": "set", 
     * "target ": "webview",
     *  "url":"http://alpha-touch.hangame.co.jp/registration/gamecloud/input.nhn" }
     * ================= 
     * response JSON Data Example
     * {
     * "id": "dsfdh34576dfgg76",
     * "type": "result",
     * "code": "200",
     * "message": "success"
     * }
     * 
     * @param parameter
     * 
     */
    public String openWindow(String parameter) {
        DebugLog.d(TAG, "webview call openWindow()  parameter = " + parameter);
        JSONObject json;
        String response = null;
        ;
        try {
            json = new JSONObject(parameter);
            String id = json.optString("id");
            String type = json.optString("type");
            String target = json.optString("target");
            final String url = json.optString("url");
            final String windowName = json.optString("windowName");

            String resErrorStr = "{\"id\": \"" + id + "\", \"type\": \"result\", \"code\": \""
                    + Constants.RESPONSE_500 + "\", \"message\": \"" + Constants.RESPONSE_INTERNAL_ERROR + "\"}";
            String resSusscessStr = "{\"id\": \"" + id + "\", \"type\": \"result\", \"code\": \""
                    + Constants.RESPONSE_200 + "\", \"message\": \"" + Constants.RESPONSE_SUCCESS + "\"}";
            DebugLog.d(TAG, "id=" + id + ",type = " + type + ",target=" + target + ",url = " + url);

            if ("".equals(id) || id == null || "".equals(type) || type == null || "".equals(url) || url == null
                    || "".equals(target) || target == null) {
                response = resErrorStr;
                DebugLog.d(TAG, "parameter is null return");
                return response;
            }
            if ("webview".equalsIgnoreCase(target)) {
                DebugLog.d(TAG, "webview open a new window ");
                ((Activity) this.mContext).runOnUiThread(new Runnable() {
                    @Override
                    public void run() {
                        //add 20130407
                        putListOpenTabName(windowName);
                        newWindow(url);

                    }
                });
                response = resSusscessStr;
            } else {//adopt default android-system browser
                if (mWebviewActivity != null) {
                    ((Activity) mContext).runOnUiThread(new Runnable() {
                        @Override
                        public void run() {
                            // TODO Auto-generated method stub
                            Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(url));
                            mWebviewActivity.startActivity(intent);
                        }
                    });
                    response = resSusscessStr;
                } else {
                    DebugLog.d(TAG, "mWebviewActivity is null");
                    response = resErrorStr;
                }
            }
            //return response;
        } catch (JSONException e) {
            DebugLog.d(TAG, "exception = " + e.getMessage());
        }
        ubiGCPlayerCallback("openWindow", response);
        return response;
    }

    /** open new browser */
    public void newWindow(String url) {
        if ("".equals(url) || url == null) {
            return;
        }
        Message msg = new Message();
        msg.what = HANDLE_OPEN_NEW_WINDOW;
        msg.obj = url;
        if (mHandler != null)
            mHandler.sendMessage(msg);
    }

    /**
     * JavaScript call back method
     * remove child browser 
     */
    public void removeChildBrowser() {
        DebugLog.d(TAG, "removeChildBrowser()");
        Message msg = new Message();
        msg.what = HANDLE_CLOSE_CHILD_BROWSER;
        mHandler.sendMessage(msg);
    }

    /** open new browser in UI thread */
    private void handleOpenNewWindow(String url) {
        ChildBrowser mChildBrowser = new ChildBrowser(Utils.checkUrl(url), mContext, this, mChildViewList);
        View currentView = mChildBrowser.getChildView();
        mRootView.removeAllViews();
        mRootView.addView(currentView);
        mChildViewList.add(0, currentView);
        mChildWebviewLst.add(0, mChildBrowser.getChildWebview());
        currentView.requestFocus();
        mChildBrowser.setOnClildBrowserListener(new ClildBrowserListener() {
            @Override
            public void closeCurrentWindow() {
                removeChildBrowser();

            }
        });
    }

    /* remove child window*/
    public void handleRemoveChildBrowser() {
        DebugLog.d(TAG, "removeChildBrowserWindow() childViewList.size = " + mChildViewList.size());
        if (mChildWebviewLst.size() > 1) {
            mChildWebviewLst.remove(0);
        }
        if (mChildViewList.size() > 1) {
            //add 20130407
            removeListOpenTabName();

            mRootView.removeAllViews();
            mChildViewList.remove(0);
            if (mChildViewList.size() == 1) {
                DebugLog.d(TAG, "webview Url = " + mWebView.getUrl());
                if (GameInfo.isErrorUrl(mWebView.getUrl()))
                    mWebView.reload();
            }
            View currentView = mChildViewList.get(0);
            mRootView.addView(currentView);
            currentView.requestFocus();
            //         flProgress.setVisibility(View.GONE);
        } else {
            GameActivity.g_bIsClickPurchase = false;
            mWebviewActivity.finish();
        }
    }

    /**
     * JavaScript call back method
     * remove child browser 
     */

    private final Handler mHandler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            switch (msg.what) {
            case HANDLE_POORPROBINGRESULT:
                handlePoorProbingResult(msg.obj.toString());
                break;
            case HANDLE_PROHIBIT_PLAY:
                handleProhibitPlay(msg.obj.toString());
                break;
            case HANDLE_PROHIBIT_CHECKAVAILABLENETWORK:
                handleProhibitCheckAvailableNetwork(msg.obj.toString());
                break;
            case HANDLE_CHECKAVAILABLENETWORK_LTE:
                handleCheckAvailableNetworkLTE(msg.obj.toString());
                break;
            case HANDLE_OPEN_NEW_WINDOW:
                handleOpenNewWindow(msg.obj.toString());
                break;
            case HANDLE_CLOSE_CHILD_BROWSER:
                handleRemoveChildBrowser();
                break;
            case HANDLE_GET_BANDWIDTH_PROBING_URI:
                // DebugLog.d(TAG,
                // "call javascript:playerNotification.getBandwidthProbingUri()");

                // ubiGCPlayerCallback("getBandwidthProbingUri",msg.obj.toString());

                break;

            case 1102:
                DebugLog.i(TAG, "selectDevice ");
                chromecast.selectDevice(mContext, new DeviceSelectionDialog.DeviceSelectionListener() {

                    @Override
                    public void onSelected(DeviceSelectionDialog dialog) {

                        DebugLog.e(TAG, "select chromecast");

                        CastDevice device = dialog.selectedDevice();
                        if (device != null) {
                            DebugLog.e(TAG, "select chromecast:" + dialog.selectedDevice().getFriendlyName());

                            haveCastDevice = true;
                            GCApplication.getApplication().setDevice(device);
                            chromecast.startCastWaitingDialog(device.getFriendlyName());
                            /** the chromecast connect timeout 10s */
                            chromecast.setCastWaitTimeout(0, 20);
                            chromecast.setSelectedDevice(device);

                        } else {
                            DebugLog.e(TAG, "have no device");
                        }
                    }

                    @Override
                    public void onCancelled(DeviceSelectionDialog dialog) {

                        haveCastDevice = false;
                        retPlayOnCast(null, null, null);

                        synchronized (mLock) {
                            mLock.notify();
                            DebugLog.e(TAG, "notify the thread");
                        }
                    }

                });

                break;
            case HANDLE_RECEIVE_ANNOUNCE_901:
                DebugLog.d(TAG, "HANDLE_RECEIVE_ANNOUNCE_901 send cast");
                if (Constants.TOAST_BEHAVIOR_CTR_IN_IDLE) {
                    sCtrToast = null;
                    sCtrToast = new GCToastControl(mContext, msg.obj.toString());
                } else {
                    Utils.showPopUpMessager(mContext, msg.obj.toString(),
                            Gravity.CENTER_HORIZONTAL | Gravity.BOTTOM, GCToastControl.TOAST_901_700_DURATION_TIME);
                }

                break;

            case HANDLE_RECEIVE_ANNOUNCE_902:
                DebugLog.d(TAG, "HANDLE_RECEIVE_ANNOUNCE_902 send cast");
                notifyClosePlayerWebJS();
                Intent i = new Intent(Constants.TICKET_EXPIRED_BROADCAST);
                Bundle data = new Bundle();
                data.putString("message", msg.obj.toString());
                i.putExtras(data);
                mContext.sendBroadcast(i);
                break;
            case HANDLE_RECEIVE_ANNOUNCE_700_710_1001:
                DebugLog.d(TAG, "HANDLE_RECEIVE_ANNOUNCE_700_710_1001 send cast msg.arg1 = " + msg.arg1);
                if (msg.arg1 == ANNOUNCEMESSAGE_PRESENTMODE_TWINKLE) {
                    DebugLog.d(TAG, "ANNOUNCE_700_710_1001 line1042");
                    if (Constants.TOAST_BEHAVIOR_CTR_IN_IDLE) {
                        sCtrToast = null;
                        sCtrToast = new GCToastControl(mContext, msg.obj.toString());
                    } else {
                        Utils.showPopUpMessager(mContext, msg.obj.toString(),
                                Gravity.CENTER_HORIZONTAL | Gravity.BOTTOM,
                                GCToastControl.TOAST_901_700_DURATION_TIME);
                    }

                } else {
                    if (700 == msg.arg2 || 710 == msg.arg2) {
                        Intent i2 = new Intent(Constants.ANNOUCEMSG_MAINTENANCE_700_710);
                        Bundle data2 = new Bundle();
                        data2.putString("message", msg.obj.toString());
                        i2.putExtras(data2);
                        mContext.sendBroadcast(i2);
                    } else {
                        notifyClosePlayerWebJS();
                        Intent i2 = new Intent(Constants.TICKET_EXPIRED_BROADCAST);
                        Bundle data2 = new Bundle();
                        data2.putString("message", msg.obj.toString());
                        i2.putExtras(data2);
                        mContext.sendBroadcast(i2);
                    }
                }
                break;

            default:
                break;
            }
        }
    };

    private void saveAccountAndPassword(String parameter) {
        String result = null, id = null;
        try {
            JSONObject json = new JSONObject(parameter);
            id = json.getString("id");

            String account = "";
            String password = "";
            String domain = "";
            boolean cleanRecord = false;

            if (!json.isNull("cleanRecord") && Boolean.parseBoolean(json.getString("cleanRecord"))) {
                cleanRecord = true;
            }

            if (!json.isNull("domain")) {
                domain = json.getString("domain");
            }

            if (!cleanRecord) {
                account = json.getString("account");
                password = json.getString("password");
            }
            /*((Activity)mContext).runOnUiThread(new Runnable(){
               @Override
               public void run() {*/
            // TODO Auto-generated method stub
            //encode
            String enAccount = mPlayer.setAesEncode(account);
            String enPassword = mPlayer.setAesEncode(password);
            String enDomain = mPlayer.setAesEncode(domain);

            SharedPreferences gcWebPreference = PreferenceManager.openPrference(mContext,
                    Constants.REMEMBER_PREFERENCE_DB);
            HashMap<String, String> editorValue = new HashMap<String, String>();
            editorValue.put(Constants.REMEMEBER_ACCOUNT_KEY, enAccount);
            editorValue.put(Constants.REMEMEBER_PASSWORD_KEY, enPassword);
            editorValue.put(Constants.REMEMEBER_DOMAIN_KEY, enDomain);
            PreferenceManager.updateParamsValue(gcWebPreference, editorValue);
            //}});

            result = "{\"id\": \"" + id
                    + "\",\"type\": \"result\",\"code\": \"200\",\"message\": \"success(200)\"}";
        } catch (Exception e) {
            DebugLog.d(TAG, "exception = " + e.getMessage());
            result = "{\"id\": \"" + id
                    + "\",\"type\": \"result\",\"code\": \"500\",\"message\": \"player internal error(500) \"}";
        }
        this.ubiGCPlayerCallback("saveAccountAndPassword", result);
    }

    /**
     * JavaScript callBack method
     * @param url
     */
    private void getAccountAndPassword(String parameter) {
        String result = null, id = null;
        try {
            JSONObject json = new JSONObject(parameter);
            id = json.getString("id");
            SharedPreferences gcWebPreference = PreferenceManager.openPrference(mContext,
                    Constants.REMEMBER_PREFERENCE_DB);
            String account = PreferenceManager.getParamsValue(gcWebPreference, Constants.REMEMEBER_ACCOUNT_KEY);
            String password = PreferenceManager.getParamsValue(gcWebPreference, Constants.REMEMEBER_PASSWORD_KEY);
            String domain = PreferenceManager.getParamsValue(gcWebPreference, Constants.REMEMEBER_DOMAIN_KEY);
            //decode         
            account = mPlayer.getAesDecode(account);
            password = mPlayer.getAesDecode(password);
            domain = mPlayer.getAesDecode(domain);
            //Toast.makeText(this.context, account, Toast.LENGTH_SHORT).show();
            if (null == account || "".equals(account) || null == password || "".equals(password)) {
                result = "{\"id\": \"" + id
                        + "\",\"type\": \"result\",\"code\": \"500\",\"message\": \"player internal error(500) \"}";
            } else {
                result = "{\"id\": \"" + id
                        + "\",\"type\": \"result\",\"code\": \"200\", \"message\": \"success\",\"account\": \""
                        + account + "\",\"password\": \"" + password + "\",\"domain\": \"" + domain + "\"}";
            }
        } catch (Exception e) {
            DebugLog.d(TAG, "exception = " + e.getMessage());
            result = "{\"id\": \"" + id
                    + "\",\"type\": \"result\",\"code\": \"500\",\"message\": \"player internal error(500) \"}";
        }
        this.ubiGCPlayerCallback("getAccountAndPassword", result);
        //return result;
    }

    /**
     * WebServer - > client
     * BillingActivity
     * start purchase
     * will start BillingActivity.
     * @param jsonData
     * @return
     */
    /*private String  purchaseInApp(final String jsonData) {
       DebugLog.d(TAG, "call purchaseInApp()");
           
       {
      "id": "dsfdh34576dfgg76",
      "type": "set",
      "appName": "ubitusgc",  //will be used as keyword parameter for API: getInAppContents(java.lang.String keyword,
                                             InAppPurchasor.DiscoveryParameters params)
      "method": "VCAST",
      "properties": {
         "sku": "123456789012345678901234", //refer to PurchaseLevel.doPurchase(), purchaseParameters.setSku()
         "contentType": "Application - In App",
         "priceType": "Per Period", //refer to PurchaseLevel.doPurchase(), purchaseParameters.setPriceType()
         "price": "1.99", //refer to purchaseParameters.setPrice(float price) 
         "inAppName": "SSF4" //will be used in purchaseInAppContent(java.lang.String keyword, java.lang.String itemID, InAppPurchasor.PurchaseParameters purchaseParameters)
                        // there is a field named "inAppName" in PurchaseParameters class object, refer to PurchaseLevel.doPurchase(), purchaseParameters.setInAppName()
      }
       }
           
           
       ((Activity) mContext).runOnUiThread(new Runnable() {
        
     @Override
     public void run() {
        // TODO Auto-generated method stub
        String result = null; 
        Intent intent = new Intent();
        
        intent.setClass(mContext, BillingActivity.class);
        //intent.setClass(mContext, VzwSdkIntegrationApp.class);
        intent.putExtra("jsonData", jsonData);
        sIsBillingTriggered = true;//disable timeout single
        mWebviewActivity.startActivityForResult(intent, Constants.START_BILLINGACTIVITY_REQUEST_CODE);
     }
         
       });
           
       return null;
    }*/

    /**
      * WebServer - > client
      * BillingActivity
      * start purchase
      * will start BillingActivity.
      * @param jsonData
      * @return
      */
    private String purchaseInApp(final String jsonData) {
        DebugLog.d(TAG, "call purchaseInApp()");

        purchaseForPphone(jsonData);

        return null;
    }

    /**
     * //for PPhone protocol
     * @param jsonData
     *  {
        "id": "dsfdh34576dfgg88",
        "type": "set",
        "properties" : {
           "billingItemId" : "12345",
         }
        }
            
        callback as below:
            
        {
            "id": "dsfdh34576dfgg76",
            "type": "result",
            "code": success(200), webview internal error(600)
            "message": "success"
        }
     */
    private void purchaseForPphone(final String jsonData) {
        DebugLog.d(TAG, "call purchaseForPPhone() ");
        String jStrId = "";
        try {
            JSONObject json = new JSONObject(jsonData);
            jStrId = json.getString("id");
            String jStrType = json.getString("type");
            JSONObject jObjProperties = json.getJSONObject("properties");
            //              String billingItemId = jObjProperties.getString("billingItemId");
            int billingItemId = jObjProperties.getInt("billingItemId");
            if (((LoadWebJsActivity) mContext).mBillingPphone != null) {
                ((LoadWebJsActivity) mContext).mBillingPphone.doPuchaseInAppGame(jStrId, billingItemId);
            }
        } catch (Exception e) {
            DebugLog.d(TAG, "inAppgamePurchase exception = " + e.getMessage());
            String callbackErrorRs = "{\"id\": \"" + jStrId + "\",\"type\": \"result\",\"code\": \""
                    + Constants.RESPONSE_600 + "\",\"message\": \"failure\"}";
            ubiGCPlayerCallback("purchaseInApp", callbackErrorRs);
        }
    }

    /**
     * For pphone protocol ,callback the purchase result
     * be invoked by Billingpphone purchase result interface.
     * @param bSuccess
     * @param rsReceipt
     * @param strPurchaseGameSessionId
     */
    public void notifyPurchaseResultByPphone(boolean bSuccess, String rsReceipt, String strPurchaseGameSessionId) {
        DebugLog.d(TAG, "call notifyPurchaseResultBypphone() bSuccess = " + bSuccess);
        String strCbPurchaseResult = "";
        if (bSuccess && rsReceipt != null && !"".equals(rsReceipt)) {
            byte[] licenseBytes = rsReceipt.getBytes();
            String base64license = Base64.encodeToString(licenseBytes, Base64.DEFAULT);
            strCbPurchaseResult = "{\"id\": \"" + strPurchaseGameSessionId + "\",\"type\": \"result\",\"code\": \""
                    + Constants.RESPONSE_200 + "\",\"message\": \"success\"}";
            mReceiptMap.put(strPurchaseGameSessionId, base64license);

        } else {
            strCbPurchaseResult = "{\"id\": \"" + strPurchaseGameSessionId + "\",\"type\": \"result\",\"code\": \""
                    + Constants.RESPONSE_600 + "\",\"message\": \"failure\"}";

        }
        DebugLog.d(TAG, "call notifyPurchaseResultBypphone() ubiGCPlayerCallback result = " + strCbPurchaseResult);
        ubiGCPlayerCallback("purchaseInApp", strCbPurchaseResult);
    }

    /**
     * Client -> client - >WebServer
     * BillingActivity
     * get the purchase result from billingActivity
     * will put the result to local receiptMap
     * @param bSuccess
     * @param license
     * @param strId ----session id (req -> res)
     */
    public void notifyPurchaseResult(boolean bSuccess, String license, String strId) {
        DebugLog.d(TAG, "call notifyPurchaseResult() bSuccess = " + bSuccess);
        String request;
        /**
        {
            "id": "dsfdh34576dfgg76",
            "type": "result",
            "code": "200",
            "message": "success",
            "receipt": "xxxxx" //this xxxx stands for the base64 encoded license string
        }    
        */
        if (bSuccess && license != null) {

            byte[] licenseBytes = license.getBytes();
            String base64license = Base64.encodeToString(licenseBytes, Base64.DEFAULT);
            //request = "{\"id\": \""+ strId + "\",\"type\": \"result\",\"code\": \""+Constants.RESPONSE_200+"\",\"message\": \"success\",\"receipt\": \"" + base64license + "\"}";
            request = "{\"id\": \"" + strId + "\",\"type\": \"result\",\"code\": \"" + Constants.RESPONSE_200
                    + "\",\"message\": \"success\"}";
            mReceiptMap.put(strId, base64license);
        } else {

            request = "{\"id\": \"" + strId + "\",\"type\": \"result\",\"code\": \"" + Constants.RESPONSE_500
                    + "\",\"message\": \"failure\"}";
        }

        DebugLog.d(TAG, "javascript:playerNotification.notifyPurchaseResult. request = " + request);

        ubiGCPlayerCallback("purchaseInApp", request);

        mBillingStatus = Constants.BILLING_STATUS_END;
        sIsBillingTriggered = false;
    }

    /**
     * Webserver -> client
     * BillingActivity
     * will invoke after purchaseInApp()
     * @param sessionId
     * @return
     */
    public String ubiGCPlayerGetReceipt(String sessionId) {
        DebugLog.d(TAG, "ubiGCPlayerGetReceipt sessionId = " + sessionId);
        String result;
        if (null == sessionId || null == mReceiptMap) {
            return "";
        }

        result = mReceiptMap.get(sessionId);
        return result;
    }

    private void processNetworkType(Intent intent, Context context) {
        int netType;
        int netSubtype;
        int networkType;
        boolean isConnected;
        String reloadUrl;
        DebugLog.d(TAG, "processNetworkType() enter");

        NetworkInfo netInfo = Utils.getCurNetworkInfo(context);
        if (netInfo == null || netInfo.isAvailable() == false) {
            DebugLog.d(TAG, "getCurNetworkInfo() is null");
            netInfo = (NetworkInfo) intent.getParcelableExtra(ConnectivityManager.EXTRA_NETWORK_INFO);
        }

        if (netInfo == null || netInfo.isAvailable() == false) {
            DebugLog.d(TAG, "getCurNetworkInfo() netInfo is null line1383");
            if (mbNetworIsConnect != false) {
                mbNetworIsConnect = false;
                reloadUrl = GameInfo.getErrorUrl();
                reload(reloadUrl);
            }
            Utils.setNetworkType(Constants.NETWORKTYPE_NONE);
            return;
        }
        netType = netInfo.getType();
        netSubtype = netInfo.getSubtype();
        isConnected = netInfo.isConnected();
        DebugLog.e(TAG, "======processNetworkType nettype = " + netType + ",netSubtype = " + netSubtype
                + ",isConnect = " + isConnected);
        switch (netType) {
        case ConnectivityManager.TYPE_MOBILE_SUPL:
        case ConnectivityManager.TYPE_MOBILE_MMS:
        case ConnectivityManager.TYPE_MOBILE_HIPRI:
        case ConnectivityManager.TYPE_MOBILE_DUN:
        case ConnectivityManager.TYPE_MOBILE:
            DebugLog.d(TAG, "processNetworkType ConnectivityManager.TYPE_MOBILE netSubtype=" + netSubtype);
            if (netSubtype == TelephonyManager.NETWORK_TYPE_LTE) {//4
                DebugLog.d(TAG, "processNetworkType ConnectivityManager.TYPE_MOBILE 4G");
                networkType = Constants.NETWORKTYPE_LTE;
            } else {//3
                DebugLog.d(TAG, "processNetworkType ConnectivityManager.TYPE_MOBILE 3G");
                networkType = Constants.NETWORKTYPE_3G;
            }
            break;
        case ConnectivityManager.TYPE_WIFI:
            DebugLog.d(TAG, "processNetworkType ConnectivityManager.TYPE_WIFI");
            networkType = Constants.NETWORKTYPE_WIFI;
            break;
        case ConnectivityManager.TYPE_ETHERNET:
            DebugLog.d(TAG, "processNetworkType ConnectivityManager.TYPE_ETHERNET");
            networkType = Constants.NETWORKTYPE_ETHERNET;
            break;
        default:
            DebugLog.d(TAG, "other network status");
            networkType = Constants.NETWORKTYPE_OTHERS;
            break;
        }
        DebugLog.e(TAG, "======processNetworkType nettype = " + netType + ",netSubtype = " + netSubtype
                + ",isConnect = " + isConnected + ",mbNetworIsConnect = " + mbNetworIsConnect);
        if (isConnected) {
            reloadUrl = Utils.checkUrl(GameInfo.DEFAULT_URL);
            Utils.setNetworkType(networkType);
            //         Utils.setNetworkType(Constants.NETWORKTYPE_WIFI);//temp change
        } else {
            reloadUrl = GameInfo.getErrorUrl();
            Utils.setNetworkType(Constants.NETWORKTYPE_NONE);
        }

        //      if((networkType == Constants.NETWORKTYPE_WIFI || networkType == Constants.NETWORKTYPE_LTE) && mbNetworIsConnect != isConnected){
        if (mbNetworIsConnect != isConnected) {
            mbNetworIsConnect = isConnected;
            reload(reloadUrl);
            DebugLog.d(TAG, "Notify reload finish");
        }
    }

    private void handleCheckAvailableNetworkLTE(final String jsonData) {
        JSONObject json;
        try {
            json = new JSONObject(jsonData);
            final String id = json.optString("id");

            //TODO
            if (Constants.sIsEnableNetworkLte) {
                Utils.showYesNoPrompt(mContext, GameActivityRes.STRING_WARNING,
                        GameActivityRes.STRING_NETWORKTYPE_CHECKAVAILABLENETWORK_LTE_MSG,
                        GameActivityRes.STRING_NETWORKTYPE_BACKTO_TOPPAGE,
                        GameActivityRes.STRING_NETWORKTYPE_ACCEPT_USE_LTE,

                        new DialogInterface.OnClickListener() {
                            @Override
                            public void onClick(DialogInterface dialog, int which) {
                                notifyCheckAvailableNetworkError(id);
                                dialog.dismiss();
                            }
                        }, new DialogInterface.OnClickListener() {
                            @Override
                            public void onClick(DialogInterface dialog, int which) {
                                Constants.sIsAcceptLteUsage = true;
                                SharedPreferences gcWebPreference = PreferenceManager.openPrference(mContext,
                                        Constants.REMEMBER_PREFERENCE_DB);
                                HashMap<String, String> editorValue = new HashMap<String, String>();
                                editorValue.put(Constants.REMEMEBER_ACCEPT_USE_LTE, "true");
                                PreferenceManager.updateParamsValue(gcWebPreference, editorValue);
                                Utils.startGameActivity(mContext, mWebviewActivity, null, null, null);
                                mPlayer.ubiGCPlayerInvoke("checkAvailableNetwork", jsonData);
                                dialog.dismiss();
                            }
                        });
            } else {
                notifyCheckAvailableNetworkError(id);
                Utils.showYesNoPrompt(mContext, GameActivityRes.STRING_WARNING,
                        GameActivityRes.STRING_NETWORKTYPE_CHECKAVAILABLENETWORK_NOTALLOWLTE_MSG,
                        GameActivityRes.STRING_NETWORKTYPE_BACKTO_TOPPAGE, GameActivityRes.STRING_NETWORKTYPE_SETUP,

                        new DialogInterface.OnClickListener() {
                            @Override
                            public void onClick(DialogInterface dialog, int which) {
                                dialog.dismiss();
                            }
                        }, new DialogInterface.OnClickListener() {
                            @Override
                            public void onClick(DialogInterface dialog, int which) {
                                Utils.showNetworkCfgDialog(mWebviewActivity, null);
                                dialog.dismiss();
                            }
                        });
            }
        } catch (JSONException e) {
            // TODO Auto-generated catch block
            DebugLog.d(TAG, "excepion = " + e.getMessage());
        }
    }

    private void handleProhibitCheckAvailableNetwork(String jsonData) {
        JSONObject json;
        try {
            json = new JSONObject(jsonData);
            mPlayId = json.optString("id");
            DebugLog.d(TAG, "handleProhibitCheckAvailableNetwork() enter");

            String result = "{\"code\": \"" + Constants.RESPONSE_500
                    + "\",\"message\": \"Only allow to play game under LTE or WIFI.\"}";
            ubiGCPlayerCallback("checkAvailableNetwork", result);

            notifyClosePlayerWebJS();
            callJsUpdateStatus(Constants.RESPONSE_302);

            WebBrowser.sGameExitStatus = Constants.GAMEACTIVITY_ALERT_DIALOG_TYPE_NOT_LTEWIFI;
            DebugLog.d(TAG, "====prohibit play in 3G network=====");
            Utils.ShowOKPrompt(mContext, GameActivityRes.STRING_WARNING, GameActivityRes.STRING_NETWORKTYPE_WRN_3G,
                    GameActivityRes.STRING_NETWORKTYPE_CLOSEAPK, new DialogInterface.OnClickListener() {
                        @Override
                        public void onClick(DialogInterface dialog, int which) {
                            LoadWebJsActivity.sGameingExitAndExitApp = true;
                            Bundle bundle = new Bundle();
                            bundle.putInt("msgtype", NotifyManagement.LOCAL_GAMEACTIVITY_RESULT);
                            Intent intent = new Intent(Constants.RECEIVER_BROADCAST);
                            intent.putExtras(bundle);
                            WebBrowser.this.mContext.sendBroadcast(intent);
                            dialog.dismiss();
                        }
                    });
        } catch (JSONException e) {
            // TODO Auto-generated catch block
            DebugLog.d(TAG, "excepion = " + e.getMessage());
        }

    }

    //   private void notifyCheckAvailableNetworkSuccess(String id)
    //   {
    //       DebugLog.d(TAG, "notifyCheckAvailableNetworkSuccess() enter");
    //        String result = "{\"code\": \""+Constants.RESPONSE_200+"\",\"message\": \"Allow to play game.\"}";   
    //        ubiGCPlayerCallback("checkAvailableNetwork", result);
    //   }

    private void notifyCheckAvailableNetworkError(String id) {
        DebugLog.d(TAG, "notifyCheckAvailableNetworkError() enter");
        String result = "{" + "\"id\": \"" + id + "\"," + "\"code\": \"" + Constants.RESPONSE_500
                + "\",\"message\": \"Only allow to play game under LTE or WIFI.\"}";
        ubiGCPlayerCallback("checkAvailableNetwork", result);
        callJsUpdateStatus(Constants.RESPONSE_302);
        WebBrowser.sGameExitStatus = Constants.GAMEACTIVITY_ALERT_DIALOG_TYPE_NOT_LTEWIFI;
    }

    private void notifyProhibitPlay(String jsonData) {
        DebugLog.d(TAG, "notifyProhibitPlay() enter");
        JSONObject json;
        try {
            json = new JSONObject(jsonData);
            mPlayId = json.optString("id");
            String result = "{\"code\": \"" + Constants.RESPONSE_500
                    + "\",\"message\": \"Only allow to play game under LTE or WIFI.\"}";
            ubiGCPlayerCallback("play", result);

            notifyClosePlayerWebJS();
            callJsUpdateStatus(Constants.RESPONSE_302);
        } catch (JSONException e) {
            // TODO Auto-generated catch block
            DebugLog.d(TAG, "excepion = " + e.getMessage());
        }
    }

    private void handleProhibitPlay(String jsonData) {
        JSONObject json;
        try {
            json = new JSONObject(jsonData);
            mPlayId = json.optString("id");
            String appType = json.optString("appType");
            DebugLog.d(TAG, "handleProhibitPlay() enter, mPlayId=" + mPlayId + ", appType=" + appType);
            if (appType.equals("probing")) {
                notifyProbingCompleted(false);

            } else {
                String result = "{\"code\": \"" + Constants.RESPONSE_500
                        + "\",\"message\": \"Only allow to play game under LTE or WIFI.\"}";
                ubiGCPlayerCallback("play", result);

                notifyClosePlayerWebJS();
                callJsUpdateStatus(Constants.RESPONSE_302);
            }
            WebBrowser.sGameExitStatus = Constants.GAMEACTIVITY_ALERT_DIALOG_TYPE_NOT_LTEWIFI;
            DebugLog.d(TAG, "====prohibit play in 3G network=====");
            Utils.ShowOKPrompt(mContext, GameActivityRes.STRING_WARNING, GameActivityRes.STRING_PROHIBITPLAY,
                    new DialogInterface.OnClickListener() {
                        @Override
                        public void onClick(DialogInterface dialog, int which) {
                            dialog.dismiss();
                        }
                    });
        } catch (JSONException e) {
            // TODO Auto-generated catch block
            DebugLog.d(TAG, "excepion = " + e.getMessage());
        }

    }

    private void handlePoorProbingResult(String jsonData) {
        JSONObject json;
        try {
            json = new JSONObject(jsonData);
            mPlayId = json.optString("id");
            String appType = json.optString("appType");
            DebugLog.d(TAG, "handlePoorProbingResult() enter, mPlayId=" + mPlayId + ", appType=" + appType);

            String result = "{\"code\": \"" + Constants.RESPONSE_500
                    + "\",\"message\": \"Probing result is too low to play game fluently.\"}";
            ubiGCPlayerCallback("play", result);
            notifyClosePlayerWebJS();
            callJsUpdateStatus(Constants.RESPONSE_302);

            DebugLog.d(TAG, "handlePoorProbingResult() probing is too low");
            Utils.ShowOKPrompt(mContext, GameActivityRes.STRING_WARNING, GameActivityRes.STRING_POORBITRATE,
                    new DialogInterface.OnClickListener() {
                        @Override
                        public void onClick(DialogInterface dialog, int which) {
                            dialog.dismiss();
                            WebBrowser.sGameExitStatus = Constants.GAMEACTIVITY_ALERT_DIALOG_TYPE_POOR_PROBINGRESULT;
                        }
                    });
        } catch (JSONException e) {
            // TODO Auto-generated catch block
            DebugLog.d(TAG, "excepion = " + e.getMessage());
        }
    }

    /**
     * release the webview url
     */
    public void reload(String reloadUrl) {
        if (!sBCurrentActivityStatus) {
            return;
        }
        DebugLog.d(TAG, "0829 reload() enter");
        int size = mChildViewList.size();
        if (size > 1) {
            for (int i = 0; i < (size - 1); i++) {
                WebView child = (WebView) mChildViewList.get(i).findViewById(GameActivityRes.ID_CHILD_WEBVIEW);
                if (child.getTag() != null) {
                    child.loadUrl(child.getTag().toString());
                    child.setTag(null);
                } else {
                    child.reload();
                }
            }
        }
        //      String reloadUrl = Utils.checkUrl(GameInfo.DEFAULT_URL);
        mWebView.loadUrl(reloadUrl);
    }

    //return signature string
    public String ubiGCPlayerDigestMessage(String message) {
        String resultSignature = "";
        try {
            byte[] sha1Bytes = Utils.SHA1(message);
            //DebugLog.d(TAG, "ubiGCPlayerDigestMessage() sha1Str = " + sha1Str);
            //DebugLog.d(TAG, "ubiGCPlayerDigestMessage() sha1Bytes = " + Arrays.toString(sha1Bytes));

            byte[] rsaEncryptedBytes = Utils.rsaEncrypt(Constants.sModulusStr, Constants.sPublicExponentStr,
                    sha1Bytes);
            DebugLog.d(TAG, "ubiGCPlayerDigestMessage() rsaEncryptedBytes = " + Arrays.toString(rsaEncryptedBytes));
            resultSignature = Base64.encodeToString(rsaEncryptedBytes, Base64.NO_WRAP);
        } catch (NoSuchAlgorithmException e) {
            // TODO Auto-generated catch block
            DebugLog.d(TAG, "excepion = " + e.getMessage());
            return "";
        } catch (UnsupportedEncodingException e) {
            // TODO Auto-generated catch block
            DebugLog.d(TAG, "excepion = " + e.getMessage());
            return "";
        }
        return resultSignature;
    }

    /**
     * WebServer->client
     * BillingActivity purchase process
     * webServer send skuArray to client
     * client will get all license result by skuArray and put the license result to local list
     * and notify WebServer,and then the WebServer will invoke the ubiGCPlayerGetLicense(sku) next time.
     * @param jsonData
     * @return
     */
    private String checkInApp(String jsonData) {
        String result = null;
        DebugLog.d(TAG, "0829 checkInApp() jsonData= " + jsonData);
        try {
            BillingActivity.mSkuJsonData = jsonData;

            new Thread(new Runnable() {

                public void run() {
                    // TODO Auto-generated method stub
                    //BillingActivity.checkInAppLicense(Constants.BILLING_KEYWORD, BillingActivity.mSku, mContext);
                    BillingActivity.handleCheckSkuArray(BillingActivity.mSkuJsonData, mContext);
                    String result = "{" + "\"id\": \"" + BillingActivity.mStrId + "\"," + "\"type\": \"result\","
                            + "\"code\": \"" + Constants.RESPONSE_200 + "\"," + "\"message\": \"success\"" + "}";

                    //web server will invoke the ubiGCPlayerGetLicense(sku)  after response the checkInappLicense result
                    CloudGamePlayer.sWebBrowser.ubiGCPlayerCallback("checkInApp", result);
                }
            }).start();
            return "";
        } catch (Exception e) {
            // TODO Auto-generated catch block
            DebugLog.d(TAG, "excepion = " + e.getMessage());
            result = "{" + "\"code\": \"" + Constants.RESPONSE_500
                    + "\",\"message\": \" player internal error(500) \"}";
        }

        this.ubiGCPlayerCallback("checkInApp", result);

        return "";
    }

    /**
     * WebServer -> client
     * BillingActivity
     * Will invoke this method after invoke checkInApp(String jsonData)
     * @param sku
     * @return
     */
    public String ubiGCPlayerGetLicense(String sku) {
        String result;
        if (null == sku || null == mCheckLicenseMap) {
            return "";
        }

        result = mCheckLicenseMap.get(sku);
        DebugLog.d(TAG, "0829 ubiGCPlayerGetLicense() sku= " + sku + ",result=" + result);
        if (result == null || result.equals("")) {
            return "";
        }

        return result;
    }

    /**
     * client -> client
     * BillingActivity
     * save all licenses in local HaspMap after do BillingActivity->checkInAppLicense()
     * @param sku
     * @param license
     */
    public void notifyCheckLicenseResult(String sku, String license) {
        DebugLog.d(TAG, "0829 notifyCheckLicenseResult() sku= " + sku + ",license=" + license);
        String request;

        if (sku != null && license != null) {

            byte[] licenseBytes = license.getBytes();
            String base64license = Base64.encodeToString(licenseBytes, Base64.DEFAULT);
            DebugLog.d(TAG, "0829 notifyCheckLicenseResult() sku= " + sku + ",base64license=" + base64license);
            mCheckLicenseMap.put(sku, base64license);
        }
    }

    /**
     * WebSever->client
     * will clear application data folder
     * @param jsonData
     * @return
     */
    private String clearUserCookies(String jsonData) {
        DebugLog.d(TAG, "0829 clearUserCookies() enter");
        ((LoadWebJsActivity) mContext).clearApplicationData(mContext);
        return "";
    }

    public void openNativeWindow(final String url) {
        ((Activity) this.mContext).runOnUiThread(new Runnable() {
            @Override
            public void run() {
                // TODO Auto-generated method stub
                Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(url));
                mWebviewActivity.startActivity(intent);
            }
        });
    }

    /**
     * be invoked by webServer JS
     * Example:
       main ?????????ayer.ubiGCPlayerCommunicate("subwin", ...)
       webview ????????????????????????????????????????ubwin"
       ?????bview ??????????????????oke openWindow ???????????????????owName:"subwin" ?????????????      ????????????????????????in ?????????????????biGCPlayerDelegate; ?????????????main", 
       ??????????????CPlayerDelegate("main",....);
     * @param target
     * @param jsonData
     */
    public void ubiGCPlayerCommunicate(String target, String jsonData) {
        DebugLog.i(TAG, "===comm ubiGCPlayerCommunicate  target = " + target);
        DebugLog.d(TAG, "===comm jsonData = " + jsonData);
        if (checkIsCommWinName(target)) {
            DebugLog.i(TAG, "===comm ubiGCPlayerDelegate source target = " + MULTI_TAB_WIN_MAIN);
            ubiGCPlayerDelegate(target, MULTI_TAB_WIN_MAIN, jsonData);//parent win delegate
        }
    }

    /**
     * check is belong to communication window
     * client definition only
     * local method
     * @param target
     * @return
     */
    public boolean checkIsCommWinName(final String target) {
        if (target != null && !"".equals(target)) {
            if (mLstOpenWin != null) {
                int lstOpenwinSize = mLstOpenWin.size();
                if (lstOpenwinSize > 0) {
                    for (int i = 0; i < lstOpenwinSize; i++) {
                        String windowName = mLstOpenWin.get(i);
                        if (target.equalsIgnoreCase(MULTI_TAB_WIN_MAIN)
                                || (windowName != null && windowName.equals(target))) {
                            return true;
                        }
                    }
                }
            }
        }
        return false;
    }

    /**
     * get source target name in sub window
     * client definition only
     * local method
     * @return
     */
    public String getSourceTargetInSubWin() {
        if (mLstOpenWin != null && mLstOpenWin.size() > 0) {
            int lstOpenwinSize = mLstOpenWin.size();
            //   DebugLog.i(TAG, "comm before removeListOpenTabName size = "+lstOpenwinSize);
            String currentSubWinName = mLstOpenWin.get(lstOpenwinSize - 1);
            //   DebugLog.i(TAG, "getSourceTargetBySubWin = "+currentSubWinName);
            return currentSubWinName;
        }
        return null;
    }

    /**
     * after received the JS's openWin and communicate message
     * Will convert message to target window with source reference 
     * And will delegate communication message in local
     * Local method for C->JS
     * @param target original target value in invoke the method ubiGCPlayerCommunicate.
     * @param source come from the source target win,is used by the source parameter in invoking javascript:ubiGCPlayerDelegate..
     * @param jsonData
     */
    public void ubiGCPlayerDelegate(final String target, String source, final String jsonData) {
        final String strUrl = "javascript:ubiGCPlayerDelegate('" + source + "','" + jsonData + "')";
        ((Activity) this.mContext).runOnUiThread(new Runnable() {
            @Override
            public void run() {
                if (target.equalsIgnoreCase(MULTI_TAB_WIN_MAIN)) {//if come from main win,it will using  main webview object
                    mWebView.loadUrl(strUrl);
                } else {//else if come from sub win ,it will find the current sub win obj in loop list and using it.
                    if (mChildWebviewLst != null && mChildWebviewLst.size() > 0) {
                        WebView subWebviewObj = mChildWebviewLst.get(0);
                        if (subWebviewObj != null) {
                            subWebviewObj.loadUrl(strUrl);
                        }
                    }
                }
            }
        });
    }

    /**
     * Local method
     * For keep the new win name in List
     * @param windowName
     */
    private void putListOpenTabName(final String windowName) {
        if (windowName != null && !"".equals(windowName)) {
            if (mLstOpenWin == null) {
                mLstOpenWin = new ArrayList<String>();
                DebugLog.i(TAG, "comm init mLstOpenWin object ");
            }
            DebugLog.i(TAG, "comm before putOpenTabName listOpenwinName size = " + mLstOpenWin.size());
            mLstOpenWin.add(windowName);
            DebugLog.i(TAG, "comm after putOpenTabName listOpenwinName size = " + mLstOpenWin.size());
        }
    }

    /**
     * local method
     * For remove the win name in List
     */
    private void removeListOpenTabName() {
        if (mLstOpenWin != null && mLstOpenWin.size() > 0) {
            int lstOpenwinSize = mLstOpenWin.size();
            DebugLog.i(TAG, "comm before removeListOpenTabName size = " + lstOpenwinSize);
            mLstOpenWin.remove(lstOpenwinSize - 1);
            DebugLog.i(TAG, "comm after removeListOpenTabName size = " + mLstOpenWin.size());

        }
    }

    public void JSgoBack() {
        // TODO Auto-generated method stub
        DebugLog.d(TAG, "JSgoBack() mWebView.getUrl() = " + mWebView.getUrl());
        if (mWebView.getUrl() != null) {
            if (GameInfo.isErrorUrl(mWebView.getUrl())) {
                Bundle bundle = new Bundle();
                bundle.putInt("msgtype", Constants.HANDLER_UI_NOTIFY_EXIT_APP_SERVEER);
                bundle.putString("msgcontent", "Notify Exit Application");

                Intent intent = new Intent(Constants.RECEIVER_BROADCAST);
                intent.putExtras(bundle);

                if (mContext != null)
                    mContext.sendBroadcast(intent);
            } else {
                DebugLog.d(TAG, "JSgoBack() javascript:history.back()");
                mWebView.loadUrl("javascript:history.back();");
            }
        }
    }

    public void goBack(String jsonData) {
        try {
            JSONObject json = new JSONObject(jsonData);
            String id = json.optString("id");
            String type = json.optString("type");
            String code = json.optString("code");
            if (code.compareTo("200") == 0) {
                DebugLog.e(TAG, " goback ok");
            } else {
                DebugLog.e(TAG, " goback no");
            }

        } catch (Exception e) {
            // TODO Auto-generated catch block
            DebugLog.d(TAG, "exception = " + e.getMessage());
        }
    }

    private void exitApp(String jsonData) {
        String result = null;
        try {
            JSONObject json = new JSONObject(jsonData);
            String id = json.optString("id");
            String type = json.optString("type");

            Bundle bundle = new Bundle();
            bundle.putInt("msgtype", Constants.HANDLER_UI_NOTIFY_EXIT_APP_SERVEER);
            bundle.putString("msgcontent", "Notify Exit Application");

            Intent intent = new Intent(Constants.RECEIVER_BROADCAST);
            intent.putExtras(bundle);

            if (mContext != null)
                mContext.sendBroadcast(intent);
            else
                DebugLog.d(TAG, "mContext == null");

            result = "{" + "\"id\": \"" + id + "\"," + "\"type\": \"result\"," + "\"code\": \"200\","
                    + "\"message\": \"success(200)\"" + "}";
        } catch (Exception e) {
            // TODO Auto-generated catch block
            DebugLog.d(TAG, "exception = " + e.getMessage());
            result = "{" + "\"code\": \"" + Constants.RESPONSE_500
                    + "\",\"message\": \" player internal error(500) \"}";
        }

        this.ubiGCPlayerCallback("exitApp", result);
    }

    private void launchNativeUI(final String jsonData) {
        String id = null;
        String uiName = null;
        String result = null;
        try {
            JSONObject json = new JSONObject(jsonData);
            id = json.optString("id");
            uiName = json.optString("uiName");
        } catch (Exception e) {
            DebugLog.d(TAG, "exception = " + e.getMessage());
            result = "{" + "\"code\": \"" + Constants.RESPONSE_500
                    + "\",\"message\": \" player internal error(500) \"}";
        }

        if ("datepicker".equals(uiName)) {
            final Calendar myCalendar = Calendar.getInstance();
            DatePickerDialog.OnDateSetListener dateSetListener = new DatePickerDialog.OnDateSetListener() {
                @Override
                public void onDateSet(DatePicker view, int year, int monthOfYear, int dayOfMonth) {
                    myCalendar.set(Calendar.YEAR, year);
                    myCalendar.set(Calendar.MONTH, monthOfYear);
                    myCalendar.set(Calendar.DAY_OF_MONTH, dayOfMonth);
                    String myFormat = "dd-MM-yyyy"; //In which you need put here
                    SimpleDateFormat sdf = new SimpleDateFormat(myFormat, Locale.US);
                    String date = sdf.format(myCalendar.getTime());
                    String result = "{\"id\": \"" + System.currentTimeMillis()
                            + "\", \"type\":\"set\", \"uiName\" : \"datepicker\", \"data\" : \"" + date + "\" }";
                    ubiGCPlayerCallback("returnNativeUI", result);
                }
            };
            new DatePickerDialog(mContext, dateSetListener, myCalendar.get(Calendar.YEAR),
                    myCalendar.get(Calendar.MONTH), myCalendar.get(Calendar.DAY_OF_MONTH)).show();

            result = "{" + "\"id\": \"" + id + "\"," + "\"type\": \"result\"," + "\"code\": \"200\","
                    + "\"message\": \"success(200)\"" + "}";
        } else {
            result = "{" + "\"code\": \"" + Constants.RESPONSE_500
                    + "\",\"message\": \" player internal error(500) \"}";
        }
        ubiGCPlayerCallback("launchNativeUI", result);
    }

    public void setOnToolBarListener(ToolbarListener toolbarListener) {
        mToolbarListener = toolbarListener;
    }

    private void enableToolbar(final String jsonData) {
        if (mToolbarListener != null) {
            ((Activity) mContext).runOnUiThread(new Runnable() {

                @Override
                public void run() {
                    mToolbarListener.enableToolbar(jsonData);
                }

            });

        }
    }

    private void disableToolbar(final String jsonData) {
        if (mToolbarListener != null) {
            ((Activity) mContext).runOnUiThread(new Runnable() {

                @Override
                public void run() {
                    mToolbarListener.disableToolbar(jsonData);
                }
            });
        }
    }

    private void updateUserProfile(final String jsonData) {
        if (mToolbarListener != null) {
            ((Activity) mContext).runOnUiThread(new Runnable() {
                @Override
                public void run() {
                    mToolbarListener.updateUserProfile(jsonData);
                }
            });

        }
    }

    private void notifyURLRoute(final String jsonData) {
        if (mToolbarListener != null) {
            mToolbarListener.notifyURLRoute(jsonData);
        }
    }

    private void notifyUserLogined(final String jsonData) {
        if (mToolbarListener != null) {
            mToolbarListener.notifyUserLogined(jsonData);
        }
    }

    public static interface ToolbarListener {
        public void enableToolbar(String jsonData);

        public void disableToolbar(String jsonData);

        public void updateUserProfile(String jsonData);

        public void announceMessage(String jsonData) throws Exception;

        public void notifyURLRoute(String jsonData);

        public void notifyUserLogined(String jsonData);

        public boolean isEnable();
    }

    public void startFacebookDialog(final String jsonData) {

        DebugLog.d(TAG, "startFacebookDialog() Do nothing, you need to new a instance of WebFaceBook");
        String result = "{" + "\"code\": \"" + Constants.RESPONSE_500
                + "\",\"message\": \" facebookDialog error(500) \"}";
        ubiGCPlayerCallback("facebookDialog", result);

    }

    private String openConfigurationPage(String jsonData) {
        String result = null;
        try {
            JSONObject json = new JSONObject(jsonData);
            String id = json.optString("id");
            result = "{" + "\"id\": \"" + id + "\"," + "\"type\": \"result\"," + "\"code\": \""
                    + Constants.RESPONSE_200 + "\"," + "\"message\": \"success\"" + "}";
            Utils.showNetworkCfgDialog(mWebviewActivity, null);
        } catch (Exception e) {
            // TODO Auto-generated catch block
            DebugLog.d(TAG, "excepion = " + e.getMessage());
            result = "{" + "\"code\": \"" + Constants.RESPONSE_500
                    + "\",\"message\": \" player internal error(500) \"}";
        }

        this.ubiGCPlayerCallback("openConfigurationPage", result);

        return result;
    }

    private void readStoredAcceptUseLteCfgStatus() {
        SharedPreferences gcWebPreference = PreferenceManager.openPrference(mContext,
                Constants.REMEMBER_PREFERENCE_DB);
        String ltecfg = PreferenceManager.getParamsValue(gcWebPreference, Constants.REMEMEBER_ACCEPT_USE_LTE);
        if (ltecfg == null || ltecfg.equals("") || ltecfg.equals("false")) {
            Constants.sIsAcceptLteUsage = false;
        }
        if (ltecfg != null && ltecfg.equals("true")) {
            Constants.sIsAcceptLteUsage = true;
        }
    }

    public void googlePurchase(final String jsonData) {

        DebugLog.d(TAG, "googlePurchase()");
        ((Activity) mContext).runOnUiThread(new Runnable() {

            @Override
            public void run() {
                // TODO Auto-generated method stub
                String result = null;
                Intent intent = new Intent();

                intent.setClass(mContext, GoogleBillingActivity.class);
                //intent.setClass(mContext, VzwSdkIntegrationApp.class);
                intent.putExtra("jsonData", jsonData);
                sIsBillingTriggered = true;//disable timeout single
                mWebviewActivity.startActivityForResult(intent, Constants.START_BILLINGACTIVITY_REQUEST_CODE);
            }

        });
    }

    //http://wiki.ubitus.net/pages/viewpage.action?pageId=33362966
    private void paypalPayment(String jsonData) {
        mPayPal.paypalPayment(jsonData);
    }

    private void paypalPaymentDone(String jsonData) {
        mPayPal.paypalPaymentDone(jsonData);
    }

    public void onCreate(Bundle savedInstanceState) {

    }

    public void onStart() {

    }

    public void onStop() {

    }

    public void onSaveInstanceState(Bundle outState) {

    }

    public void onActivityResult(int requestCode, int resultCode, Intent data) {
        mPayPal.onActivityResult(requestCode, resultCode, data);
    }

    /**
     *  JSON Data Example
     *  {
     *       "id": "6ba7b810-9dad-11d1-80b4-00c04fd430c8",
     *      "type": "set",
     *      "downloadList": [
     *         {"id": "file01",
     *          "url": "http://dqxstage.ugamenow.com/dqx/detection/2M.dat",
     *          "badBoundTime": "1111"
     *         },
     *         {"id": "file02",
     *          "url": "http://dqxstage.ugamenow.com/dqx/detection/4M.dat",
     *          "badBoundTime": "2222"
     *         },
     *         {"id": "file03",
     *          "url": "http://dqxstage.ugamenow.com/dqx/detection/8M.dat",
     *          "badBoundTime": "4444"
     *         }
     *      ]
     *  }
     */
    private void detectHttpBandwidth(final String jsonData) {
        DebugLog.d(TAG, "detectHttpBandwidth() enter");
        new Thread(new Runnable() {
            public void run() {
                JSONObject json;
                String id = null;
                String type = null;
                String resJson = null;
                int result = -2;
                int lastIndex = -1;
                //download time results for {file01 (2M), file02 (4M), file03 (8M)}
                String[] fileIdList = null;
                int[] downloadTimeList = null;
                try {
                    do {
                        json = new JSONObject(jsonData);
                        id = json.optString("id");
                        type = json.optString("type");
                        JSONArray downloadList = json.getJSONArray("downloadList");
                        int len = downloadList.length();
                        fileIdList = new String[len];
                        downloadTimeList = new int[len];
                        for (int index = 0; index < len; index++) {
                            JSONObject downloadInfo = downloadList.getJSONObject(index);
                            String fid = downloadInfo.getString("id");
                            String url = downloadInfo.getString("url");
                            int badBoundTime = downloadInfo.getInt("badBoundTime");
                            DebugLog.d(TAG, "detectHttpBandwidth() fid: " + fid + ", url: " + url
                                    + ", badBoundTime: " + badBoundTime);
                            fileIdList[index] = fid;
                            downloadTimeList[index] = -1;
                            int downloadTime = Utils.detectFileDownloadTime(url);
                            if (downloadTime > 0) {
                                lastIndex = index;
                                downloadTimeList[index] = downloadTime;
                                if (downloadTime > badBoundTime) {
                                    //network is not good enough to meet criteria, stop download remained file
                                    result = -1;
                                    break;
                                }
                                if (index == len - 1) {
                                    result = 0;
                                }
                            } else {
                                //error occurred during connecting to download server
                                result = -2;
                                break;
                            }
                        }
                    } while (false);
                } catch (JSONException e) {
                    DebugLog.d(TAG, "detectHttpBandwidth excepion = " + e.getMessage());
                    result = -2;
                }

                switch (result) {
                case 0: //network is good
                    resJson = "{" + "\"id\": \"" + id + "\"," + "\"type\": \"result\"," + "\"code\": \""
                            + Constants.RESPONSE_200 + "\"," + "\"message\": \"success\"," + "\"downloadResult\": ["
                            + "{\"id\": \"" + fileIdList[0] + "\"," + "\"downloadTime\": \"" + downloadTimeList[0]
                            + "\"}," + "{\"id\": \"" + fileIdList[1] + "\"," + "\"downloadTime\": \""
                            + downloadTimeList[1] + "\"}," + "{\"id\": \"" + fileIdList[2] + "\","
                            + "\"downloadTime\": \"" + downloadTimeList[2] + "\"}]" + "}";
                    break;
                case -1: //network is not good enough to meet criteria
                    StringBuffer resJsonStrBuf = new StringBuffer("{" + "\"id\": \"" + id + "\","
                            + "\"type\": \"result\"," + "\"code\": \"" + Constants.RESPONSE_531 + "\","
                            + "\"message\": \"detect Http bandwidth failed\"," + "\"downloadResult\": [");
                    for (int i = 0; i < lastIndex + 1; i++) {
                        resJsonStrBuf.append("{\"id\": \"").append(fileIdList[i]).append("\",\"downloadTime\": \"")
                                .append(downloadTimeList[i]).append("\"}");
                        if (i != lastIndex) {
                            resJsonStrBuf.append(",");
                        }
                    }
                    resJsonStrBuf.append("]}");
                    resJson = resJsonStrBuf.toString();
                    break;
                case -2: //error occurred while communicating with server
                    resJson = "{" + "\"id\": \"" + id + "\"," + "\"type\": \"result\"," + "\"code\": \""
                            + Constants.RESPONSE_532 + "\"," + "\"message\": \"downloaded file is not exist\""
                            + "}";
                    break;
                }

                CloudGamePlayer.sWebBrowser.ubiGCPlayerCallback("detectHttpBandwidth", resJson);
            }
        }).start();
    }

    public int getBillingStatus() {
        return mBillingStatus;
    }

    public void setBillingStatus(int status) {
        synchronized (this) {
            mBillingStatus = status;
        }
    }
}