org.mariotaku.twidere.activity.support.HomeActivity.java Source code

Java tutorial

Introduction

Here is the source code for org.mariotaku.twidere.activity.support.HomeActivity.java

Source

/*
 *             Twidere - Twitter client for Android
 *
 *  Copyright (C) 2012-2014 Mariotaku Lee <mariotaku.lee@gmail.com>
 *
 *  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.mariotaku.twidere.activity.support;

import android.app.NotificationManager;
import android.app.PendingIntent;
import android.app.SearchManager;
import android.content.ContentResolver;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.SharedPreferences.OnSharedPreferenceChangeListener;
import android.content.res.Resources;
import android.database.ContentObserver;
import android.graphics.Canvas;
import android.graphics.PorterDuff.Mode;
import android.graphics.Rect;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
import android.support.annotation.NonNull;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.NotificationCompat;
import android.support.v4.view.ViewCompat;
import android.support.v4.view.ViewPager;
import android.support.v4.view.ViewPager.OnPageChangeListener;
import android.support.v7.app.ThemedAppCompatDelegateFactory;
import android.support.v7.widget.Toolbar;
import android.view.Gravity;
import android.view.KeyEvent;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.View.OnLongClickListener;
import android.view.ViewGroup;
import android.view.ViewGroup.MarginLayoutParams;
import android.view.Window;
import android.view.WindowManager;
import android.widget.FrameLayout;
import android.widget.FrameLayout.LayoutParams;
import android.widget.Toast;

import com.jeremyfeinstein.slidingmenu.lib.SlidingMenu;
import com.jeremyfeinstein.slidingmenu.lib.SlidingMenu.CanvasTransformer;
import com.jeremyfeinstein.slidingmenu.lib.SlidingMenu.OnClosedListener;
import com.jeremyfeinstein.slidingmenu.lib.SlidingMenu.OnOpenedListener;
import com.meizu.flyme.reflect.StatusBarProxy;
import com.squareup.otto.Bus;
import com.squareup.otto.Subscribe;

import org.apache.commons.lang3.ArrayUtils;
import org.mariotaku.twidere.R;
import org.mariotaku.twidere.activity.SettingsActivity;
import org.mariotaku.twidere.activity.SettingsWizardActivity;
import org.mariotaku.twidere.activity.UsageStatisticsActivity;
import org.mariotaku.twidere.adapter.support.SupportTabsAdapter;
import org.mariotaku.twidere.app.TwidereApplication;
import org.mariotaku.twidere.fragment.CustomTabsFragment;
import org.mariotaku.twidere.fragment.iface.RefreshScrollTopInterface;
import org.mariotaku.twidere.fragment.iface.SupportFragmentCallback;
import org.mariotaku.twidere.fragment.support.AccountsDashboardFragment;
import org.mariotaku.twidere.fragment.support.DirectMessagesFragment;
import org.mariotaku.twidere.fragment.support.TrendsSuggestionsFragment;
import org.mariotaku.twidere.graphic.EmptyDrawable;
import org.mariotaku.twidere.model.ParcelableAccount;
import org.mariotaku.twidere.model.SupportTabSpec;
import org.mariotaku.twidere.provider.TwidereDataStore.Accounts;
import org.mariotaku.twidere.provider.TwidereDataStore.Mentions;
import org.mariotaku.twidere.provider.TwidereDataStore.Statuses;
import org.mariotaku.twidere.service.StreamingService;
import org.mariotaku.twidere.util.AsyncTaskUtils;
import org.mariotaku.twidere.util.AsyncTwitterWrapper;
import org.mariotaku.twidere.util.CustomTabUtils;
import org.mariotaku.twidere.util.KeyboardShortcutsHandler;
import org.mariotaku.twidere.util.KeyboardShortcutsHandler.KeyboardShortcutCallback;
import org.mariotaku.twidere.util.MathUtils;
import org.mariotaku.twidere.util.MultiSelectEventHandler;
import org.mariotaku.twidere.util.ParseUtils;
import org.mariotaku.twidere.util.ReadStateManager;
import org.mariotaku.twidere.util.ThemeUtils;
import org.mariotaku.twidere.util.TwidereColorUtils;
import org.mariotaku.twidere.util.Utils;
import org.mariotaku.twidere.util.message.TaskStateChangedEvent;
import org.mariotaku.twidere.util.message.UnreadCountUpdatedEvent;
import org.mariotaku.twidere.util.support.ActivitySupport;
import org.mariotaku.twidere.util.support.ActivitySupport.TaskDescriptionCompat;
import org.mariotaku.twidere.util.support.ViewSupport;
import org.mariotaku.twidere.util.support.view.ViewOutlineProviderCompat;
import org.mariotaku.twidere.view.ExtendedViewPager;
import org.mariotaku.twidere.view.HomeSlidingMenu;
import org.mariotaku.twidere.view.LeftDrawerFrameLayout;
import org.mariotaku.twidere.view.TabPagerIndicator;
import org.mariotaku.twidere.view.TintedStatusFrameLayout;
import org.mariotaku.twidere.view.iface.IHomeActionButton;

import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

import edu.tsinghua.spice.Utilies.NetworkStateUtil;
import edu.tsinghua.spice.Utilies.SpiceProfilingUtil;

import static org.mariotaku.twidere.util.CompareUtils.classEquals;
import static org.mariotaku.twidere.util.Utils.cleanDatabasesByItemLimit;
import static org.mariotaku.twidere.util.Utils.getDefaultAccountId;
import static org.mariotaku.twidere.util.Utils.getTabDisplayOptionInt;
import static org.mariotaku.twidere.util.Utils.isDatabaseReady;
import static org.mariotaku.twidere.util.Utils.openMessageConversation;
import static org.mariotaku.twidere.util.Utils.openSearch;
import static org.mariotaku.twidere.util.Utils.showMenuItemToast;

public class HomeActivity extends BaseAppCompatActivity implements OnClickListener, OnPageChangeListener,
        SupportFragmentCallback, OnOpenedListener, OnClosedListener, OnLongClickListener {

    private final Handler mHandler = new Handler();

    private final ContentObserver mAccountChangeObserver = new AccountChangeObserver(this, mHandler);

    private ParcelableAccount mSelectedAccountToSearch;

    private SharedPreferences mPreferences;

    private AsyncTwitterWrapper mTwitterWrapper;

    private NotificationManager mNotificationManager;

    private MultiSelectEventHandler mMultiSelectHandler;
    private ReadStateManager mReadStateManager;

    private SupportTabsAdapter mPagerAdapter;

    private ExtendedViewPager mViewPager;
    private TabPagerIndicator mTabIndicator;
    private HomeSlidingMenu mSlidingMenu;
    private View mEmptyTabHint;
    private View mActionsButton;
    private View mActionBarWithOverlay;
    private LeftDrawerFrameLayout mLeftDrawerContainer;
    private TintedStatusFrameLayout mColorStatusFrameLayout;

    private UpdateUnreadCountTask mUpdateUnreadCountTask;

    private Toolbar mActionBar;

    private OnSharedPreferenceChangeListener mReadStateChangeListener = new OnSharedPreferenceChangeListener() {
        @Override
        public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {
            updateUnreadCount();
        }
    };
    private ControlBarShowHideHelper mControlBarShowHideHelper = new ControlBarShowHideHelper(this);
    private int mTabColumns;
    private View mActionBarContainer;

    public void closeAccountsDrawer() {
        if (mSlidingMenu == null)
            return;
        mSlidingMenu.showContent();
    }

    public long[] getActivatedAccountIds() {
        final Fragment fragment = getLeftDrawerFragment();
        if (fragment instanceof AccountsDashboardFragment) {
            return ((AccountsDashboardFragment) fragment).getActivatedAccountIds();
        }
        return Utils.getActivatedAccountIds(this);
    }

    @Override
    public Fragment getCurrentVisibleFragment() {
        final int currentItem = mViewPager.getCurrentItem();
        if (currentItem < 0 || currentItem >= mPagerAdapter.getCount())
            return null;
        return (Fragment) mPagerAdapter.instantiateItem(mViewPager, currentItem);
    }

    @Override
    public boolean triggerRefresh(final int position) {
        final Fragment f = (Fragment) mPagerAdapter.instantiateItem(mViewPager, position);
        if (!(f instanceof RefreshScrollTopInterface))
            return false;
        if (f.getActivity() == null || f.isDetached())
            return false;
        return ((RefreshScrollTopInterface) f).triggerRefresh();
    }

    public Fragment getLeftDrawerFragment() {
        return getSupportFragmentManager().findFragmentById(R.id.left_drawer);
    }

    @Override
    public boolean getSystemWindowsInsets(Rect insets) {
        final int height = mTabIndicator != null ? mTabIndicator.getHeight() : 0;
        insets.top = height != 0 ? height : ThemeUtils.getActionBarHeight(this);
        return true;
    }

    @Override
    public void setControlBarVisibleAnimate(boolean visible) {
        mControlBarShowHideHelper.setControlBarVisibleAnimate(visible);
    }

    @Override
    public boolean onOptionsItemSelected(final MenuItem item) {
        switch (item.getItemId()) {
        case MENU_HOME: {
            final FragmentManager fm = getSupportFragmentManager();
            final int count = fm.getBackStackEntryCount();

            if (mSlidingMenu.isMenuShowing()) {
                mSlidingMenu.showContent();
                return true;
            } else if (count == 0) {
                mSlidingMenu.showMenu();
                return true;
            }
            return true;
        }
        case MENU_SEARCH: {
            openSearchView(mSelectedAccountToSearch);
            return true;
        }
        case MENU_ACTIONS: {
            triggerActionsClick();
            return true;
        }
        }
        return super.onOptionsItemSelected(item);
    }

    @Override
    public boolean handleKeyboardShortcutSingle(@NonNull KeyboardShortcutsHandler handler, int keyCode,
            @NonNull KeyEvent event) {
        if (handleFragmentKeyboardShortcutSingle(handler, keyCode, event))
            return true;
        String action = handler.getKeyAction(CONTEXT_TAG_HOME, keyCode, event);
        if (action != null) {
            switch (action) {
            case ACTION_HOME_ACCOUNTS_DASHBOARD: {
                if (mSlidingMenu.isMenuShowing()) {
                    mSlidingMenu.showContent(true);
                } else {
                    mSlidingMenu.showMenu(true);
                    setControlBarVisibleAnimate(true);
                }
                return true;
            }
            }
        }
        action = handler.getKeyAction(CONTEXT_TAG_NAVIGATION, keyCode, event);
        if (action != null) {
            switch (action) {
            case ACTION_NAVIGATION_PREVIOUS_TAB: {
                final int previous = mViewPager.getCurrentItem() - 1;
                final int mode = mSlidingMenu.getMode();
                if (previous < 0 && (mode == SlidingMenu.LEFT || mode == SlidingMenu.LEFT_RIGHT)) {
                    mSlidingMenu.showMenu(true);
                    setControlBarVisibleAnimate(true);
                } else if (previous < mPagerAdapter.getCount()) {
                    if (mSlidingMenu.isSecondaryMenuShowing()) {
                        mSlidingMenu.showContent(true);
                    } else {
                        mViewPager.setCurrentItem(previous, true);
                    }
                }
                return true;
            }
            case ACTION_NAVIGATION_NEXT_TAB: {
                final int next = mViewPager.getCurrentItem() + 1;
                final int mode = mSlidingMenu.getMode();
                if (next >= mPagerAdapter.getCount()
                        && (mode == SlidingMenu.RIGHT || mode == SlidingMenu.LEFT_RIGHT)) {
                    mSlidingMenu.showSecondaryMenu(true);
                    setControlBarVisibleAnimate(true);
                } else if (next >= 0) {
                    if (mSlidingMenu.isMenuShowing()) {
                        mSlidingMenu.showContent(true);
                    } else {
                        mViewPager.setCurrentItem(next, true);
                    }
                }
                return true;
            }
            }
        }
        return handler.handleKey(this, null, keyCode, event);
    }

    @Override
    public void setControlBarOffset(float offset) {
        mActionBarWithOverlay.setTranslationY(mTabColumns > 1 ? 0 : getControlBarHeight() * (offset - 1));
        final ViewGroup.LayoutParams lp = mActionsButton.getLayoutParams();
        if (lp instanceof MarginLayoutParams) {
            mActionsButton.setTranslationY(
                    (((MarginLayoutParams) lp).bottomMargin + mActionsButton.getHeight()) * (1 - offset));
        } else {
            mActionsButton.setTranslationY(mActionsButton.getHeight() * (1 - offset));
        }
        notifyControlBarOffsetChanged();
    }

    @Override
    public boolean handleKeyboardShortcutRepeat(@NonNull KeyboardShortcutsHandler handler, int keyCode,
            int repeatCount, @NonNull KeyEvent event) {
        if (handleFragmentKeyboardShortcutRepeat(handler, keyCode, repeatCount, event))
            return true;
        return super.handleKeyboardShortcutRepeat(handler, keyCode, repeatCount, event);
    }

    /**
     * Called when the context is first created.
     */
    @Override
    protected void onCreate(final Bundle savedInstanceState) {
        final Window window = getWindow();
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
            window.addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
        }
        super.onCreate(savedInstanceState);
        if (!isDatabaseReady(this)) {
            Toast.makeText(this, R.string.preparing_database_toast, Toast.LENGTH_SHORT).show();
            finish();
            return;
        }
        mPreferences = getSharedPreferences(SHARED_PREFERENCES_NAME, Context.MODE_PRIVATE);
        mTwitterWrapper = getTwitterWrapper();
        final TwidereApplication app = TwidereApplication.getInstance(this);
        mReadStateManager = app.getReadStateManager();
        mNotificationManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
        mMultiSelectHandler = new MultiSelectEventHandler(this);
        mMultiSelectHandler.dispatchOnCreate();
        //        if (!Utils.hasAccount(this)) {
        //            final Intent signInIntent = new Intent(INTENT_ACTION_TWITTER_LOGIN);
        //            signInIntent.setClass(this, SignInActivity.class);
        //            startActivity(signInIntent);
        //            finish();
        //            return;
        //        } else {
        //            notifyAccountsChanged();
        //        }
        final Intent intent = getIntent();
        if (openSettingsWizard()) {
            finish();
            return;
        }
        setContentView(R.layout.activity_home);
        setSupportActionBar(mActionBar);
        sendBroadcast(new Intent(BROADCAST_HOME_ACTIVITY_ONCREATE));
        final boolean refreshOnStart = mPreferences.getBoolean(KEY_REFRESH_ON_START, false);
        int tabDisplayOptionInt = getTabDisplayOptionInt(this);

        mTabColumns = getResources().getInteger(R.integer.default_tab_columns);

        mColorStatusFrameLayout.setOnFitSystemWindowsListener(this);
        mPagerAdapter = new SupportTabsAdapter(this, getSupportFragmentManager(), mTabIndicator, mTabColumns);
        mViewPager.setAdapter(mPagerAdapter);
        //        mViewPager.setOffscreenPageLimit(3);
        mTabIndicator.setViewPager(mViewPager);
        mTabIndicator.setOnPageChangeListener(this);
        mTabIndicator.setColumns(mTabColumns);
        if (tabDisplayOptionInt == 0) {
            tabDisplayOptionInt = TabPagerIndicator.ICON;
        }
        mTabIndicator.setTabDisplayOption(tabDisplayOptionInt);
        mTabIndicator.setTabExpandEnabled((tabDisplayOptionInt & TabPagerIndicator.LABEL) == 0);
        mTabIndicator.setDisplayBadge(mPreferences.getBoolean(KEY_UNREAD_COUNT, true));
        mTabIndicator.updateAppearance();

        mActionsButton.setOnClickListener(this);
        mActionsButton.setOnLongClickListener(this);
        mEmptyTabHint.setOnClickListener(this);

        ThemeUtils.setCompatContentViewOverlay(this, new EmptyDrawable());
        ViewCompat.setElevation(mActionBarContainer, ThemeUtils.getSupportActionBarElevation(this));
        ViewSupport.setOutlineProvider(mActionBarContainer, ViewOutlineProviderCompat.BACKGROUND);
        final View windowOverlay = findViewById(R.id.window_overlay);
        ViewSupport.setBackground(windowOverlay,
                ThemeUtils.getNormalWindowContentOverlay(this, getCurrentThemeResourceId()));

        setupSlidingMenu();
        setupBars();
        showDataProfilingRequest();
        initUnreadCount();
        updateActionsButton();
        updateSlidingMenuTouchMode();
        getDelegate().setKeyListener(new ThemedAppCompatDelegateFactory.KeyListener() {
            @Override
            public boolean onKeyDown(int keyCode, KeyEvent event) {
                return false;
            }

            @Override
            public boolean onKeyUp(int keyCode, KeyEvent event) {
                // Steal MENU key event
                switch (keyCode) {
                case KeyEvent.KEYCODE_MENU: {
                    if (mSlidingMenu != null) {
                        mSlidingMenu.toggle(true);
                        return true;
                    }
                    break;
                }
                }
                return false;
            }
        });

        if (savedInstanceState == null) {
            if (refreshOnStart) {
                mTwitterWrapper.refreshAll(getActivatedAccountIds());
            }
            if (intent.getBooleanExtra(EXTRA_OPEN_ACCOUNTS_DRAWER, false)) {
                openAccountsDrawer();
            }
        }
        setupHomeTabs();

        final int initialTabPosition = handleIntent(intent, savedInstanceState == null);
        setTabPosition(initialTabPosition);

        startService(new Intent(this, StreamingService.class));
    }

    @Override
    protected void onStart() {
        super.onStart();
        mMultiSelectHandler.dispatchOnStart();
        sendBroadcast(new Intent(BROADCAST_HOME_ACTIVITY_ONSTART));
        final ContentResolver resolver = getContentResolver();
        resolver.registerContentObserver(Accounts.CONTENT_URI, true, mAccountChangeObserver);
        final Bus bus = TwidereApplication.getInstance(this).getMessageBus();
        assert bus != null;
        bus.register(this);
        // spice
        SpiceProfilingUtil.profile(this, SpiceProfilingUtil.FILE_NAME_APP, "App Launch" + "," + Build.MODEL + ","
                + "mediaPreview=" + mPreferences.getBoolean(KEY_MEDIA_PREVIEW, false));
        SpiceProfilingUtil.profile(this, SpiceProfilingUtil.FILE_NAME_ONLAUNCH,
                "App Launch" + "," + NetworkStateUtil.getConnectedType(this) + "," + Build.MODEL);
        //end
        mReadStateManager.registerOnSharedPreferenceChangeListener(mReadStateChangeListener);
        updateUnreadCount();
    }

    @Override
    protected void onResume() {
        super.onResume();
        sendBroadcast(new Intent(BROADCAST_HOME_ACTIVITY_ONRESUME));
        invalidateOptionsMenu();
        updateActionsButtonStyle();
        updateActionsButton();
        updateSlidingMenuTouchMode();
    }

    @Override
    protected void onPause() {
        sendBroadcast(new Intent(BROADCAST_HOME_ACTIVITY_ONPAUSE));
        super.onPause();
    }

    @Override
    protected void onStop() {
        mMultiSelectHandler.dispatchOnStop();
        mReadStateManager.unregisterOnSharedPreferenceChangeListener(mReadStateChangeListener);
        final Bus bus = TwidereApplication.getInstance(this).getMessageBus();
        assert bus != null;
        bus.unregister(this);
        final ContentResolver resolver = getContentResolver();
        resolver.unregisterContentObserver(mAccountChangeObserver);
        mPreferences.edit().putInt(KEY_SAVED_TAB_POSITION, mViewPager.getCurrentItem()).apply();
        sendBroadcast(new Intent(BROADCAST_HOME_ACTIVITY_ONSTOP));

        // spice
        SpiceProfilingUtil.profile(this, SpiceProfilingUtil.FILE_NAME_APP, "App Stop");
        SpiceProfilingUtil.profile(this, SpiceProfilingUtil.FILE_NAME_ONLAUNCH,
                "App Stop" + "," + NetworkStateUtil.getConnectedType(this) + "," + Build.MODEL);
        //end
        super.onStop();
    }

    public ViewPager getViewPager() {
        return mViewPager;
    }

    public void notifyAccountsChanged() {
    }

    @Subscribe
    public void notifyTaskStateChanged(TaskStateChangedEvent event) {
        updateActionsButton();
    }

    @Subscribe
    public void notifyUnreadCountUpdated(UnreadCountUpdatedEvent event) {
        updateUnreadCount();
    }

    @Override
    public void onClick(final View v) {
        switch (v.getId()) {
        case R.id.actions_button: {
            triggerActionsClick();
            break;
        }
        case R.id.empty_tab_hint: {
            final Intent intent = new Intent(this, SettingsActivity.class);
            intent.putExtra(SettingsActivity.EXTRA_SHOW_FRAGMENT, CustomTabsFragment.class.getName());
            intent.putExtra(SettingsActivity.EXTRA_SHOW_FRAGMENT_TITLE, R.string.tabs);
            startActivityForResult(intent, REQUEST_SETTINGS);
            break;
        }
        }
    }

    @Override
    public void onClosed() {
        updateDrawerPercentOpen(0, true);
    }

    @Override
    public boolean onLongClick(final View v) {
        switch (v.getId()) {
        case R.id.actions_button: {
            showMenuItemToast(v, v.getContentDescription(), true);
            return true;
        }
        }
        return false;
    }

    @Override
    public void onOpened() {
        updateDrawerPercentOpen(1, true);
    }

    @Override
    public void onPageScrolled(final int position, final float positionOffset, final int positionOffsetPixels) {
    }

    @Override
    public void onPageSelected(final int position) {
        if (mSlidingMenu.isMenuShowing()) {
            mSlidingMenu.showContent();
        }
        updateSlidingMenuTouchMode();
        updateActionsButton();
    }

    @Override
    public void onPageScrollStateChanged(final int state) {
        setControlBarVisibleAnimate(true);
    }

    @Override
    public void onWindowFocusChanged(final boolean hasFocus) {
        super.onWindowFocusChanged(hasFocus);
        if (mSlidingMenu != null && mSlidingMenu.isMenuShowing()) {
            updateDrawerPercentOpen(1, false);
        } else {
            updateDrawerPercentOpen(0, false);
        }
    }

    @Override
    public boolean onSearchRequested() {
        startActivity(new Intent(this, QuickSearchBarActivity.class));
        return true;
    }

    public void openSearchView(final ParcelableAccount account) {
        mSelectedAccountToSearch = account;
        onSearchRequested();
    }

    public void setSystemWindowInsets(Rect insets) {
        final Fragment fragment = getLeftDrawerFragment();
        if (fragment instanceof AccountsDashboardFragment) {
            ((AccountsDashboardFragment) fragment).setStatusBarHeight(insets.top);
        }
        mColorStatusFrameLayout.setStatusBarHeight(insets.top);
    }

    public void updateUnreadCount() {
        if (mTabIndicator == null
                || mUpdateUnreadCountTask != null && mUpdateUnreadCountTask.getStatus() == AsyncTask.Status.RUNNING)
            return;
        mUpdateUnreadCountTask = new UpdateUnreadCountTask(this, mReadStateManager, mTabIndicator,
                mPagerAdapter.getTabs());
        AsyncTaskUtils.executeTask(mUpdateUnreadCountTask);
        mTabIndicator.setDisplayBadge(mPreferences.getBoolean(KEY_UNREAD_COUNT, true));
    }

    @Override
    protected void onActivityResult(final int requestCode, final int resultCode, final Intent data) {
        switch (requestCode) {
        case REQUEST_SWIPEBACK_ACTIVITY: {
            // closeAccountsDrawer();
            return;
        }
        }
        super.onActivityResult(requestCode, resultCode, data);
    }

    @Override
    protected void onNewIntent(final Intent intent) {
        final int tabPosition = handleIntent(intent, false);
        if (tabPosition >= 0) {
            mViewPager.setCurrentItem(MathUtils.clamp(tabPosition, mPagerAdapter.getCount(), 0));
        }
    }

    @Override
    protected void onDestroy() {

        stopService(new Intent(this, StreamingService.class));

        // Delete unused items in databases.
        cleanDatabasesByItemLimit(this);
        sendBroadcast(new Intent(BROADCAST_HOME_ACTIVITY_ONDESTROY));
        super.onDestroy();
    }

    @Override
    public void onBackPressed() {
        if (mSlidingMenu != null && mSlidingMenu.isMenuShowing()) {
            mSlidingMenu.showContent();
            return;
        }
        super.onBackPressed();
    }

    @Override
    public float getControlBarOffset() {
        if (mTabColumns > 1) {
            final ViewGroup.LayoutParams lp = mActionsButton.getLayoutParams();
            float total;
            if (lp instanceof MarginLayoutParams) {
                total = ((MarginLayoutParams) lp).bottomMargin + mActionsButton.getHeight();
            } else {
                total = mActionsButton.getHeight();
            }
            return 1 - mActionsButton.getTranslationY() / total;
        }
        final float totalHeight = getControlBarHeight();
        return 1 + mActionBarWithOverlay.getTranslationY() / totalHeight;
    }

    @Override
    public void onContentChanged() {
        super.onContentChanged();
        mActionBar = (Toolbar) findViewById(R.id.action_bar);
        mActionBarContainer = findViewById(R.id.twidere_action_bar_container);
        mTabIndicator = (TabPagerIndicator) findViewById(R.id.main_tabs);
        mSlidingMenu = (HomeSlidingMenu) findViewById(R.id.home_menu);
        mViewPager = (ExtendedViewPager) findViewById(R.id.main_pager);
        mEmptyTabHint = findViewById(R.id.empty_tab_hint);
        mActionsButton = findViewById(R.id.actions_button);
        mActionBarWithOverlay = findViewById(R.id.twidere_action_bar_with_overlay);
        mTabIndicator = (TabPagerIndicator) findViewById(R.id.main_tabs);
        mColorStatusFrameLayout = (TintedStatusFrameLayout) findViewById(R.id.home_content);
    }

    private Fragment getKeyboardShortcutRecipient() {
        if (mSlidingMenu.isMenuShowing()) {
            return getLeftDrawerFragment();
        } else if (mSlidingMenu.isSecondaryMenuShowing()) {
            return null;
        } else {
            return getCurrentVisibleFragment();
        }
    }

    @Override
    public int getControlBarHeight() {
        return mTabIndicator.getHeight() - mTabIndicator.getStripHeight();
    }

    private boolean handleFragmentKeyboardShortcutRepeat(final KeyboardShortcutsHandler handler, final int keyCode,
            final int repeatCount, @NonNull final KeyEvent event) {
        final Fragment fragment = getKeyboardShortcutRecipient();
        if (fragment instanceof KeyboardShortcutCallback) {
            return ((KeyboardShortcutCallback) fragment).handleKeyboardShortcutRepeat(handler, keyCode, repeatCount,
                    event);
        }
        return false;
    }

    private boolean handleFragmentKeyboardShortcutSingle(final KeyboardShortcutsHandler handler, final int keyCode,
            @NonNull final KeyEvent event) {
        final Fragment fragment = getKeyboardShortcutRecipient();
        if (fragment instanceof KeyboardShortcutCallback) {
            return ((KeyboardShortcutCallback) fragment).handleKeyboardShortcutSingle(handler, keyCode, event);
        }
        return false;
    }

    private int handleIntent(final Intent intent, final boolean firstCreate) {
        // use packge's class loader to prevent BadParcelException
        intent.setExtrasClassLoader(getClassLoader());
        // reset intent
        setIntent(new Intent(this, HomeActivity.class));
        final String action = intent.getAction();
        if (Intent.ACTION_SEARCH.equals(action)) {
            final String query = intent.getStringExtra(SearchManager.QUERY);
            final Bundle appSearchData = intent.getBundleExtra(SearchManager.APP_DATA);
            final long accountId;
            if (appSearchData != null && appSearchData.containsKey(EXTRA_ACCOUNT_ID)) {
                accountId = appSearchData.getLong(EXTRA_ACCOUNT_ID, -1);
            } else {
                accountId = getDefaultAccountId(this);
            }
            openSearch(this, accountId, query);
            return -1;
        }
        final boolean refreshOnStart = mPreferences.getBoolean(KEY_REFRESH_ON_START, false);
        final long[] refreshedIds = intent.getLongArrayExtra(EXTRA_REFRESH_IDS);
        if (refreshedIds != null) {
            mTwitterWrapper.refreshAll(refreshedIds);
        } else if (firstCreate && refreshOnStart) {
            mTwitterWrapper.refreshAll();
        }

        final Uri uri = intent.getData();
        final String tabType = uri != null ? Utils.matchTabType(uri) : null;
        int initialTab = -1;
        if (tabType != null) {
            final long accountId = ParseUtils.parseLong(uri.getQueryParameter(QUERY_PARAM_ACCOUNT_ID));
            for (int i = mPagerAdapter.getCount() - 1; i > -1; i--) {
                final SupportTabSpec tab = mPagerAdapter.getTab(i);
                if (tabType.equals(tab.type)) {
                    initialTab = i;
                    if (hasAccountId(tab.args, accountId)) {
                        break;
                    }
                }
            }
        }
        if (initialTab != -1 && mViewPager != null) {
            // clearNotification(initial_tab);
        }
        final Intent extraIntent = intent.getParcelableExtra(EXTRA_EXTRA_INTENT);
        if (extraIntent != null && firstCreate) {
            extraIntent.setExtrasClassLoader(getClassLoader());
            startActivity(extraIntent);
        }
        return initialTab;
    }

    private boolean hasAccountId(Bundle args, long accountId) {
        if (args == null)
            return false;
        if (args.containsKey(EXTRA_ACCOUNT_ID)) {
            return args.getLong(EXTRA_ACCOUNT_ID) == accountId;
        } else if (args.containsKey(EXTRA_ACCOUNT_IDS)) {
            return ArrayUtils.contains(args.getLongArray(EXTRA_ACCOUNT_IDS), accountId);
        }
        return false;
    }

    private void initUnreadCount() {
        for (int i = 0, j = mTabIndicator.getCount(); i < j; i++) {
            mTabIndicator.setBadge(i, 0);
        }
    }

    private void openAccountsDrawer() {
        if (mSlidingMenu == null)
            return;
        mSlidingMenu.showMenu();
    }

    private boolean openSettingsWizard() {
        if (mPreferences == null || mPreferences.getBoolean(KEY_SETTINGS_WIZARD_COMPLETED, false))
            return false;
        startActivity(new Intent(this, SettingsWizardActivity.class));
        return true;
    }

    private void setTabPosition(final int initialTab) {
        final boolean rememberPosition = mPreferences.getBoolean(KEY_REMEMBER_POSITION, true);
        if (initialTab >= 0) {
            mViewPager.setCurrentItem(MathUtils.clamp(initialTab, mPagerAdapter.getCount(), 0));
        } else if (rememberPosition) {
            final int position = mPreferences.getInt(KEY_SAVED_TAB_POSITION, 0);
            mViewPager.setCurrentItem(MathUtils.clamp(position, mPagerAdapter.getCount(), 0));
        }
    }

    private void setupBars() {
        final int themeColor = getThemeColor();
        final int themeResId = getCurrentThemeResourceId();
        final String backgroundOption = getCurrentThemeBackgroundOption();
        final boolean isTransparent = ThemeUtils.isTransparentBackground(backgroundOption);
        final int actionBarAlpha = isTransparent
                ? ThemeUtils.getActionBarAlpha(ThemeUtils.getUserThemeBackgroundAlpha(this))
                : 0xFF;
        final IHomeActionButton homeActionButton = (IHomeActionButton) mActionsButton;
        mTabIndicator.setItemContext(ThemeUtils.getActionBarThemedContext(this, themeResId, themeColor));
        ViewSupport.setBackground(mActionBarContainer,
                ThemeUtils.getActionBarBackground(this, themeResId, themeColor, backgroundOption, true));
        final int actionBarColor = ThemeUtils.getActionBarColor(this, themeColor, themeResId, backgroundOption);
        final int actionItemColor = ThemeUtils.getContrastForegroundColor(this, getCurrentThemeResourceId(),
                themeColor);
        final int[] foregroundColors = new int[2];
        ThemeUtils.getColorForegroundAndInverse(this, foregroundColors);
        if (ThemeUtils.isDarkTheme(themeResId)) {
            homeActionButton.setButtonColor(actionBarColor);
            homeActionButton.setIconColor(actionItemColor, Mode.SRC_ATOP);
            mTabIndicator.setStripColor(themeColor);
            mTabIndicator.setIconColor(foregroundColors[0]);
            mTabIndicator.setLabelColor(foregroundColors[0]);
        } else {
            final int contrastColor = TwidereColorUtils.getContrastYIQ(themeColor,
                    ThemeUtils.ACCENT_COLOR_THRESHOLD, foregroundColors[0], foregroundColors[1]);
            homeActionButton.setButtonColor(themeColor);
            homeActionButton.setIconColor(actionItemColor, Mode.SRC_ATOP);
            mTabIndicator.setStripColor(contrastColor);
            mTabIndicator.setIconColor(contrastColor);
            mTabIndicator.setLabelColor(contrastColor);
            ActivitySupport.setTaskDescription(this, new TaskDescriptionCompat(null, null, themeColor));
        }
        mColorStatusFrameLayout.setDrawColor(true);
        mColorStatusFrameLayout.setDrawShadow(false);
        mColorStatusFrameLayout.setColor(actionBarColor, actionBarAlpha);
        StatusBarProxy.setStatusBarDarkIcon(getWindow(),
                TwidereColorUtils.getYIQLuminance(actionBarColor) > ThemeUtils.ACCENT_COLOR_THRESHOLD);
        mColorStatusFrameLayout.setFactor(1);
        mActionBarWithOverlay.setAlpha(actionBarAlpha / 255f);
        mActionsButton.setAlpha(actionBarAlpha / 255f);
    }

    private void setupHomeTabs() {
        mPagerAdapter.clear();
        mPagerAdapter.addTabs(CustomTabUtils.getHomeTabs(this));
        final boolean hasNoTab = mPagerAdapter.getCount() == 0;
        mEmptyTabHint.setVisibility(hasNoTab ? View.VISIBLE : View.GONE);
        mViewPager.setVisibility(hasNoTab ? View.GONE : View.VISIBLE);
        //        mViewPager.setOffscreenPageLimit(mPagerAdapter.getCount() / 2);
    }

    private void setupSlidingMenu() {
        if (mSlidingMenu == null)
            return;
        final Resources res = getResources();
        final int marginThreshold = res.getDimensionPixelSize(R.dimen.default_sliding_menu_margin_threshold);
        final boolean relativeBehindWidth = res.getBoolean(R.bool.relative_behind_width);
        mSlidingMenu.setMode(SlidingMenu.LEFT);
        mSlidingMenu.setShadowWidthRes(R.dimen.default_sliding_menu_shadow_width);
        mSlidingMenu.setShadowDrawable(R.drawable.shadow_left);
        mSlidingMenu.setSecondaryShadowDrawable(R.drawable.shadow_right);
        if (relativeBehindWidth) {
            mSlidingMenu.setBehindOffsetRes(R.dimen.drawer_offset_home);
        } else {
            mSlidingMenu.setBehindWidthRes(R.dimen.drawer_width_home);
        }
        mSlidingMenu.setTouchmodeMarginThreshold(marginThreshold);
        mSlidingMenu.setFadeDegree(0.5f);
        mSlidingMenu.setMenu(R.layout.drawer_home_accounts);
        mSlidingMenu.setOnOpenedListener(this);
        mSlidingMenu.setOnClosedListener(this);
        mLeftDrawerContainer = (LeftDrawerFrameLayout) mSlidingMenu.getMenu()
                .findViewById(R.id.left_drawer_container);
        final boolean isTransparentBackground = ThemeUtils
                .isTransparentBackground(getCurrentThemeBackgroundOption());
        mLeftDrawerContainer.setClipEnabled(isTransparentBackground);
        mLeftDrawerContainer.setScrollScale(mSlidingMenu.getBehindScrollScale());
        mSlidingMenu.setBehindCanvasTransformer(new ListenerCanvasTransformer(this));
        final Window window = getWindow();
        ThemeUtils.applyWindowBackground(this, mSlidingMenu.getContent(), getCurrentThemeResourceId(),
                getThemeBackgroundOption(), getCurrentThemeBackgroundAlpha());
        window.setBackgroundDrawable(new EmptyDrawable());

        mSlidingMenu.addIgnoredView(mActionBarContainer);
    }

    private void showDataProfilingRequest() {
        //spice
        if (mPreferences.contains(KEY_USAGE_STATISTICS)) {
            return;
        }
        final Intent intent = new Intent(this, UsageStatisticsActivity.class);
        final PendingIntent contentIntent = PendingIntent.getActivity(this, 0, intent, 0);
        final NotificationCompat.Builder builder = new NotificationCompat.Builder(this);
        builder.setAutoCancel(true);
        builder.setSmallIcon(R.drawable.ic_stat_info);
        builder.setTicker(getString(R.string.usage_statistics));
        builder.setContentTitle(getString(R.string.usage_statistics));
        builder.setContentText(getString(R.string.usage_statistics_notification_summary));
        builder.setContentIntent(contentIntent);
        mNotificationManager.notify(NOTIFICATION_ID_DATA_PROFILING, builder.build());
    }

    private void triggerActionsClick() {
        if (mViewPager == null || mPagerAdapter == null)
            return;
        final int position = mViewPager.getCurrentItem();
        final SupportTabSpec tab = mPagerAdapter.getTab(position);
        if (tab == null) {
            startActivity(new Intent(INTENT_ACTION_COMPOSE));
        } else {
            if (classEquals(DirectMessagesFragment.class, tab.cls)) {
                openMessageConversation(this, -1, -1);
            } else if (classEquals(TrendsSuggestionsFragment.class, tab.cls)) {
                openSearchView(null);
            } else {
                startActivity(new Intent(INTENT_ACTION_COMPOSE));
            }
        }
    }

    private void updateActionsButton() {
        if (mViewPager == null || mPagerAdapter == null)
            return;
        final int icon, title;
        final int position = mViewPager.getCurrentItem();
        final SupportTabSpec tab = mPagerAdapter.getTab(position);
        if (tab == null) {
            title = R.string.compose;
            icon = R.drawable.ic_action_status_compose;
        } else {
            if (classEquals(DirectMessagesFragment.class, tab.cls)) {
                icon = R.drawable.ic_action_add;
                title = R.string.new_direct_message;
            } else if (classEquals(TrendsSuggestionsFragment.class, tab.cls)) {
                icon = R.drawable.ic_action_search;
                title = android.R.string.search_go;
            } else {
                icon = R.drawable.ic_action_status_compose;
                title = R.string.compose;
            }
        }
        if (mActionsButton instanceof IHomeActionButton) {
            final IHomeActionButton hab = (IHomeActionButton) mActionsButton;
            hab.setIcon(icon);
            hab.setTitle(title);
        }
    }

    private void updateActionsButtonStyle() {
        final boolean leftsideComposeButton = mPreferences.getBoolean(KEY_LEFTSIDE_COMPOSE_BUTTON, false);
        final FrameLayout.LayoutParams lp = (LayoutParams) mActionsButton.getLayoutParams();
        lp.gravity = Gravity.BOTTOM | (leftsideComposeButton ? Gravity.LEFT : Gravity.RIGHT);
        mActionsButton.setLayoutParams(lp);
    }

    private void updateDrawerPercentOpen(final float percentOpen, final boolean horizontalScroll) {
        if (mLeftDrawerContainer == null)
            return;
        mLeftDrawerContainer.setPercentOpen(percentOpen);
    }

    private void updateSlidingMenuTouchMode() {
        if (mViewPager == null || mSlidingMenu == null)
            return;
        final int position = mViewPager.getCurrentItem();
        final boolean pagingEnabled = mViewPager.isEnabled();
        final boolean atFirstOrLast = position == 0 || position == mPagerAdapter.getCount() - 1;
        final int mode = !pagingEnabled || atFirstOrLast ? SlidingMenu.TOUCHMODE_FULLSCREEN
                : SlidingMenu.TOUCHMODE_MARGIN;
        mSlidingMenu.setTouchModeAbove(mode);
    }

    private static final class AccountChangeObserver extends ContentObserver {
        private final HomeActivity mActivity;

        public AccountChangeObserver(final HomeActivity activity, final Handler handler) {
            super(handler);
            mActivity = activity;
        }

        @Override
        public void onChange(final boolean selfChange) {
            onChange(selfChange, null);
        }

        @Override
        public void onChange(final boolean selfChange, final Uri uri) {
            mActivity.notifyAccountsChanged();
            mActivity.updateUnreadCount();
        }
    }

    private static class ListenerCanvasTransformer implements CanvasTransformer {
        private final HomeActivity mHomeActivity;

        public ListenerCanvasTransformer(final HomeActivity homeActivity) {
            mHomeActivity = homeActivity;
        }

        @Override
        public void transformCanvas(final Canvas canvas, final float percentOpen) {
            mHomeActivity.updateDrawerPercentOpen(percentOpen, true);
        }

    }

    private static class UpdateUnreadCountTask extends AsyncTask<Object, Object, Map<SupportTabSpec, Integer>> {
        private final Context mContext;
        private final ReadStateManager mReadStateManager;
        private final TabPagerIndicator mIndicator;
        private final List<SupportTabSpec> mTabs;

        UpdateUnreadCountTask(final Context context, final ReadStateManager manager,
                final TabPagerIndicator indicator, final List<SupportTabSpec> tabs) {
            mContext = context;
            mReadStateManager = manager;
            mIndicator = indicator;
            mTabs = Collections.unmodifiableList(tabs);
        }

        @Override
        protected Map<SupportTabSpec, Integer> doInBackground(final Object... params) {
            final Map<SupportTabSpec, Integer> result = new HashMap<>();
            for (SupportTabSpec spec : mTabs) {
                switch (spec.type) {
                case TAB_TYPE_HOME_TIMELINE: {
                    final long[] accountIds = Utils.getAccountIds(spec.args);
                    final String tagWithAccounts = Utils.getReadPositionTagWithAccounts(mContext, true, spec.tag,
                            accountIds);
                    final long position = mReadStateManager.getPosition(tagWithAccounts);
                    result.put(spec, Utils.getStatusesCount(mContext, Statuses.CONTENT_URI, position, accountIds));
                    break;
                }
                case TAB_TYPE_MENTIONS_TIMELINE: {
                    final long[] accountIds = Utils.getAccountIds(spec.args);
                    final String tagWithAccounts = Utils.getReadPositionTagWithAccounts(mContext, true, spec.tag,
                            accountIds);
                    final long position = mReadStateManager.getPosition(tagWithAccounts);
                    result.put(spec, Utils.getStatusesCount(mContext, Mentions.CONTENT_URI, position, accountIds));
                    break;
                }
                case TAB_TYPE_DIRECT_MESSAGES: {
                    break;
                }
                }
            }
            return result;
        }

        @Override
        protected void onPostExecute(final Map<SupportTabSpec, Integer> result) {
            mIndicator.clearBadge();
            for (Entry<SupportTabSpec, Integer> entry : result.entrySet()) {
                final SupportTabSpec key = entry.getKey();
                mIndicator.setBadge(key.position, entry.getValue());
            }
        }

    }

}