org.namelessrom.devicecontrol.MainActivity.java Source code

Java tutorial

Introduction

Here is the source code for org.namelessrom.devicecontrol.MainActivity.java

Source

/*
 *  Copyright (C) 2013 - 2014 Alexander "Evisceration" Martinz
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 *
 */
package org.namelessrom.devicecontrol;

import android.app.Activity;
import android.graphics.Color;
import android.os.Build;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentTransaction;
import android.support.v7.app.ActionBar;
import android.support.v7.widget.Toolbar;
import android.text.TextUtils;
import android.view.Menu;
import android.view.View;
import android.widget.AdapterView;
import android.widget.FrameLayout;
import android.widget.LinearLayout;
import android.widget.ListView;
import android.widget.Toast;

import com.balysv.materialmenu.MaterialMenuDrawable;
import com.balysv.materialmenu.extras.toolbar.MaterialMenuIconToolbar;
import com.jeremyfeinstein.slidingmenu.lib.SlidingMenu;
import com.pollfish.constants.Position;
import com.pollfish.main.PollFish;
import com.stericson.roottools.RootTools;

import org.namelessrom.devicecontrol.about.AboutFragment;
import org.namelessrom.devicecontrol.activities.BaseActivity;
import org.namelessrom.devicecontrol.appmanager.AppListFragment;
import org.namelessrom.devicecontrol.configuration.DeviceConfiguration;
import org.namelessrom.devicecontrol.database.DatabaseHandler;
import org.namelessrom.devicecontrol.device.DeviceFeatureFragment;
import org.namelessrom.devicecontrol.device.DeviceInformationFragment;
import org.namelessrom.devicecontrol.device.sub.FastChargeFragment;
import org.namelessrom.devicecontrol.device.sub.SoundControlFragment;
import org.namelessrom.devicecontrol.editor.BuildPropEditorFragment;
import org.namelessrom.devicecontrol.editor.SysctlEditorFragment;
import org.namelessrom.devicecontrol.editor.SysctlFragment;
import org.namelessrom.devicecontrol.flasher.FlasherFragment;
import org.namelessrom.devicecontrol.listeners.OnBackPressedListener;
import org.namelessrom.devicecontrol.tasker.TaskerFragment;
import org.namelessrom.devicecontrol.ui.adapters.MenuListArrayAdapter;
import org.namelessrom.devicecontrol.cpu.CpuSettingsFragment;
import org.namelessrom.devicecontrol.ui.fragments.performance.FilesystemFragment;
import org.namelessrom.devicecontrol.ui.fragments.performance.GpuSettingsFragment;
import org.namelessrom.devicecontrol.ui.fragments.performance.InformationFragment;
import org.namelessrom.devicecontrol.ui.fragments.performance.ThermalFragment;
import org.namelessrom.devicecontrol.ui.fragments.performance.sub.EntropyFragment;
import org.namelessrom.devicecontrol.cpu.GovernorFragment;
import org.namelessrom.devicecontrol.ui.fragments.performance.sub.IoSchedConfigFragment;
import org.namelessrom.devicecontrol.ui.fragments.performance.sub.KsmFragment;
import org.namelessrom.devicecontrol.ui.fragments.performance.sub.UksmFragment;
import org.namelessrom.devicecontrol.ui.fragments.performance.sub.VoltageFragment;
import org.namelessrom.devicecontrol.ui.fragments.preferences.PreferencesFragment;
import org.namelessrom.devicecontrol.ui.fragments.tools.ToolsMoreFragment;
import org.namelessrom.devicecontrol.ui.fragments.tools.WirelessFileManagerFragment;
import org.namelessrom.devicecontrol.utils.AppHelper;
import org.namelessrom.devicecontrol.utils.Utils;
import org.namelessrom.proprietary.Configuration;

import java.io.File;
import java.util.ArrayList;

public class MainActivity extends BaseActivity implements AdapterView.OnItemClickListener, View.OnClickListener {

    //==============================================================================================
    // Fields
    //==============================================================================================
    private static final Object lockObject = new Object();

    private static long mBackPressed;
    private Toast mToast;

    public static SlidingMenu sSlidingMenu;
    public static MaterialMenuIconToolbar sMaterialMenu;

    public static boolean sDisableFragmentAnimations;

    private Fragment mCurrentFragment;

    private int mTitle = R.string.home;
    private int mFragmentTitle = R.string.home;
    private int mSubFragmentTitle = -1;

    private final ArrayList<Integer> mMenuEntries = new ArrayList<>();
    private final ArrayList<Integer> mMenuIcons = new ArrayList<>();

    private void setupMenuLists() {
        // header - device
        mMenuEntries.add(R.string.device);
        mMenuIcons.add(-1);
        // device - information
        mMenuEntries.add(DeviceConstants.ID_DEVICE_INFORMATION);
        mMenuIcons.add(R.drawable.ic_device_info);
        // device - features
        mMenuEntries.add(DeviceConstants.ID_FEATURES);
        mMenuIcons.add(R.drawable.ic_developer_mode);

        // header - performance
        mMenuEntries.add(R.string.performance);
        mMenuIcons.add(-1);
        // performance - information
        mMenuEntries.add(DeviceConstants.ID_PERFORMANCE_INFO);
        mMenuIcons.add(R.drawable.ic_menu_perf_info);
        // performance - cpu
        mMenuEntries.add(DeviceConstants.ID_PERFORMANCE_CPU_SETTINGS);
        mMenuIcons.add(R.drawable.ic_memory);
        // performance - gpu
        mMenuEntries.add(DeviceConstants.ID_PERFORMANCE_GPU_SETTINGS);
        mMenuIcons.add(R.drawable.ic_display);
        // performance - filesystem
        mMenuEntries.add(DeviceConstants.ID_FILESYSTEM);
        mMenuIcons.add(R.drawable.ic_storage);
        // performance - thermal
        if (Utils.fileExists(getString(R.string.directory_msm_thermal))
                || Utils.fileExists(getString(R.string.file_intelli_thermal_base))) {
            mMenuEntries.add(DeviceConstants.ID_THERMAL);
            mMenuIcons.add(R.drawable.ic_heat);
        }

        // header - tools
        mMenuEntries.add(R.string.tools);
        mMenuIcons.add(-1);
        // tools - tasker
        mMenuEntries.add(DeviceConstants.ID_TOOLS_TASKER);
        mMenuIcons.add(R.drawable.ic_extension);
        // tools - flasher
        mMenuEntries.add(DeviceConstants.ID_TOOLS_FLASHER);
        mMenuIcons.add(R.drawable.ic_flash);
        // tools - more
        mMenuEntries.add(DeviceConstants.ID_TOOLS_MORE);
        mMenuIcons.add(R.drawable.ic_widgets);
    }

    //==============================================================================================
    // Overridden Methods
    //==============================================================================================

    @Override
    protected void onResume() {
        super.onResume();
        final String pfApiKey = Configuration.getPollfishApiKeyDc();
        if (!TextUtils.equals("---", pfApiKey) && DeviceConfiguration.get(this).showPollfish) {
            Logger.v(this, "PollFish.init()");
            PollFish.init(this, pfApiKey, Position.BOTTOM_RIGHT, 30);
        }
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        // setup action bar
        final Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);
        toolbar.setNavigationOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if (mSubFragmentTitle == -1) {
                    sSlidingMenu.toggle(true);
                } else {
                    onCustomBackPressed(true);
                }
            }
        });

        // setup material menu icon
        sMaterialMenu = new MaterialMenuIconToolbar(this, Color.WHITE, MaterialMenuDrawable.Stroke.THIN) {
            @Override
            public int getToolbarViewId() {
                return R.id.toolbar;
            }
        };
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
            sMaterialMenu.setNeverDrawTouch(true);
        }

        Utils.setupDirectories();

        final FrameLayout container = (FrameLayout) findViewById(R.id.container);
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
            container.setBackground(null);
        } else {
            //noinspection deprecation
            container.setBackgroundDrawable(null);
        }

        final View v = getLayoutInflater().inflate(R.layout.menu_list, container, false);
        final ListView menuList = (ListView) v.findViewById(R.id.navbarlist);
        final LinearLayout menuContainer = (LinearLayout) v.findViewById(R.id.menu_container);
        // setup our static items
        menuContainer.findViewById(R.id.menu_prefs).setOnClickListener(this);
        menuContainer.findViewById(R.id.menu_about).setOnClickListener(this);

        sSlidingMenu = new SlidingMenu(this);
        sSlidingMenu.setMode(SlidingMenu.LEFT);
        sSlidingMenu.setShadowWidthRes(R.dimen.shadow_width);
        sSlidingMenu.setShadowDrawable(R.drawable.shadow_left);
        sSlidingMenu.setBehindWidthRes(R.dimen.slidingmenu_offset);
        sSlidingMenu.setFadeEnabled(true);
        sSlidingMenu.setFadeDegree(0.45f);
        sSlidingMenu.attachToActivity(this, SlidingMenu.SLIDING_CONTENT);
        sSlidingMenu.setMenu(v);

        // setup touch mode
        MainActivity.setSwipeOnContent(DeviceConfiguration.get(this).swipeOnContent);

        // setup menu list
        setupMenuLists();
        final MenuListArrayAdapter mAdapter = new MenuListArrayAdapter(this, R.layout.menu_main_list_item,
                mMenuEntries, mMenuIcons);
        menuList.setAdapter(mAdapter);
        menuList.setChoiceMode(ListView.CHOICE_MODE_SINGLE);
        menuList.setOnItemClickListener(this);

        loadFragmentPrivate(DeviceConstants.ID_ABOUT, false);
        getSupportFragmentManager().executePendingTransactions();

        Utils.startTaskerService();

        final String downgradePath = getFilesDir() + DeviceConstants.DC_DOWNGRADE;
        if (Utils.fileExists(downgradePath)) {
            if (!new File(downgradePath).delete()) {
                Logger.wtf(this, "Could not delete downgrade indicator file!");
            }
            Toast.makeText(this, R.string.downgraded, Toast.LENGTH_LONG).show();
        }

        if (DeviceConfiguration.get(this).dcFirstStart) {
            DeviceConfiguration.get(this).dcFirstStart = false;
            DeviceConfiguration.get(this).saveConfiguration(this);
        }
    }

    @Override
    public void onClick(final View v) {
        final int id = v.getId();
        switch (id) {
        case R.id.menu_prefs:
            loadFragmentPrivate(DeviceConstants.ID_PREFERENCES, false);
            break;
        case R.id.menu_about:
            loadFragmentPrivate(DeviceConstants.ID_ABOUT, false);
            break;
        }
    }

    @Override
    public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
        loadFragmentPrivate((Integer) adapterView.getItemAtPosition(i), false);
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        restoreActionBar();
        return super.onCreateOptionsMenu(menu);
    }

    @Override
    protected void onPostCreate(final Bundle savedInstanceState) {
        super.onPostCreate(savedInstanceState);
        sMaterialMenu.syncState(savedInstanceState);
    }

    @Override
    protected void onSaveInstanceState(@NonNull final Bundle outState) {
        sMaterialMenu.onSaveInstanceState(outState);
        super.onSaveInstanceState(outState);
    }

    private void onCustomBackPressed(final boolean animatePressed) {
        Logger.v(this, "onCustomBackPressed(%s)", animatePressed);

        // toggle menu if it is showing and return
        if (sSlidingMenu.isMenuShowing()) {
            sSlidingMenu.toggle(true);
            return;
        }

        // if we have a OnBackPressedListener at the fragment, go in
        if (mCurrentFragment instanceof OnBackPressedListener) {
            final OnBackPressedListener listener = ((OnBackPressedListener) mCurrentFragment);

            // if our listener handles onBackPressed(), return
            if (listener.onBackPressed()) {
                Logger.v(this, "onBackPressed()");
                return;
            }

            // else we will have to go back or exit.
            // in this case, lets get the correct icons
            final MaterialMenuDrawable.IconState iconState;
            if (listener.showBurger()) {
                iconState = MaterialMenuDrawable.IconState.BURGER;
            } else {
                iconState = MaterialMenuDrawable.IconState.ARROW;
            }

            Logger.v(this, "iconState: %s", iconState);

            // we can separate actionbar back actions and back key presses
            if (animatePressed) {
                sMaterialMenu.animatePressedState(iconState);
            } else {
                sMaterialMenu.animateState(iconState);
            }

            // after animating, go further
        }

        // we we have at least one fragment in the BackStack, pop it and return
        if (getSupportFragmentManager().getBackStackEntryCount() > 0) {
            getSupportFragmentManager().popBackStack();

            // restore title / actionbar
            if (mSubFragmentTitle != -1) {
                mTitle = mSubFragmentTitle;
            } else {
                mTitle = mFragmentTitle;
            }
            restoreActionBar();

            return;
        }

        // if nothing matched by now, we do not have any fragments in the BackStack, nor we have
        // the menu open. in that case lets detect a double back press and exit the activity
        if (mBackPressed + 2000 > System.currentTimeMillis()) {
            if (mToast != null) {
                mToast.cancel();
            }
            finish();
        } else {
            mToast = Toast.makeText(getBaseContext(), getString(R.string.action_press_again), Toast.LENGTH_SHORT);
            mToast.show();
        }
        mBackPressed = System.currentTimeMillis();
    }

    @Override
    public void onBackPressed() {
        onCustomBackPressed(false);
    }

    @Override
    protected void onDestroy() {
        DatabaseHandler.tearDown();
        synchronized (lockObject) {
            Logger.i(this, "closing shells");
            try {
                RootTools.closeAllShells();
            } catch (Exception e) {
                Logger.e(this, String.format("onDestroy(): %s", e));
            }
        }
        super.onDestroy();
    }

    //==============================================================================================
    // Methods
    //==============================================================================================

    public void setFragment(final Fragment fragment) {
        if (fragment == null)
            return;
        Logger.v(this, "setFragment: %s", fragment.getId());
        mCurrentFragment = fragment;
    }

    public static void loadFragment(final Activity activity, final int id) {
        loadFragment(activity, id, false);
    }

    public static void loadFragment(final Activity activity, final int id, final boolean onResume) {
        if (activity instanceof MainActivity) {
            ((MainActivity) activity).loadFragmentPrivate(id, onResume);
        }
    }

    private void loadFragmentPrivate(final int i, final boolean onResume) {
        switch (i) {
        default: // slip through...
            //--------------------------------------------------------------------------------------
        case DeviceConstants.ID_ABOUT:
            if (!onResume)
                mCurrentFragment = new AboutFragment();
            mTitle = mFragmentTitle = R.string.app_name;
            mSubFragmentTitle = -1;
            break;
        //--------------------------------------------------------------------------------------
        case DeviceConstants.ID_DEVICE_INFORMATION:
            if (!onResume)
                mCurrentFragment = new DeviceInformationFragment();
            mTitle = mFragmentTitle = R.string.device;
            mSubFragmentTitle = -1;
            break;
        //--------------------------------------------------------------------------------------
        case DeviceConstants.ID_FEATURES:
            if (!onResume)
                mCurrentFragment = new DeviceFeatureFragment();
            mTitle = mFragmentTitle = R.string.features;
            mSubFragmentTitle = -1;
            break;
        case DeviceConstants.ID_FAST_CHARGE:
            if (!onResume)
                mCurrentFragment = new FastChargeFragment();
            mTitle = mSubFragmentTitle = R.string.fast_charge;
            break;
        case DeviceConstants.ID_SOUND_CONTROL:
            if (!onResume)
                mCurrentFragment = new SoundControlFragment();
            mTitle = mSubFragmentTitle = R.string.sound_control;
            break;
        case DeviceConstants.ID_KSM:
            if (!onResume)
                mCurrentFragment = new KsmFragment();
            mTitle = mSubFragmentTitle = R.string.ksm;
            break;
        case DeviceConstants.ID_UKSM:
            if (!onResume)
                mCurrentFragment = new UksmFragment();
            mTitle = mSubFragmentTitle = R.string.uksm;
            break;
        case DeviceConstants.ID_VOLTAGE:
            if (!onResume)
                mCurrentFragment = new VoltageFragment();
            mTitle = mSubFragmentTitle = R.string.voltage_control;
            break;
        case DeviceConstants.ID_ENTROPY:
            if (!onResume)
                mCurrentFragment = new EntropyFragment();
            mTitle = mSubFragmentTitle = R.string.entropy;
            break;
        //--------------------------------------------------------------------------------------
        case DeviceConstants.ID_PERFORMANCE_INFO:
            if (!onResume)
                mCurrentFragment = new InformationFragment();
            mTitle = mFragmentTitle = R.string.information;
            mSubFragmentTitle = -1;
            break;
        //--------------------------------------------------------------------------------------
        case DeviceConstants.ID_PERFORMANCE_CPU_SETTINGS:
            if (!onResume)
                mCurrentFragment = new CpuSettingsFragment();
            mTitle = mFragmentTitle = R.string.cpusettings;
            mSubFragmentTitle = -1;
            break;
        case DeviceConstants.ID_GOVERNOR_TUNABLE:
            if (!onResume)
                mCurrentFragment = new GovernorFragment();
            mTitle = mSubFragmentTitle = R.string.cpu_governor_tuning;
            break;
        //--------------------------------------------------------------------------------------
        case DeviceConstants.ID_PERFORMANCE_GPU_SETTINGS:
            if (!onResume)
                mCurrentFragment = new GpuSettingsFragment();
            mTitle = mFragmentTitle = R.string.gpusettings;
            mSubFragmentTitle = -1;
            break;
        //--------------------------------------------------------------------------------------
        case DeviceConstants.ID_FILESYSTEM:
            if (!onResume)
                mCurrentFragment = new FilesystemFragment();
            mTitle = mFragmentTitle = R.string.filesystem;
            mSubFragmentTitle = -1;
            break;
        case DeviceConstants.ID_IOSCHED_TUNING:
            if (!onResume)
                mCurrentFragment = new IoSchedConfigFragment();
            mTitle = mSubFragmentTitle = R.string.io;
            break;
        //--------------------------------------------------------------------------------------
        case DeviceConstants.ID_THERMAL:
            if (!onResume)
                mCurrentFragment = new ThermalFragment();
            mTitle = mFragmentTitle = R.string.thermal;
            mSubFragmentTitle = -1;
            break;
        //--------------------------------------------------------------------------------------
        case DeviceConstants.ID_TOOLS_TASKER:
            if (!onResume)
                mCurrentFragment = new TaskerFragment();
            mTitle = mFragmentTitle = R.string.tasker;
            mSubFragmentTitle = -1;
            break;
        //--------------------------------------------------------------------------------------
        case DeviceConstants.ID_TOOLS_FLASHER:
            if (!onResume)
                mCurrentFragment = new FlasherFragment();
            mTitle = mFragmentTitle = R.string.flasher;
            mSubFragmentTitle = -1;
            break;
        //--------------------------------------------------------------------------------------
        case DeviceConstants.ID_TOOLS_MORE:
            if (!onResume)
                mCurrentFragment = new ToolsMoreFragment();
            mTitle = mFragmentTitle = R.string.more;
            mSubFragmentTitle = -1;
            break;
        case DeviceConstants.ID_TOOLS_VM:
            if (!onResume)
                mCurrentFragment = new SysctlFragment();
            mTitle = mSubFragmentTitle = R.string.sysctl_vm;
            break;
        case DeviceConstants.ID_TOOLS_EDITORS_VM:
            if (!onResume)
                mCurrentFragment = new SysctlEditorFragment();
            mTitle = mSubFragmentTitle = R.string.sysctl_vm;
            break;
        case DeviceConstants.ID_TOOLS_EDITORS_BUILD_PROP:
            if (!onResume)
                mCurrentFragment = new BuildPropEditorFragment();
            mTitle = mSubFragmentTitle = R.string.buildprop;
            break;
        case DeviceConstants.ID_TOOLS_APP_MANAGER:
            if (!onResume)
                mCurrentFragment = new AppListFragment();
            mTitle = mSubFragmentTitle = R.string.app_manager;
            break;
        case DeviceConstants.ID_TOOLS_WIRELESS_FM:
            if (!onResume)
                mCurrentFragment = new WirelessFileManagerFragment();
            mTitle = mSubFragmentTitle = R.string.wireless_file_manager;
            break;
        //--------------------------------------------------------------------------------------
        case DeviceConstants.ID_PREFERENCES:
            if (!onResume)
                mCurrentFragment = new PreferencesFragment();
            mTitle = mFragmentTitle = R.string.preferences;
            mSubFragmentTitle = -1;
            break;
        }

        restoreActionBar();

        if (onResume) {
            return;
        }

        final boolean isSubFragment = mSubFragmentTitle != -1;

        final FragmentManager fragmentManager = getSupportFragmentManager();
        if (!isSubFragment && fragmentManager.getBackStackEntryCount() > 0) {
            // set a lock to prevent calling setFragment as onResume gets called
            AppHelper.preventOnResume = true;
            MainActivity.sDisableFragmentAnimations = true;
            fragmentManager.popBackStackImmediate(null, FragmentManager.POP_BACK_STACK_INCLUSIVE);
            MainActivity.sDisableFragmentAnimations = false;
            // release the lock
            AppHelper.preventOnResume = false;
        }

        final FragmentTransaction ft = fragmentManager.beginTransaction();

        if (isSubFragment) {
            ft.setCustomAnimations(R.anim.slide_in_right, R.anim.slide_out_right, R.anim.slide_in_left,
                    R.anim.slide_out_left);
            ft.addToBackStack(null);
        }

        ft.replace(R.id.container, mCurrentFragment);
        ft.commit();

        final MaterialMenuDrawable.IconState iconState;
        if (isSubFragment) {
            iconState = MaterialMenuDrawable.IconState.ARROW;
        } else {
            iconState = MaterialMenuDrawable.IconState.BURGER;
        }

        sMaterialMenu.animateState(iconState);
    }

    private void restoreActionBar() {
        final ActionBar actionBar = getSupportActionBar();
        if (actionBar != null) {
            actionBar.setTitle(mTitle);
        }
    }

    public static void setSwipeOnContent(final boolean swipeOnContent) {
        if (sSlidingMenu == null)
            return;

        sSlidingMenu.setTouchModeAbove(
                swipeOnContent ? SlidingMenu.TOUCHMODE_FULLSCREEN : SlidingMenu.TOUCHMODE_MARGIN);
    }

}