mobisocial.musubi.ui.fragments.EulaFragment.java Source code

Java tutorial

Introduction

Here is the source code for mobisocial.musubi.ui.fragments.EulaFragment.java

Source

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

package mobisocial.musubi.ui.fragments;

import java.io.IOException;
import java.util.HashSet;

import mobisocial.metrics.MusubiMetrics;
import mobisocial.musubi.App;
import mobisocial.musubi.R;

import org.apache.commons.io.IOUtils;

import android.app.Activity;
import android.app.Dialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.DialogInterface.OnKeyListener;
import android.content.Intent;
import android.content.SharedPreferences;
import android.os.AsyncTask;
import android.os.Bundle;
import android.support.v4.app.DialogFragment;
import android.support.v4.app.SupportActivity;
import android.text.Html;
import android.text.util.Linkify;
import android.util.Log;
import android.view.KeyEvent;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.CheckBox;
import android.widget.CompoundButton;
import android.widget.CompoundButton.OnCheckedChangeListener;
import android.widget.LinearLayout;
import android.widget.ScrollView;
import android.widget.TabHost;
import android.widget.TabHost.TabSpec;
import android.widget.TabWidget;
import android.widget.TextView;

public class EulaFragment extends DialogFragment {
    public interface Callback {
        void eulaResult(boolean accepted);
    }

    public static final String TAG = "EulaFragment";

    public static final String PREFS_NAME = "eula";
    public static final String EULA_VERSION_KEY = "version";
    //bump me and update the copy bundled in the assests directory
    public static final int CURRENT_VERSION = 0;

    public static final String EULA_LOCAL_ASSET = "eula.txt";
    public static final String EULA_WEB_URL = "http://mobisocial.stanford.edu/musubi/public/#/eula";
    public static final String PRIVACY_LOCAL_ASSET = "privacypolicy.txt";
    public static final String PRIVACY_WEB_URL = "http://mobisocial.stanford.edu/musubi/public/#/privacy";

    public static final int EULA_WEB_DELAY = 12 * 1000;

    public static final String EULA_MAIL_SUBJECT = "Musubi Usage Agreements";

    private Button mAcceptButton;
    private Button mRejectButton;
    private Button mEmailButton;
    private CheckBox mAcceptedCheckbox;
    private ScrollView mEulaScroll;
    private LinearLayout mLoading;
    private TextView mEulaBodyView;
    private TextView mPrivacyBodyView;
    private LinearLayout mEulaAcceptArea;
    private Button mDismissButton;
    private Activity mActivity;
    private TabHost mTabs;
    private String mEulaTxt;
    private String mPrivacyTxt;
    private boolean mAccepted = false;

    private boolean mRequired;

    public EulaFragment() {
        //in case something weird happens
        //the default is true
        mRequired = true;
    }

    public EulaFragment(boolean required) {
        mRequired = required;
    }

    public static boolean needsEULA(Context context) {
        SharedPreferences prefs = context.getSharedPreferences(EulaFragment.PREFS_NAME, 0);
        int old_version = prefs.getInt(EulaFragment.EULA_VERSION_KEY, -1);
        if (old_version < 0 || old_version < EulaFragment.CURRENT_VERSION) {
            return true;
        }
        return false;
    }

    public static void acceptedEULA(Context context) {
        SharedPreferences prefs = context.getSharedPreferences(EulaFragment.PREFS_NAME, 0);
        prefs.edit().putInt(EulaFragment.EULA_VERSION_KEY, EulaFragment.CURRENT_VERSION).commit();
    }

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
    }

    @Override
    public void onAttach(SupportActivity activity) {
        super.onAttach(activity);
        mActivity = activity.asActivity();
    }

    class AgreementLoader extends AsyncTask<Void, Void, Void> {
        @Override
        protected void onPreExecute() {
            mEulaScroll.setVisibility(View.GONE);
            mLoading.setVisibility(View.VISIBLE);
        }

        @Override
        protected Void doInBackground(Void... params) {
            if (mEulaTxt == null) {
                try {
                    mEulaTxt = IOUtils.toString(mActivity.getResources().getAssets().open(EULA_LOCAL_ASSET));
                } catch (IOException e) {
                    Log.e(TAG, "failed to set text on eula view", e);
                    mEulaTxt = "Visit " + EULA_WEB_URL;
                    Linkify.addLinks(mEulaBodyView, Linkify.ALL);
                }
            }
            if (mPrivacyTxt == null) {
                try {
                    mPrivacyTxt = IOUtils.toString(mActivity.getResources().getAssets().open(PRIVACY_LOCAL_ASSET));
                } catch (IOException e) {
                    Log.e(TAG, "failed to set text on eula view", e);
                    mPrivacyTxt = "Visit " + PRIVACY_WEB_URL;
                    Linkify.addLinks(mPrivacyBodyView, Linkify.ALL);
                }
            }
            return null;
        }

        @Override
        protected void onPostExecute(Void result) {
            mEulaBodyView.setText(mEulaTxt);
            mPrivacyBodyView.setText(mPrivacyTxt);

            mEulaScroll.setVisibility(View.VISIBLE);
            mLoading.setVisibility(View.GONE);
        }
    }

    @Override
    public Dialog onCreateDialog(Bundle savedInstanceState) {
        Dialog dialog = super.onCreateDialog(savedInstanceState);
        dialog.setContentView(R.layout.eula);

        //load the tabs
        mTabs = (TabHost) dialog.findViewById(android.R.id.tabhost);
        mTabs.setup();

        TabSpec tab_one = mTabs.newTabSpec("eula_tab");
        tab_one.setContent(R.id.eula_body);
        tab_one.setIndicator("EULA");
        mTabs.addTab(tab_one);

        TabSpec tab_two = mTabs.newTabSpec("privacy_tab");
        tab_two.setContent(R.id.priv_body);
        tab_two.setIndicator("Privacy Policy");
        mTabs.addTab(tab_two);

        //work around lack of ability to control tab height from xml completely
        TabWidget tab_widget = (TabWidget) dialog.findViewById(android.R.id.tabs);
        mTabs.getTabWidget().getChildAt(0).getLayoutParams().height = tab_widget.getLayoutParams().height;
        mTabs.getTabWidget().getChildAt(1).getLayoutParams().height = tab_widget.getLayoutParams().height;

        //load the agreements
        mEulaScroll = (ScrollView) dialog.findViewById(R.id.eula_scroll);
        mLoading = (LinearLayout) dialog.findViewById(R.id.loading);
        mEulaBodyView = (TextView) dialog.findViewById(R.id.eula_body);
        mPrivacyBodyView = (TextView) dialog.findViewById(R.id.priv_body);

        mAcceptedCheckbox = (CheckBox) dialog.findViewById(R.id.eula_checkbox);
        mAcceptButton = (Button) dialog.findViewById(R.id.eula_accept);
        mRejectButton = (Button) dialog.findViewById(R.id.eula_reject);
        mEmailButton = (Button) dialog.findViewById(R.id.eula_email);
        mDismissButton = (Button) dialog.findViewById(R.id.eula_dismiss);
        mEulaAcceptArea = (LinearLayout) dialog.findViewById(R.id.eula_accept_area);

        mAcceptedCheckbox.setOnCheckedChangeListener(new OnAcceptToggle());
        mAcceptButton.setOnClickListener(new OnAccept());
        mRejectButton.setOnClickListener(new OnReject());
        mEmailButton.setOnClickListener(new OnEmail());
        mDismissButton.setOnClickListener(new OnDismiss());

        if (!mRequired) {
            mEulaAcceptArea.setVisibility(View.GONE);
            mAcceptButton.setVisibility(View.GONE);
            mRejectButton.setVisibility(View.GONE);
            mDismissButton.setVisibility(View.VISIBLE);
        } else {
            mEulaAcceptArea.setVisibility(View.VISIBLE);
            mAcceptButton.setVisibility(View.VISIBLE);
            mRejectButton.setVisibility(View.VISIBLE);
            mDismissButton.setVisibility(View.GONE);
        }

        mAcceptButton.setEnabled(mAcceptedCheckbox.isChecked());
        dialog.setTitle("Musubi Usage Agreements");
        dialog.setOnKeyListener(new OnKey());

        new AgreementLoader().execute();
        return dialog;
    }

    class OnAcceptToggle implements OnCheckedChangeListener {
        @Override
        public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
            mAcceptButton.setEnabled(isChecked);
        }
    }

    class OnAccept implements OnClickListener {
        @Override
        public void onClick(View v) {
            if (!mAcceptedCheckbox.isChecked()) {
                return;
            }
            App.getUsageMetrics(mActivity).report(MusubiMetrics.EULA_ACCEPTED);
            mAccepted = true;
            broadcastResult();
            dismiss();
        }
    }

    class OnReject implements OnClickListener {
        @Override
        public void onClick(View v) {
            App.getUsageMetrics(mActivity).report(MusubiMetrics.EULA_DECLINED);
            broadcastResult();
            dismiss();
        }
    }

    class OnDismiss implements OnClickListener {
        @Override
        public void onClick(View v) {
            dismiss();
        }
    }

    class OnEmail implements OnClickListener {
        @Override
        public void onClick(View v) {
            App.getUsageMetrics(mActivity).report(MusubiMetrics.EULA_EMAIL_REQUESTED);
            Intent intent = new Intent(Intent.ACTION_SEND);
            intent.setType("text/plain");
            intent.putExtra(android.content.Intent.EXTRA_SUBJECT, EULA_MAIL_SUBJECT);
            intent.putExtra(android.content.Intent.EXTRA_TEXT, mEulaTxt + "\n\n\n\n\n" + mPrivacyTxt);
            startActivity(Intent.createChooser(intent, "Send Agreements..."));
        }
    }

    public class OnKey implements OnKeyListener {
        @Override
        public boolean onKey(DialogInterface dialog, int keyCode, KeyEvent event) {
            //disable back
            if (mRequired && keyCode == KeyEvent.KEYCODE_BACK) {
                return true;
            }
            return false;
        }
    }

    //closing one eula should close them all
    private static HashSet<Callback> sCallbacks = new HashSet<Callback>();

    public void addCallback(Callback callback) {
        sCallbacks.add(callback);
    }

    public void broadcastResult() {
        for (Callback c : sCallbacks) {
            c.eulaResult(mAccepted);
        }
        sCallbacks.clear();
    }
}