com.mobicage.rogerthat.registration.AbstractRegistrationActivity.java Source code

Java tutorial

Introduction

Here is the source code for com.mobicage.rogerthat.registration.AbstractRegistrationActivity.java

Source

/*
 * Copyright 2018 GIG Technology NV
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 * @@license_version:1.4@@
 */
package com.mobicage.rogerthat.registration;

import android.app.Activity;
import android.app.ProgressDialog;
import android.content.Context;
import android.content.Intent;
import android.os.Handler;
import android.os.HandlerThread;
import android.os.Looper;
import android.telephony.TelephonyManager;

import com.mobicage.rogerth.at.R;
import com.mobicage.rogerthat.MainActivity;
import com.mobicage.rogerthat.MainService;
import com.mobicage.rogerthat.ServiceBoundActivity;
import com.mobicage.rogerthat.config.Configuration;
import com.mobicage.rogerthat.config.ConfigurationProvider;
import com.mobicage.rogerthat.plugins.system.MobileInfo;
import com.mobicage.rogerthat.plugins.system.SystemPlugin;
import com.mobicage.rogerthat.util.GoogleServicesUtils;
import com.mobicage.rogerthat.util.http.HTTPUtil;
import com.mobicage.rogerthat.util.logging.L;
import com.mobicage.rogerthat.util.security.SecurityUtils;
import com.mobicage.rogerthat.util.system.SafeAsyncTask;
import com.mobicage.rogerthat.util.system.SafeRunnable;
import com.mobicage.rogerthat.util.system.T;
import com.mobicage.rogerthat.util.ui.Pausable;
import com.mobicage.rogerthat.util.ui.UIUtils;
import com.mobicage.rpc.Credentials;
import com.mobicage.rpc.config.AppConstants;
import com.mobicage.rpc.config.CloudConstants;
import com.mobicage.rpc.newxmpp.XMPPConfigurationFactory;

import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.HttpStatus;
import org.apache.http.NameValuePair;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.protocol.HTTP;
import org.jivesoftware.smack.ConnectionConfiguration;
import org.jivesoftware.smack.Logger;
import org.jivesoftware.smack.XMPPConnection;
import org.json.simple.JSONObject;
import org.json.simple.JSONValue;

import java.io.IOException;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import javax.net.ssl.SSLException;

public abstract class AbstractRegistrationActivity extends ServiceBoundActivity {

    public final static String INTENT_LOG_URL = "com.mobicage.rogerthat.registration.log_url";

    public static final int HTTP_RETRY_COUNT = 3;
    public static final int HTTP_TIMEOUT = 10000;

    public static final int XMPP_CHECK_DELAY_MILLIS = 5000;
    public static final int XMPP_MAX_NUM_ATTEMPTS = 8;

    public static final String INVITOR_CODE_CONFIGKEY = "invitor_code";
    public static final String INVITOR_SECRET_CONFIGKEY = "invitor_secret";

    private Activity mActivity;
    private AbstractRegistrationWizard mWizard;

    private Handler mUIHandler;

    private HandlerThread mWorkerThread;
    private Looper mWorkerLooper;
    private Handler mWorkerHandler;

    private String mGCMRegistrationId = "";
    private boolean mAgeAndGenderSet = true;

    public void init(Activity activity) {
        T.UI();
        mActivity = activity;
        mUIHandler = new Handler();
        T.setUIThread("RegistrationProcedureActivity.UI");

        mWorkerThread = new HandlerThread("rogerthat_registration_worker");
        mWorkerThread.start();
        mWorkerLooper = mWorkerThread.getLooper();
        mWorkerHandler = new Handler(mWorkerLooper);
        mWorkerHandler.post(new SafeRunnable() {
            @Override
            public void safeRun() {
                T.setRegistrationThread("RegistrationProcedureActivity.WORKER");
            }
        });

        startRegistrationService();
    }

    public void closeWorkerThread() {
        T.UI();
        final Looper looper = mWorkerHandler.getLooper();
        if (looper != null)
            looper.quit();

        try {
            mWorkerThread.join();
        } catch (InterruptedException e) {
            L.bug(e);
        }

        mWorkerHandler = null;
        mWorkerThread = null;
        T.resetRegistrationThreadId();
    }

    public void runOnWorker(Runnable runnable) {
        mWorkerHandler.post(runnable);
    }

    public void runDelayedOnWorker(Runnable runnable, int delayMillis) {
        mWorkerHandler.postDelayed(runnable, delayMillis);
    }

    public void runOnUI(Runnable runnable) {
        mUIHandler.post(runnable);
    }

    public void runDelayedOnUI(Runnable runnable, int delayMillis) {
        mUIHandler.postDelayed(runnable, delayMillis);
    }

    public String getMobileInfo() {
        T.REGISTRATION();
        MobileInfo info = SystemPlugin.gatherMobileInfo(mService);
        String json = JSONValue.toJSONString(info.toJSONMap());
        return json;
    }

    private void startRegistrationService() {
        startService(new Intent(this, RegistrationService.class));
    }

    private void stopRegistrationService() {
        stopService(new Intent(this, RegistrationService.class));
    }

    public void startMainActivity(boolean directly) {
        if (!directly && AppConstants.PROFILE_SHOW_GENDER_AND_BIRTHDATE && !getAgeAndGenderSet()) {
            Intent intent = new Intent(mActivity, MainActivity.class);
            intent.setAction(MainActivity.ACTION_COMPLETE_PROFILE);
            intent.setFlags(MainActivity.FLAG_CLEAR_STACK_SINGLE_TOP);
            startActivity(intent);
        } else {
            Intent intent = new Intent(mActivity, MainActivity.class);
            intent.setAction(MainActivity.ACTION_REGISTERED);
            startActivity(intent);
        }

        mActivity.finish();
    }

    public void tryConnect(final ProgressDialog pd, final int attempt, final String statusMessage,
            final RegistrationInfo info) {
        T.UI();
        final Pausable pausable = this;

        if (attempt > XMPP_MAX_NUM_ATTEMPTS) {
            pd.dismiss();
            String message = getString(R.string.registration_error);
            UIUtils.showDialog(mActivity, null, message, getString(R.string.try_again), null, null, null);
            mWizard.reInit();
            mWizard.goBackToPrevious();
            return;
        }
        pd.setMessage(statusMessage + attempt);
        if (!pd.isShowing())
            pd.show();
        L.d("Registration attempt #" + attempt);

        final String xmppServiceName = info.mCredentials.getXmppServiceName();
        final String xmppAccount = info.mCredentials.getXmppAccount();
        final String xmppPassword = info.mCredentials.getPassword();

        final ConfigurationProvider cp = mService.getConfigurationProvider();
        Configuration cfg = cp.getConfiguration(RegistrationWizard2.CONFIGKEY);
        final String invitorCode = (cfg == null) ? null : cfg.get(INVITOR_CODE_CONFIGKEY, null);
        final String invitorSecret = (cfg == null) ? null : cfg.get(INVITOR_SECRET_CONFIGKEY, null);

        Runnable runnable = new SafeRunnable() {

            @Override
            public void safeRun() {
                T.REGISTRATION();
                try {

                    if (CloudConstants.USE_XMPP_KICK_CHANNEL) {

                        final ConnectionConfiguration xmppConfig = new XMPPConfigurationFactory(cp,
                                mService.getNetworkConnectivityManager(), null)
                                        .getSafeXmppConnectionConfiguration(xmppServiceName);
                        final XMPPConnection xmppCon = new XMPPConnection(xmppConfig);

                        xmppCon.setLogger(new Logger() {
                            @Override
                            public void log(String message) {
                                L.d(message);
                            }
                        });
                        xmppCon.connect();
                        xmppCon.login(xmppAccount, xmppPassword);

                        final Thread t2 = new Thread(new SafeRunnable() {
                            @Override
                            protected void safeRun() throws Exception {
                                L.d("REG Before disconnect (on separate thread) - xmpp-" + xmppCon.hashCode());
                                xmppCon.disconnect();
                                L.d("REG After disconnect (on separate thread) - xmpp-" + xmppCon.hashCode());
                            }
                        });
                        t2.setDaemon(true);
                        t2.start();

                    }

                    postFinishRegistration(info.mCredentials.getUsername(), info.mCredentials.getPassword(),
                            invitorCode, invitorSecret);

                    runOnUI(new SafeRunnable(pausable) {

                        @Override
                        protected void safeRun() throws Exception {
                            T.UI();
                            mWizard.setCredentials(info.mCredentials);

                            if (CloudConstants.USE_GCM_KICK_CHANNEL && !"".equals(mGCMRegistrationId)) {
                                GoogleServicesUtils.saveGCMRegistrationId(mService, mGCMRegistrationId);
                            }

                            mService.setCredentials(mWizard.getCredentials());
                            mService.setRegisteredInConfig(true);

                            final Intent launchServiceIntent = new Intent(mActivity, MainService.class);
                            launchServiceIntent.putExtra(MainService.START_INTENT_JUST_REGISTERED, true);
                            launchServiceIntent.putExtra(MainService.START_INTENT_MY_EMAIL, mWizard.getEmail());
                            mActivity.startService(launchServiceIntent);
                            stopRegistrationService();
                            pd.dismiss();

                            mWizard.finish(); // finish
                        }
                    });

                } catch (Exception e) {
                    L.d("Exception while trying to end the registration process", e);
                    runOnUI(new SafeRunnable(pausable) {

                        @Override
                        protected void safeRun() throws Exception {
                            T.UI();
                            tryConnect(pd, attempt + 1, statusMessage, info);
                        }
                    });
                }
            }
        };
        if (attempt == 1) {
            runOnWorker(runnable);
        } else {
            runDelayedOnWorker(runnable, XMPP_CHECK_DELAY_MILLIS);
        }
    }

    public void sendRegistrationStep(final String step) {
        List<NameValuePair> extraParams = new ArrayList<>();
        sendRegistrationStep(step, extraParams);
    }

    public void sendRegistrationUrl(final String url, final int count) {
        List<NameValuePair> extraParams = new ArrayList<>();
        extraParams.add(new BasicNameValuePair("url", url));
        extraParams.add(new BasicNameValuePair("count", count + ""));
        sendRegistrationStep("log_url", extraParams);
    }

    public void sendRegistrationStep(final String step, final List<NameValuePair> extraParams) {
        new SafeAsyncTask<Object, Object, Object>() {

            @Override
            protected Object safeDoInBackground(Object... params) {
                final HttpPost httpPost = HTTPUtil.getHttpPost(mActivity, CloudConstants.REGISTRATION_LOG_STEP_URL);
                List<NameValuePair> formParams = HTTPUtil.getRegistrationFormParams(mActivity);
                formParams.add(new BasicNameValuePair("step", step));
                formParams.add(new BasicNameValuePair("install_id", mWizard.getInstallationId()));
                formParams.addAll(extraParams);

                UrlEncodedFormEntity entity;
                try {
                    entity = new UrlEncodedFormEntity(formParams, HTTP.UTF_8);
                } catch (UnsupportedEncodingException e) {
                    L.bug(e);
                    return false;
                }
                httpPost.setEntity(entity);
                L.d("Sending registration step: " + step);
                HttpResponse response;
                try {
                    response = HTTPUtil.getHttpClient(HTTP_TIMEOUT, HTTP_RETRY_COUNT).execute(httpPost);
                } catch (ClientProtocolException e) {
                    L.bug(e);
                    return false;
                } catch (SSLException e) {
                    L.bug(e);
                    return false;
                } catch (IOException e) {
                    L.e(e);
                    return false;
                }

                if (response.getEntity() != null) {
                    try {
                        response.getEntity().consumeContent();
                    } catch (IOException e) {
                        L.bug(e);
                        return false;
                    }
                }

                L.d("Registration step " + step + " sent");
                final int responseCode = response.getStatusLine().getStatusCode();
                if (responseCode != HttpStatus.SC_OK) {
                    L.bug("HTTP request resulted in status code " + responseCode);
                    return false;
                }

                return true;
            }

            @Override
            protected void safeOnPostExecute(Object result) {
            }

            @Override
            protected void safeOnCancelled(Object result) {
            }

            @Override
            protected void safeOnProgressUpdate(Object... values) {
            }

            @Override
            protected void safeOnPreExecute() {
            }

        }.execute();
    }

    @SuppressWarnings("unchecked")
    private void postFinishRegistration(final String username, final String password, final String invitorCode,
            final String invitorSecret) throws ClientProtocolException, IOException {
        T.REGISTRATION();
        final String mobileInfo = getMobileInfo();
        HttpClient httpClient = HTTPUtil.getHttpClient();
        final HttpPost httpPost = HTTPUtil.getHttpPost(mActivity, CloudConstants.REGISTRATION_FINISH_URL);
        List<NameValuePair> formParams = HTTPUtil.getRegistrationFormParams(mActivity);
        formParams.add(new BasicNameValuePair("mobileInfo", mobileInfo));
        formParams.add(new BasicNameValuePair("account", username));
        formParams.add(new BasicNameValuePair("password", password));

        formParams.add(new BasicNameValuePair("invitor_code", invitorCode));
        formParams.add(new BasicNameValuePair("invitor_secret", invitorSecret));

        httpPost.setEntity(new UrlEncodedFormEntity(formParams, HTTP.UTF_8));
        L.d("before http final post");
        HttpResponse response = httpClient.execute(httpPost);
        L.d("after http final post");
        final int responseCode = response.getStatusLine().getStatusCode();
        if (responseCode != HttpStatus.SC_OK) {
            throw new IOException("HTTP request resulted in status code " + responseCode);
        }

        L.d("finish_registration call sent");
        HttpEntity httpEntity = response.getEntity();
        if (httpEntity == null) {
            throw new IOException("Response of '/unauthenticated/mobi/registration/finish' was null");
        }

        final Map<String, Object> responseMap = (Map<String, Object>) JSONValue
                .parse(new InputStreamReader(httpEntity.getContent()));
        if (responseMap == null) {
            throw new IOException("HTTP request responseMap was null");
        }
    }

    public String getGCMRegistrationId() {
        return mGCMRegistrationId;
    }

    public void setGCMRegistrationId(String GCMRegistrationId) {
        mGCMRegistrationId = GCMRegistrationId;
    }

    public void setWizard(AbstractRegistrationWizard wizard) {
        mWizard = wizard;
    }

    public boolean getAgeAndGenderSet() {
        return mAgeAndGenderSet;
    }

    public void setAgeAndGenderSet(boolean ageAndGenderSet) {
        mAgeAndGenderSet = ageAndGenderSet;
    }

    public void registerDevice() {
        T.UI();
        final HttpClient httpClient = HTTPUtil.getHttpClient();
        final String email = mWizard.getEmail();
        final String tosAge = mWizard.getTOSAge();
        final String pushNotifcationsEnabled = mWizard.getPushNotificationEnabled();
        final String timestamp = "" + mWizard.getTimestamp();
        final String deviceId = mWizard.getDeviceId();
        final String registrationId = mWizard.getRegistrationId();
        // Make call to Rogerthat
        String message = getString(R.string.activating);
        final ProgressDialog progressDialog = UIUtils.showProgressDialog(mActivity, null, message, true, false);
        final SafeRunnable showErrorDialog = new SafeRunnable() {
            @Override
            protected void safeRun() throws Exception {
                T.UI();
                progressDialog.dismiss();
                UIUtils.showErrorPleaseRetryDialog(mActivity);
            }
        };

        runOnWorker(new SafeRunnable() {
            @Override
            protected void safeRun() throws Exception {
                T.REGISTRATION();
                String version = "3";
                String signature = SecurityUtils.sha256(version + " " + email + " " + timestamp + " " + deviceId
                        + " " + registrationId + " " + CloudConstants.REGISTRATION_MAIN_SIGNATURE);

                HttpPost httppost = HTTPUtil.getHttpPost(mActivity,
                        CloudConstants.REGISTRATION_REGISTER_DEVICE_URL);
                try {
                    List<NameValuePair> nameValuePairs = HTTPUtil.getRegistrationFormParams(mActivity);
                    nameValuePairs.add(new BasicNameValuePair("version", version));
                    nameValuePairs.add(new BasicNameValuePair("registration_time", timestamp));
                    nameValuePairs.add(new BasicNameValuePair("device_id", deviceId));
                    nameValuePairs.add(new BasicNameValuePair("registration_id", registrationId));
                    nameValuePairs.add(new BasicNameValuePair("signature", signature));
                    nameValuePairs.add(new BasicNameValuePair("email", email));
                    nameValuePairs.add(new BasicNameValuePair("tos_age", tosAge));
                    nameValuePairs
                            .add(new BasicNameValuePair("push_notifications_enabled", pushNotifcationsEnabled));
                    nameValuePairs.add(new BasicNameValuePair("GCM_registration_id", getGCMRegistrationId()));
                    nameValuePairs.add(new BasicNameValuePair("hardware_model", SystemPlugin.getDeviceModelName()));
                    TelephonyManager telephonyManager = (TelephonyManager) mService
                            .getSystemService(Context.TELEPHONY_SERVICE);
                    if (telephonyManager != null) {
                        nameValuePairs.add(
                                new BasicNameValuePair("sim_carrier_name", telephonyManager.getSimOperatorName()));
                    }

                    httppost.setEntity(new UrlEncodedFormEntity(nameValuePairs));

                    // Execute HTTP Post Request
                    HttpResponse response = httpClient.execute(httppost);

                    int statusCode = response.getStatusLine().getStatusCode();
                    HttpEntity entity = response.getEntity();

                    if (entity == null) {
                        runOnUI(showErrorDialog);
                        return;
                    }

                    @SuppressWarnings("unchecked")
                    final Map<String, Object> responseMap = (Map<String, Object>) JSONValue
                            .parse(new InputStreamReader(entity.getContent()));

                    if (statusCode != 200 || responseMap == null) {
                        if (statusCode == 500 && responseMap != null) {
                            final String errorMessage = (String) responseMap.get("error");
                            if (errorMessage != null) {
                                runOnUI(new SafeRunnable() {
                                    @Override
                                    protected void safeRun() throws Exception {
                                        T.UI();
                                        progressDialog.dismiss();
                                        UIUtils.showDialog(mActivity, null, errorMessage);
                                    }
                                });
                                return;
                            }
                        }
                        runOnUI(showErrorDialog);
                        return;
                    }
                    JSONObject account = (JSONObject) responseMap.get("account");
                    setAgeAndGenderSet((Boolean) responseMap.get("age_and_gender_set"));

                    final RegistrationInfo info = new RegistrationInfo(email,
                            new Credentials((String) account.get("account"), (String) account.get("password")));
                    runOnUI(new SafeRunnable() {
                        @Override
                        protected void safeRun() throws Exception {
                            T.UI();
                            mWizard.setEmail(email);
                            mWizard.save();
                            tryConnect(progressDialog, 1, getString(R.string.registration_establish_connection,
                                    email, getString(R.string.app_name)) + " ", info);
                        }
                    });

                } catch (Exception e) {
                    L.d(e);
                    runOnUI(showErrorDialog);
                }
            }
        });
    }
}